1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-25 07:32:36 +01:00

This update includes the 0.20.3pre3 code

This commit is contained in:
dan
1998-11-23 11:32:19 +00:00
parent 59eb947539
commit 9007a6575d
88 changed files with 4862 additions and 4026 deletions

View File

@@ -24,7 +24,6 @@ wmaker_SOURCES = \
client.c \
client.h \
colormap.c \
config.h \
def_pixmaps.h \
defaults.c \
defaults.h \

View File

@@ -116,7 +116,6 @@ wmaker_SOURCES = \
client.c \
client.h \
colormap.c \
config.h \
def_pixmaps.h \
defaults.c \
defaults.h \

View File

@@ -37,8 +37,6 @@
#endif
/* max. number of distinct window levels */
#define MAX_WINDOW_LEVELS 5
/* class codes */
@@ -56,6 +54,17 @@ typedef enum {
} WClassType;
/* generic window levels (a superset of the N*XTSTEP ones) */
enum {
WMDesktopLevel = 0,
WMSunkenLevel = 1,
WMNormalLevel = 2,
WMFloatingLevel = 3,
WMDockLevel = 4,
WMSubmenuLevel = 5,
WMMainMenuLevel = 6
};
#define MAX_WINDOW_LEVELS 7
/*
* WObjDescriptor will be used by the event dispatcher to
@@ -203,9 +212,7 @@ typedef struct WPreferences {
char use_saveunders; /* turn on SaveUnders for menus,
* icons etc. */
/*
char no_window_under_dock;
*/
char no_window_over_icons;
@@ -307,6 +314,7 @@ typedef struct WPreferences {
unsigned int nodock:1; /* don't display the dock */
unsigned int noclip:1; /* don't display the clip */
unsigned int nocpp:1; /* don't use cpp */
unsigned int noupdates:1; /* don't require ~/GNUstep (-static) */
} flags; /* internal flags */
} WPreferences;

View File

@@ -411,15 +411,11 @@ wMaximizeWindow(WWindow *wwin, int directions)
if (!(wPreferences.icon_yard & IY_RIGHT))
new_x += wPreferences.icon_size;
}
#if 0
if (wPreferences.no_window_under_dock
&& wwin->screen_ptr->dock) {
new_width -= wPreferences.icon_size + DOCK_EXTRA_SPACE;
if (!wwin->screen_ptr->dock->on_right_side)
new_x += wPreferences.icon_size + DOCK_EXTRA_SPACE;
}
#endif
if (wwin->screen_ptr->dock && !wwin->screen_ptr->dock->lowered) {
if (wwin->screen_ptr->dock
&& (!wwin->screen_ptr->dock->lowered
|| wPreferences.no_window_under_dock)) {
new_width -= wPreferences.icon_size + DOCK_EXTRA_SPACE;
if (!wwin->screen_ptr->dock->on_right_side)
new_x += wPreferences.icon_size + DOCK_EXTRA_SPACE;
@@ -900,9 +896,8 @@ wIconifyWindow(WWindow *wwin)
wwin->window_flags.omnipresent || wPreferences.sticky_icons)
XMapWindow(dpy, wwin->icon->core->window);
AddToStackList(wwin->icon->core);
#ifndef STRICTNS
wLowerFrame(wwin->icon->core);
#endif
if (present) {
WWindow *owner = recursiveTransientFor(wwin->screen_ptr->focused_window);
@@ -1263,6 +1258,10 @@ wHideApplication(WApplication *wapp)
}
wapp->flags.hidden = 1;
if(wPreferences.auto_arrange_icons) {
wArrangeIcons(scr, True);
}
}
@@ -1564,7 +1563,7 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll)
wwin = wwin->prev;
while (wwin) {
if (wwin->icon && wwin->flags.miniaturized &&
if (wwin->icon && wwin->flags.miniaturized && !wwin->flags.hidden &&
(wwin->frame->workspace==scr->current_workspace ||
wwin->window_flags.omnipresent ||
wPreferences.sticky_icons)) {

View File

@@ -180,7 +180,7 @@ saveIconNameFor(char *iconPath, char *wm_instance, char *wm_class)
}
PLRelease(key);
if (val)
if (val && !wPreferences.flags.noupdates)
PLSave(dict, YES);
}
@@ -382,9 +382,7 @@ wApplicationCreate(WScreen *scr, Window main_window)
} else {
PlaceIcon(scr, &x, &y);
wAppIconMove(wapp->app_icon, x, y);
#ifndef STRICTNS
wLowerFrame(icon->core);
#endif
wLowerFrame(icon->core);
}
if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
XMapWindow(dpy, icon->core->window);

View File

@@ -391,11 +391,9 @@ WDefaultEntry optionList[] = {
{"AutoArrangeIcons", "NO", NULL,
&wPreferences.auto_arrange_icons, getBool, NULL
},
/*
{"NoWindowUnderDock", "NO", NULL,
&wPreferences.no_window_under_dock, getBool, NULL
},
*/
{"NoWindowOverIcons", "NO", NULL,
&wPreferences.no_window_over_icons, getBool, NULL
},
@@ -1209,7 +1207,7 @@ wDefaultUpdateIcons(WScreen *scr)
#define STRINGP(x) if (!PLIsString(value)) { \
wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
PLGetString(entry->plkey), x); \
entry->key, x); \
return False; }
@@ -1285,7 +1283,7 @@ again:
data = 0;
} else {
wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
val, PLGetString(entry->plkey));
val, entry->key);
if (second_pass==0) {
val = PLGetString(entry->plvalue);
second_pass = 1;
@@ -1321,7 +1319,7 @@ getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
if (sscanf(val, "%i", &data)!=1) {
wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
val, PLGetString(entry->plkey));
val, entry->key);
val = PLGetString(entry->plvalue);
wwarning(_("using default \"%s\" instead"), val);
if (sscanf(val, "%i", &data)!=1) {
@@ -1351,7 +1349,7 @@ getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
PLGetString(entry->plkey), "Coordinate");
entry->key, "Coordinate");
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1364,7 +1362,7 @@ again:
nelem = PLGetNumberOfElements(value);
if (nelem != 2) {
wwarning(_("Incorrect number of elements in array for key \"%s\"."),
PLGetString(entry->plkey));
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1379,7 +1377,7 @@ again:
if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
PLGetString(entry->plkey));
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1393,8 +1391,7 @@ again:
val_y = PLGetString(elem_y);
if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
wwarning(_("can't convert array to integers for \"%s\"."),
PLGetString(entry->plkey));
wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1465,7 +1462,7 @@ getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
PLGetString(entry->plkey), "an array of paths");
entry->key, "an array of paths");
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1516,7 +1513,7 @@ getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
{
static char data;
data = string2index(entry->key, value, entry->default_value,
data = string2index(entry->plkey, value, entry->default_value,
(WOptionEnumeration*)entry->extra_data);
if (data < 0)
return False;
@@ -1732,7 +1729,7 @@ getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
PLGetString(entry->plkey), "Texture");
entry->key, "Texture");
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -1741,12 +1738,28 @@ again:
}
return False;
}
if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
proplist_t pl;
pl = PLGetArrayElement(value, 0);
if (!pl || !PLIsString(pl) || !PLGetString(pl)
|| strcasecmp(PLGetString(pl), "solid")!=0) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
entry->key, "Solid Texture");
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
}
texture = parse_texture(scr, value);
if (!texture) {
wwarning(_("Error in texture specification for key \"%s\""),
PLGetString(entry->plkey));
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
@@ -2069,8 +2082,8 @@ again:
if (file) {
if (fork()==0) {
SetupEnvironment(scr);
close(ConnectionNumber(dpy));
CloseDescriptors();
execlp(program, program, style, "-c", cpc, "-b", back, file, NULL);
wwarning(_("could not run \"%s\""), program);
@@ -2157,7 +2170,7 @@ getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
again:
if (!wGetColor(scr, val, &color)) {
wwarning(_("could not get color for key \"%s\""),
PLGetString(entry->plkey));
entry->key);
if (second_pass==0) {
val = PLGetString(entry->plvalue);
second_pass = 1;
@@ -2741,7 +2754,7 @@ makeWorkspaceTexture(WScreen *scr, WTexture *texture, char *file, char *option)
SetupEnvironment(scr);
close(ConnectionNumber(dpy));
CloseDescriptors();
colorn = wmalloc(32);
sprintf(colorn, "\"#%2x%2x%2x\"",

View File

@@ -148,13 +148,13 @@ wInputDialog(WScreen *scr, char *title, char *message, char **text)
XDestroyWindow(dpy, parent);
if (result==NULL)
return WDB_CANCEL;
return False;
else {
if (*text)
free(*text);
*text = result;
return WDB_OK;
return True;
}
}

View File

@@ -24,12 +24,6 @@
#define WMDIALOG_H_
#define WDB_OK (0)
#define WDB_CANCEL (1)
#define WDB_YES (2)
#define WDB_NO (3)
#define WDB_EXIT (4)
int wMessageDialog(WScreen *scr, char *title, char *message,
char *defBtn, char *altBtn, char *othBtn);
int wInputDialog(WScreen *scr, char *title, char *message, char **text);

View File

@@ -208,7 +208,7 @@ renameCallback(WMenu *menu, WMenuEntry *entry)
sprintf(buffer, _("Type the name for workspace %i:"), wspace+1);
if (wInputDialog(dock->screen_ptr, _("Rename Workspace"), buffer,
&name)==WDB_OK) {
&name)) {
wWorkspaceRename(dock->screen_ptr, wspace, name);
}
if (name) {
@@ -432,9 +432,6 @@ removeIconsCallback(WMenu *menu, WMenuEntry *entry)
wDockDetach(dock, aicon);
if (keepit) {
PlaceIcon(dock->screen_ptr, &aicon->x_pos, &aicon->y_pos);
#ifndef STRICTNS
wLowerFrame(aicon->icon->core);
#endif
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos, aicon->y_pos);
if (!dock->mapped || dock->collapsed)
@@ -468,7 +465,7 @@ keepIconsCallback(WMenu *menu, WMenuEntry *entry)
clickedIcon->editing = 1;
if (wInputDialog(dock->screen_ptr, _("Keep Icon"),
_("Type the command used to launch the application"),
&command)==WDB_OK) {
&command)) {
if (command && (command[0]==0 ||
(command[0]=='-' && command[1]==0))) {
free(command);
@@ -748,7 +745,7 @@ mainIconCreate(WScreen *scr, int type)
btn->icon->core->descriptor.handle_mousedown = iconMouseDown;
btn->icon->core->descriptor.parent_type = WCLASS_DOCK_ICON;
btn->icon->core->descriptor.parent = btn;
/*ChangeStackingLevel(btn->icon->core, NSDockWindowLevel);*/
/*ChangeStackingLevel(btn->icon->core, WMDockLevel);*/
XMapWindow(dpy, btn->icon->core->window);
btn->x_pos = x_pos;
btn->y_pos = 0;
@@ -1104,9 +1101,6 @@ wDockDestroy(WDock *dock)
wDockDetach(dock, aicon);
if (keepit) {
PlaceIcon(dock->screen_ptr, &aicon->x_pos, &aicon->y_pos);
#ifndef STRICTNS
wLowerFrame(aicon->icon->core);
#endif
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos, aicon->y_pos);
if (!dock->mapped || dock->collapsed)
@@ -1703,9 +1697,9 @@ wDockRestoreState(WScreen *scr, proplist_t dock_state, int type)
aicon->y_pos = dock->y_pos + (aicon->yindex*ICON_SIZE);
if (dock->lowered)
ChangeStackingLevel(aicon->icon->core, WMNormalWindowLevel);
ChangeStackingLevel(aicon->icon->core, WMNormalLevel);
else
ChangeStackingLevel(aicon->icon->core, WMDockWindowLevel);
ChangeStackingLevel(aicon->icon->core, WMDockLevel);
wCoreConfigure(aicon->icon->core, aicon->x_pos, aicon->y_pos,
0, 0);
@@ -1725,9 +1719,9 @@ wDockRestoreState(WScreen *scr, proplist_t dock_state, int type)
old_top->x_pos = dock->x_pos;
old_top->y_pos = dock->y_pos;
if (dock->lowered)
ChangeStackingLevel(old_top->icon->core, WMNormalWindowLevel);
ChangeStackingLevel(old_top->icon->core, WMNormalLevel);
else
ChangeStackingLevel(old_top->icon->core, WMDockWindowLevel);
ChangeStackingLevel(old_top->icon->core, WMDockLevel);
dock->icon_array[0] = old_top;
XMoveWindow(dpy, old_top->icon->core->window, dock->x_pos, dock->y_pos);
/* we don't need to increment dock->icon_count here because it was
@@ -1911,18 +1905,18 @@ wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y)
if (icon->command==NULL) {
icon->editing = 0;
if (XGetCommand(dpy, wwin->client_win, &argv, &argc) && argc>0) {
icon->command = FlattenStringList(argv, argc);
XFreeStringList(argv);
} else {
char *command=NULL;
/* icon->forced_dock = 1;*/
if (!icon->attracted || dock->type!=WM_CLIP || dock->keep_attracted) {
icon->editing = 1;
if (wInputDialog(dock->screen_ptr, _("Dock Icon"),
_("Type the command used to launch the application"),
&command)==WDB_OK) {
&command)) {
if (command && (command[0]==0 ||
(command[0]=='-' && command[1]==0))) {
free(command);
@@ -1990,6 +1984,13 @@ wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y)
if (wPreferences.auto_arrange_icons)
wArrangeIcons(dock->screen_ptr, True);
#ifdef OFFIX_DND
if (icon->command && !icon->dnd_command) {
icon->dnd_command = wmalloc(strlen(icon->command)+8);
sprintf(icon->dnd_command, "%s %%d", icon->command);
}
#endif
return True;
}
@@ -2044,7 +2045,7 @@ moveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y)
/* icon->forced_dock = 1;*/
if (wInputDialog(src->screen_ptr, _("Dock Icon"),
_("Type the command used to launch the application"),
&command)==WDB_OK) {
&command)) {
if (command && (command[0]==0 ||
(command[0]=='-' && command[1]==0))) {
free(command);
@@ -2181,7 +2182,9 @@ wDockDetach(WDock *dock, WAppIcon *icon)
icon->icon->core->descriptor.handle_leavenotify = NULL;
icon->icon->core->descriptor.parent_type = WCLASS_APPICON;
icon->icon->core->descriptor.parent = icon;
ChangeStackingLevel(icon->icon->core, WMNormalWindowLevel);
ChangeStackingLevel(icon->icon->core, NORMAL_ICON_LEVEL);
wAppIconPaint(icon);
if (wPreferences.auto_arrange_icons) {
wArrangeIcons(dock->screen_ptr, True);
@@ -2198,7 +2201,7 @@ wDockDetach(WDock *dock, WAppIcon *icon)
*
* Returns False if icon can't be docked.
*/
int
Bool
wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
int *ret_x, int *ret_y, int redocking)
{
@@ -2210,6 +2213,9 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
WAppIcon *nicon = NULL;
if (wPreferences.flags.noupdates)
return False;
dx = dock->x_pos;
dy = dock->y_pos;
@@ -2238,6 +2244,9 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
return False;
if (dock->type == WM_DOCK) {
if (icon->dock != dock && ex_x != 0)
return False;
for (i=0; i<dock->max_icons; i++) {
nicon = dock->icon_array[i];
if (nicon && nicon->yindex == ex_y) {
@@ -2333,8 +2342,8 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
break;
}
}
if ((!redocking && neighbours && !aicon) ||
(redocking && neighbours && (aicon == icon || !aicon))) {
if (neighbours && (aicon==NULL || (redocking && aicon == icon))) {
*ret_x = ex_x;
*ret_y = ex_y;
return True;
@@ -2356,7 +2365,7 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
* in which case it changes x_pos and y_pos accordingly.
* Else returns false.
*/
int
Bool
wDockFindFreeSlot(WDock *dock, int *x_pos, int *y_pos)
{
WScreen *scr = dock->screen_ptr;
@@ -2369,6 +2378,7 @@ wDockFindFreeSlot(WDock *dock, int *x_pos, int *y_pos)
int corner;
int sx=0, sy=0, ex=scr->scr_width, ey=scr->scr_height;
/* if the dock is full */
if (dock->icon_count >= dock->max_icons) {
return False;
@@ -2666,7 +2676,7 @@ execCommand(WAppIcon *btn, char *command, WSavedState *state)
SetupEnvironment(scr);
close(ConnectionNumber(dpy));
CloseDescriptors();
#ifdef HAVE_SETPGID
setpgid(0, 0);
@@ -2674,7 +2684,7 @@ execCommand(WAppIcon *btn, char *command, WSavedState *state)
args = malloc(sizeof(char*)*(argc+1));
if (!args)
exit(111);
exit(111);
for (i=0; i<argc; i++) {
args[i] = argv[i];
}
@@ -2743,7 +2753,7 @@ wDockShowIcons(WDock *dock)
btn = dock->icon_array[0];
moveDock(dock, btn->x_pos, btn->y_pos);
newlevel = dock->lowered ? WMNormalWindowLevel : WMDockWindowLevel;
newlevel = dock->lowered ? WMNormalLevel : WMDockLevel;
ChangeStackingLevel(btn->icon->core, newlevel);
for (i=1; i<dock->max_icons; i++) {
@@ -2967,10 +2977,10 @@ toggleLowered(WDock *dock)
/* lower/raise Dock */
if (!dock->lowered) {
newlevel = WMNormalWindowLevel;
newlevel = WMNormalLevel;
dock->lowered = 1;
} else {
newlevel = WMDockWindowLevel;
newlevel = WMDockLevel;
dock->lowered = 0;
}
@@ -3083,7 +3093,8 @@ openDockMenu(WDock *dock, WAppIcon *aicon, XEvent *event)
/* settings */
entry = dock->menu->entries[++index];
entry->clientdata = aicon;
wMenuSetEnabled(dock->menu, index, !aicon->editing);
wMenuSetEnabled(dock->menu, index, !aicon->editing
&& !wPreferences.flags.noupdates);
/* kill */
entry = dock->menu->entries[++index];
@@ -3374,6 +3385,9 @@ handleIconMove(WDock *dock, WAppIcon *aicon, XEvent *event)
Bool docked;
int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
if (wPreferences.flags.noupdates)
return;
if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
|ButtonReleaseMask|ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) {

View File

@@ -76,9 +76,9 @@ void wDockRaiseLower(WDock *dock);
void wDockSaveState(WScreen *scr);
Bool wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y);
int wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
int *ret_x, int *ret_y, int redocking);
int wDockFindFreeSlot(WDock *dock, int *req_x, int *req_y);
Bool wDockFindFreeSlot(WDock *dock, int *req_x, int *req_y);
void wDockDetach(WDock *dock, WAppIcon *icon);
void wDockTrackWindowLaunch(WDock *dock, Window window);

View File

@@ -90,8 +90,8 @@ updateCommand(WAppIcon *icon, char *command)
}
icon->command = command;
if (!icon->wm_class && !icon->wm_instance &&
icon->command && strlen(icon->command)>0) {
if (!icon->wm_class && !icon->wm_instance && icon->command
&& strlen(icon->command)>0) {
icon->forced_dock = 1;
}
}
@@ -216,7 +216,7 @@ panelBtnCallback(WMWidget *self, void *data)
else
wAppIconPaint(aicon);
wDefaultChangeIcon(panel->wwin->screen_ptr, aicon->wm_instance,
wDefaultChangeIcon(panel->wwin->screen_ptr, aicon->wm_instance,
aicon->wm_class, text);
}
if (text)
@@ -236,11 +236,11 @@ panelBtnCallback(WMWidget *self, void *data)
text = WMGetTextFieldText(panel->dndCommandField);
updateDNDCommand(panel->editedIcon, text);
#endif
panel->editedIcon->auto_launch =
WMGetButtonSelected(panel->autoLaunchBtn);
}
if (done)
DestroyDockAppSettingsPanel(panel);
}

View File

@@ -222,12 +222,12 @@ DispatchEvent(XEvent *event)
scr = wScreenWithNumber(i);
if (scr) {
wScreenSaveState(scr);
RestoreDesktop(scr);
}
}
RestoreDesktop(NULL);
ExecExitScript();
/* received SIGTERM */
exit(0);
Exit(0);
} else if (WProgramState == WSTATE_NEED_RESTART) {
WProgramState = WSTATE_RESTARTING;
@@ -236,9 +236,9 @@ DispatchEvent(XEvent *event)
scr = wScreenWithNumber(i);
if (scr) {
wScreenSaveState(scr);
RestoreDesktop(scr);
}
}
RestoreDesktop(NULL);
/* received SIGHUP */
Restart(NULL);
}
@@ -350,10 +350,10 @@ EventLoop()
Bool
IsDoubleClick(WScreen *scr, XEvent *event)
{
if ((scr->last_click_time>0) &&
if ((scr->last_click_time>0) &&
(event->xbutton.time-scr->last_click_time<=wPreferences.dblclick_time)
&& (event->xbutton.button == scr->last_click_button)
&& (event->xbutton.window == scr->last_click_window)) {
&& (event->xbutton.subwindow == scr->last_click_window)) {
scr->flags.next_click_is_not_double = 1;
scr->last_click_time = 0;
@@ -655,12 +655,27 @@ handleButtonPress(XEvent *event)
wUnselectWindows(scr);
wSelectWindows(scr, event);
}
#ifdef MOUSE_WS_SWITCH
else if (event->xbutton.button==Button4) {
if (scr->current_workspace > 0)
wWorkspaceChange(scr, scr->current_workspace-1);
} else if (event->xbutton.button==Button5) {
if (scr->current_workspace < scr->workspace_count-1)
wWorkspaceChange(scr, scr->current_workspace+1);
}
#endif /* MOUSE_WS_SWITCH */
}
if (XFindContext(dpy, event->xbutton.window, wWinContext,
if (XFindContext(dpy, event->xbutton.subwindow, wWinContext,
(XPointer *)&desc)==XCNOENT) {
return;
if (XFindContext(dpy, event->xbutton.window, wWinContext,
(XPointer *)&desc)==XCNOENT) {
return;
}
}
if (desc->parent_type == WCLASS_WINDOW) {
@@ -697,7 +712,7 @@ handleButtonPress(XEvent *event)
} else {
scr->last_click_time = event->xbutton.time;
scr->last_click_button = event->xbutton.button;
scr->last_click_window = event->xbutton.window;
scr->last_click_window = event->xbutton.subwindow;
}
}
@@ -1213,7 +1228,10 @@ handleColormapNotify(XEvent *event)
scr->current_colormap == event->xcolormap.colormap) {
/* some bastard app (like XV) removed our colormap */
reinstall = True;
/*
* can't enforce or things like xscreensaver wont work
* reinstall = True;
*/
} else if (event->xcolormap.state == ColormapInstalled &&
scr->current_colormap == event->xcolormap.colormap) {

View File

@@ -33,6 +33,8 @@ typedef void (WDeathHandler)(pid_t pid, unsigned int status, void *cdata);
void RestoreDesktop(WScreen *scr);
void Exit(int status);
void Restart(char *manager);
void SetupEnvironment(WScreen *scr);

View File

@@ -103,7 +103,7 @@ wIconCreate(WWindow *wwin)
icon->core->stacking = wmalloc(sizeof(WStacking));
icon->core->stacking->above = NULL;
icon->core->stacking->under = NULL;
icon->core->stacking->window_level = WMNormalWindowLevel;
icon->core->stacking->window_level = NORMAL_ICON_LEVEL;
icon->core->stacking->child_of = NULL;
icon->owner = wwin;
@@ -173,7 +173,7 @@ wIconCreateWithIconFile(WScreen *scr, char *iconfile, int tile)
icon->core->stacking = wmalloc(sizeof(WStacking));
icon->core->stacking->above = NULL;
icon->core->stacking->under = NULL;
icon->core->stacking->window_level = WMNormalWindowLevel;
icon->core->stacking->window_level = NORMAL_ICON_LEVEL;
icon->core->stacking->child_of = NULL;
if (iconfile) {

View File

@@ -46,6 +46,7 @@
#include "keybind.h"
#include "xmodifier.h"
#include "defaults.h"
#include "session.h"
#include <proplist.h>
@@ -157,6 +158,16 @@ extern void EventLoop();
extern void StartUp();
void
Exit(int status)
{
#ifdef R6SM
wSessionDisconnectManager();
#endif
XCloseDisplay(dpy);
exit(status);
}
void
Restart(char *manager)
@@ -174,7 +185,9 @@ Restart(char *manager)
}
}
}
#ifdef R6SM
wSessionDisconnectManager();
#endif
XCloseDisplay(dpy);
if (!prog)
execvp(Arguments[0], Arguments);
@@ -254,6 +267,7 @@ print_help()
*/
puts(_(" -visualid visualid visual id of visual to use"));
puts(_(" -display host:dpy display to use"));
puts(_(" -static do not update or save configurations"));
puts(_(" -version print version and exit"));
}
@@ -276,7 +290,6 @@ check_defaults()
}
static void
execInitScript()
{
@@ -285,7 +298,7 @@ execInitScript()
file = wfindfile(DEF_CONFIG_PATHS, DEF_INIT_SCRIPT);
if (file) {
if (fork()==0) {
close(ConnectionNumber(dpy));
CloseDescriptors();
execl("/bin/sh", "/bin/sh", "-c", file, NULL);
wsyserror(_("%s:could not execute initialization script"), file);
@@ -304,7 +317,7 @@ ExecExitScript()
file = wfindfile(DEF_CONFIG_PATHS, DEF_EXIT_SCRIPT);
if (file) {
if (fork()==0) {
close(ConnectionNumber(dpy));
CloseDescriptors();
execl("/bin/sh", "/bin/sh", "-c", file, NULL);
wsyserror(_("%s:could not execute exit script"), file);
@@ -336,10 +349,7 @@ main(int argc, char **argv)
else
ProgName++;
/* check existence of Defaults DB directory */
check_defaults();
restart = 0;
memset(&wPreferences, 0, sizeof(WPreferences));
@@ -385,12 +395,29 @@ main(int argc, char **argv)
wwarning(_("bad value for visualid: \"%s\""), argv[i]);
exit(0);
}
} else if (strcmp(argv[i], "-static")==0) {
wPreferences.flags.noupdates = 1;
#ifdef R6SM
} else if (strcmp(argv[i], "-clientid")==0
|| strcmp(argv[i], "-restore")==0) {
i++;
if (i>=argc) {
wwarning(_("too few arguments for %s"), argv[i-1]);
exit(0);
}
#endif
} else {
print_help();
exit(0);
}
}
}
if (!wPreferences.flags.noupdates) {
/* check existence of Defaults DB directory */
check_defaults();
}
#if 0
tmp = getenv("LANG");
if (tmp) {
@@ -429,16 +456,16 @@ main(int argc, char **argv)
wwarning(_("cannot set locale modifiers"));
}
#endif
if (Locale) {
char *ptr;
Locale = wstrdup(Locale);
ptr = strchr(Locale, '.');
if (ptr)
*ptr = 0;
}
/* open display */
dpy = XOpenDisplay(DisplayName);
@@ -472,6 +499,11 @@ main(int argc, char **argv)
#ifdef SOUNDS
wSoundInitialize();
#endif
#ifdef R6SM
wSessionConnectManager(argv, argc);
#endif
StartUp(!multiHead);
execInitScript();

View File

@@ -112,9 +112,9 @@ wMenuCreate(WScreen *screen, char *title, int main_menu)
memset(menu, 0, sizeof(WMenu));
#ifdef SINGLE_MENULEVEL
tmp = WMSubmenuWindowLevel;
tmp = WMSubmenuLevel;
#else
tmp = (main_menu ? WMMainMenuWindowLevel : WMSubmenuWindowLevel);
tmp = (main_menu ? WMMainMenuLevel : WMSubmenuLevel);
#endif
flags = WFF_SINGLE_STATE;
@@ -359,10 +359,10 @@ wMenuEntrySetCascade(WMenu *menu, WMenuEntry *entry, WMenu *cascade)
if (menu->flags.lowered) {
cascade->flags.lowered = 1;
ChangeStackingLevel(cascade->frame->core, WMNormalWindowLevel);
ChangeStackingLevel(cascade->frame->core, WMNormalLevel);
cascade->brother->flags.lowered = 1;
ChangeStackingLevel(cascade->brother->frame->core, WMNormalWindowLevel);
ChangeStackingLevel(cascade->brother->frame->core, WMNormalLevel);
}
if (!menu->flags.realized)
@@ -2110,12 +2110,12 @@ changeMenuLevels(WMenu *menu, int lower)
int i;
if (!lower) {
ChangeStackingLevel(menu->frame->core, (!menu->parent ? WMMainMenuWindowLevel
: WMSubmenuWindowLevel));
ChangeStackingLevel(menu->frame->core, (!menu->parent ? WMMainMenuLevel
: WMSubmenuLevel));
wRaiseFrame(menu->frame->core);
menu->flags.lowered = 0;
} else {
ChangeStackingLevel(menu->frame->core, WMNormalWindowLevel);
ChangeStackingLevel(menu->frame->core, WMNormalLevel);
wLowerFrame(menu->frame->core);
menu->flags.lowered = 1;
}

View File

@@ -601,8 +601,8 @@ FlattenStringList(char **list, int count)
return NULL;
}
strcpy(flat_string, list[0]);
for (i=1; i<count; i++) {
*flat_string = 0;
for (i=0; i<count; i++) {
if (list[i]!=NULL && list[i][0]!=0) {
strcat(flat_string, " ");
wspace = strpbrk(list[i], " \t");
@@ -613,7 +613,7 @@ FlattenStringList(char **list, int count)
strcat(flat_string, "\"");
}
}
return flat_string;
}
@@ -804,7 +804,7 @@ getuserinput(WScreen *scr, char *line, int *ptr)
}
ret = NULL;
if (wInputDialog(scr, tmp, _("Enter command arguments:"), &ret)!= WDB_OK)
if (!wInputDialog(scr, tmp, _("Enter command arguments:"), &ret))
return NULL;
else
return ret;

View File

@@ -52,87 +52,6 @@ extern WPreferences wPreferences;
extern void
InteractivePlaceWindow(WWindow *wwin, int *x_ret, int *y_ret);
#if 0
void
PlaceIcon(WScreen *scr, int *x_ret, int *y_ret)
{
int x1, y1, x2, y2;
int icon_x, icon_y;
int left_margin, right_margin;
WCoreWindow *wcore;
left_margin = 0;
right_margin = scr->scr_width;
if (scr->dock) {
if (scr->dock->on_right_side)
right_margin -= wPreferences.icon_size + DOCK_EXTRA_SPACE;
else
left_margin += wPreferences.icon_size + DOCK_EXTRA_SPACE;
}
x1 = left_margin;
y2 = scr->scr_height;
y1 = y2-wPreferences.icon_size*2;
x2 = left_margin+wPreferences.icon_size;
while (1) {
wcore = scr->stacking_list[0];
while (wcore) {
void *parent;
if (x2>=right_margin+wPreferences.icon_size) {
x1 = left_margin;
x2 = left_margin+wPreferences.icon_size*2;
y1 -= wPreferences.icon_size;
y2 -= wPreferences.icon_size;
if (y2<wPreferences.icon_size) {
/* what's this guy doing!? */
*x_ret = 0;
*y_ret = 0;
return;
}
break;
}
parent = (void*) wcore->descriptor.parent;
/* if it is an application icon */
if (wcore->descriptor.parent_type == WCLASS_APPICON) {
icon_x = ((WAppIcon*)parent)->x_pos;
icon_y = ((WAppIcon*)parent)->y_pos;
} else if (wcore->descriptor.parent_type == WCLASS_MINIWINDOW &&
(((WIcon*)parent)->owner->frame->workspace==scr->current_workspace
|| ((WIcon*)parent)->owner->window_flags.omnipresent
|| wPreferences.sticky_icons)) {
icon_x = ((WIcon*)parent)->owner->icon_x;
icon_y = ((WIcon*)parent)->owner->icon_y;
} else {
wcore = wcore->stacking->under;
continue;
}
wcore = wcore->stacking->under;
/* test if place is taken */
if (icon_y>y1 && icon_y<y2) {
if (icon_x<x2 && icon_x>=x1) {
x2 = icon_x+wPreferences.icon_size*2;
x1 = icon_x+wPreferences.icon_size;
/* this place can't be used */
wcore = scr->stacking_list[0];
break;
}
}
}
if (!wcore) {
/* found spot */
break;
}
}
*x_ret = x1;
*y_ret = y2-wPreferences.icon_size;
}
#endif
/*
* Returns True if it is an icon and is in this workspace.
@@ -143,7 +62,7 @@ iconPosition(WCoreWindow *wcore, int sx1, int sy1, int sx2, int sy2,
{
void *parent;
int ok = 0;
parent = wcore->descriptor.parent;
/* if it is an application icon */
@@ -155,14 +74,15 @@ iconPosition(WCoreWindow *wcore, int sx1, int sy1, int sx2, int sy2,
} else if (wcore->descriptor.parent_type == WCLASS_MINIWINDOW &&
(((WIcon*)parent)->owner->frame->workspace==workspace
|| ((WIcon*)parent)->owner->window_flags.omnipresent
|| wPreferences.sticky_icons)) {
|| wPreferences.sticky_icons)
&& !((WIcon*)parent)->owner->flags.hidden) {
*retX = ((WIcon*)parent)->owner->icon_x;
*retY = ((WIcon*)parent)->owner->icon_y;
ok = 1;
}
/*
* Check if it is inside the screen.
*/
@@ -201,6 +121,7 @@ PlaceIcon(WScreen *scr, int *x_ret, int *y_ret)
int x, y;
int isize = wPreferences.icon_size;
int done = 0;
int level;
/*
* Find out screen boundaries.
@@ -257,27 +178,29 @@ PlaceIcon(WScreen *scr, int *x_ret, int *y_ret)
#define INDEX(x,y) (((y)+1)*(sw+2) + (x) + 1)
obj = scr->stacking_list[0];
while (obj) {
int x, y;
for (level = WMNormalLevel; level >= WMDesktopLevel; level--) {
obj = scr->stacking_list[level];
while (obj) {
int x, y;
if (iconPosition(obj, sx1, sy1, sx2, sy2, scr->current_workspace,
&x, &y)) {
int xdi, ydi; /* rounded down */
int xui, yui; /* rounded up */
if (iconPosition(obj, sx1, sy1, sx2, sy2, scr->current_workspace,
&x, &y)) {
int xdi, ydi; /* rounded down */
int xui, yui; /* rounded up */
xdi = x/isize;
ydi = y/isize;
xui = (x+isize/2)/isize;
yui = (y+isize/2)/isize;
map[INDEX(xdi,ydi)] = 1;
map[INDEX(xdi,yui)] = 1;
map[INDEX(xui,ydi)] = 1;
map[INDEX(xui,yui)] = 1;
xdi = x/isize;
ydi = y/isize;
xui = (x+isize/2)/isize;
yui = (y+isize/2)/isize;
map[INDEX(xdi,ydi)] = 1;
map[INDEX(xdi,yui)] = 1;
map[INDEX(xui,ydi)] = 1;
map[INDEX(xui,yui)] = 1;
}
obj = obj->stacking->under;
}
obj = obj->stacking->under;
}
/*
* Default position
*/

View File

@@ -43,6 +43,11 @@ extern Atom _XA_WM_CLIENT_LEADER;
extern Atom _XA_WM_TAKE_FOCUS;
extern Atom _XA_WM_DELETE_WINDOW;
extern Atom _XA_WM_SAVE_YOURSELF;
#ifdef R6SM
extern Atom _XA_WM_WINDOW_ROLE;
extern Atom _XA_SM_CLIENT_ID;
#endif
extern Atom _XA_GNUSTEP_WM_ATTR;
extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
@@ -209,35 +214,90 @@ PropSetWMakerProtocols(Window root)
}
int
PropGetClientLeader(Window window, Window *leader)
Window
PropGetClientLeader(Window window)
{
Atom type_ret;
int fmt_ret;
unsigned long nitems_ret;
unsigned long bytes_after_ret;
Window *win;
Window leader;
if (XGetWindowProperty(dpy, window, _XA_WM_CLIENT_LEADER, 0, 4,
if (XGetWindowProperty(dpy, window, _XA_WM_CLIENT_LEADER, 0, 1,
False, AnyPropertyType,
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
(unsigned char**)&win)!=Success)
return 0;
(unsigned char**)&win)!=Success || !win)
return None;
if (!win) return 0;
*leader = (Window)*win;
leader = (Window)*win;
XFree(win);
return 1;
if (type_ret == XA_WINDOW && fmt_ret == 32 && nitems_ret == 1
&& bytes_after_ret == 0)
return leader;
else
return None;
}
#ifdef R6SM
char*
PropGetClientID(Window window)
{
XTextProperty txprop;
txprop.value = NULL;
if (XGetTextProperty(dpy, window, &txprop, _XA_SM_CLIENT_ID)!=Success) {
return NULL;
}
if (txprop.encoding == XA_STRING && txprop.format == 8
&& txprop.nitems > 0) {
return (char*)txprop.value;
} else {
if (txprop.value)
XFree(txprop.value);
return NULL;
}
}
char*
PropGetWindowRole(Window window)
{
XTextProperty txprop;
txprop.value = NULL;
if (XGetTextProperty(dpy, window, &txprop, _XA_WM_WINDOW_ROLE)!=Success) {
return NULL;
}
if (txprop.encoding == XA_STRING && txprop.format == 8
&& txprop.nitems > 0) {
return (char*)txprop.value;
} else {
if (txprop.value)
XFree(txprop.value);
return NULL;
}
}
#endif /* R6SM */
void
PropWriteGNUstepWMAttr(Window window, GNUstepWMAttributes *attr)
{
CARD32 data[9];
unsigned long data[9];
/* handle idiot compilers where array of CARD32 != struct of CARD32 */
data[0] = attr->flags;
data[1] = attr->window_style;
data[2] = attr->window_level;

View File

@@ -35,7 +35,6 @@ void PropGetProtocols(Window window, WProtocols *prots);
int PropGetWMClass(Window window, char **wm_class, char **wm_instance);
int PropGetGNUstepWMAttr(Window window, GNUstepWMAttributes **attr);
void PropWriteGNUstepWMAttr(Window window, GNUstepWMAttributes *attr);
int PropGetClientLeader(Window window, Window *leader);
void PropSetWMakerProtocols(Window root);
void PropCleanUp(Window root);
@@ -44,4 +43,10 @@ void PropCleanUp(Window root);
int PropGetMotifWMHints(Window window, MWMHints **mwmhints);
#endif
Window PropGetClientLeader(Window window);
#ifdef R6SM
char *PropGetClientID(Window window);
#endif
#endif

View File

@@ -65,6 +65,7 @@ extern Time LastTimestamp;
extern WPreferences wPreferences;
extern int wScreenCount;
static WMenu *readMenuPipe(WScreen *scr, char **file_name);
static WMenu *readMenuFile(WScreen *scr, char *file_name);
@@ -152,12 +153,18 @@ execCommand(WMenu *menu, WMenuEntry *entry)
{
char *cmdline;
static char *shell = NULL;
/*
* This have a problem: if the shell is tcsh (not sure about others)
* and ~/.tcshrc have /bin/stty erase ^H somewhere on it, the shell
* will block and the command will not be executed.
if (!shell) {
shell = getenv("SHELL");
if (!shell)
shell = "/bin/sh";
}
*/
shell = "/bin/sh";
cmdline = ExpandOptions(menu->frame->screen_ptr, (char*)entry->clientdata);
@@ -175,14 +182,17 @@ execCommand(WMenu *menu, WMenuEntry *entry)
* Ok. -Alfredo
*/
if (fork()==0) {
SetupEnvironment(menu->frame->screen_ptr);
close(ConnectionNumber(dpy));
CloseDescriptors();
#ifdef HAVE_SETPGID
setpgid(0, 0);
#endif
execl(shell, shell, "-c", cmdline, NULL);
wsyserror("could not exec %s -c %s\n", shell, cmdline);
exit(-1);
Exit(-1);
}
free(cmdline);
}
@@ -205,16 +215,22 @@ exitCommand(WMenu *menu, WMenuEntry *entry)
|| wMessageDialog(menu->frame->screen_ptr, _("Exit"),
_("Exit window manager?"),
_("Exit"), _("Cancel"), NULL)==WAPRDefault) {
int i;
#ifdef DEBUG
printf("Exiting WindowMaker.\n");
#endif
for (i=0; i<wScreenCount; i++) {
WScreen *scr;
wScreenSaveState(menu->frame->screen_ptr);
RestoreDesktop(menu->frame->screen_ptr);
scr = wScreenWithNumber(i);
if (scr)
wScreenSaveState(scr);
}
RestoreDesktop(NULL);
ExecExitScript();
exit(0);
Exit(0);
}
inside = 0;
}
@@ -224,25 +240,74 @@ static void
shutdownCommand(WMenu *menu, WMenuEntry *entry)
{
static int inside = 0;
int result;
int i;
/* prevent reentrant calls */
if (inside)
return;
inside = 1;
if ((int)entry->clientdata==M_QUICK
|| wMessageDialog(menu->frame->screen_ptr, _("Close X session"),
_("Close Window System session?\n(all applications will be closed)"),
_("Exit"), _("Cancel"), NULL)==WAPRDefault) {
/* printf(_("Exiting...\n"));*/
wScreenSaveState(menu->frame->screen_ptr);
#define R_CANCEL 0
#define R_CLOSE 1
#define R_KILL 2
WipeDesktop(menu->frame->screen_ptr);
ExecExitScript();
exit(0);
result = R_CANCEL;
if ((int)entry->clientdata==M_QUICK)
result = R_CLOSE;
else {
#ifdef R6SM
if (wSessionIsManaged()) {
int r;
r = wMessageDialog(menu->frame->screen_ptr,
_("Close X session"),
_("Close Window System session?\n"
"Kill might close applications with unsaved data."),
_("Close"), _("Kill"), _("Cancel"));
if (r==WAPRDefault)
result = R_CLOSE;
else if (r==WAPRAlternate)
result = R_KILL;
} else
#endif
{
int r;
r = wMessageDialog(menu->frame->screen_ptr,
_("Kill X session"),
_("Kill Window System session?\n"
"(all applications will be closed)"),
_("Kill"), _("Cancel"), NULL);
if (r==WAPRDefault)
result = R_KILL;
}
}
if (result!=R_CANCEL) {
#ifdef R6SM
if (result == R_CLOSE) {
wSessionRequestShutdown();
} else
#endif /* R6SM */
{
for (i=0; i<wScreenCount; i++) {
WScreen *scr;
scr = wScreenWithNumber(i);
if (scr)
wScreenSaveState(scr);
}
WipeDesktop(NULL);
ExecExitScript();
Exit(0);
}
}
#undef R_CLOSE
#undef R_CANCEL
#undef R_KILL
inside = 0;
}
@@ -250,9 +315,16 @@ shutdownCommand(WMenu *menu, WMenuEntry *entry)
static void
restartCommand(WMenu *menu, WMenuEntry *entry)
{
wScreenSaveState(menu->frame->screen_ptr);
RestoreDesktop(menu->frame->screen_ptr);
int i;
for (i=0; i<wScreenCount; i++) {
WScreen *scr;
scr = wScreenWithNumber(i);
if (scr)
wScreenSaveState(scr);
}
RestoreDesktop(NULL);
Restart((char*)entry->clientdata);
}
@@ -1256,6 +1328,9 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command)
strcmp(dentry->d_name, "..")==0)
continue;
if (dentry->d_name[0] == '.')
continue;
buffer = wmalloc(strlen(path[i])+strlen(dentry->d_name)+4);
if (!buffer) {
wsyserror(_("out of memory while constructing directory menu %s"),
@@ -1444,6 +1519,7 @@ configureMenu(WScreen *scr, proplist_t definition)
if (PLIsString(definition)) {
struct stat stat_buf;
char *path = NULL;
Bool menu_is_default = False;
/* menu definition is a string. Probably a path, so parse the file */
@@ -1482,6 +1558,11 @@ configureMenu(WScreen *scr, proplist_t definition)
if (!path)
path = wfindfile(DEF_CONFIG_PATHS, tmp);
if (!path) {
path = wfindfile(DEF_CONFIG_PATHS, DEF_MENU_FILE);
menu_is_default = True;
}
if (!path) {
wsyserror(_("could not find menu file \"%s\" referenced in WMRootMenu"),
tmp);
@@ -1499,6 +1580,12 @@ configureMenu(WScreen *scr, proplist_t definition)
if (!scr->root_menu || stat_buf.st_mtime > scr->root_menu->timestamp
/* if the pointer in WMRootMenu has changed */
|| WDRootMenu->timestamp > scr->root_menu->timestamp) {
if (menu_is_default) {
wwarning(_("using default menu file \"%s\" as the menu referenced in WMRootMenu could not be found "),
path);
}
menu = readMenuFile(scr, path);
if (menu)
menu->timestamp = MAX(stat_buf.st_mtime, WDRootMenu->timestamp);
@@ -1649,6 +1736,7 @@ OpenRootMenu(WScreen *scr, int x, int y, int keyboard)
menu = configureMenu(scr, definition);
if (menu)
menu->timestamp = WDRootMenu->timestamp;
} else
menu = NULL;
} else {

View File

@@ -747,6 +747,11 @@ wScreenSaveState(WScreen *scr)
wwin = wwin->prev;
}
if (wPreferences.flags.noupdates)
return;
old_state = scr->session_state;
scr->session_state = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
@@ -796,7 +801,9 @@ wScreenSaveState(WScreen *scr)
path = PLMakeString(str);
free(str);
PLSetFilename(scr->session_state, path);
PLSave(scr->session_state, YES);
if (!PLSave(scr->session_state, YES)) {
wwarning(_("could not save session state in %s"), PLGetString(path));
}
PLRelease(path);
PLRelease(old_state);
}

View File

@@ -110,7 +110,7 @@ typedef struct _WScreen {
* is ordered from the topmost to
* the lowest window
*/
int window_level_count[MAX_WINDOW_LEVELS];
/* int window_level_count[MAX_WINDOW_LEVELS];*/
int window_count; /* number of windows in window_list */
#ifdef EXPERIMENTAL

View File

@@ -1,6 +1,7 @@
/* session.c - session state handling
/* session.c - session state handling and R6 style session management
*
* Copyright (c) 1998 Dan Pascu
* Copyright (c) 1998 Alfredo Kojima
*
* Window Maker window manager
*
@@ -24,10 +25,17 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef R6SM
#include <X11/SM/SMlib.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "WindowMaker.h"
#include "screen.h"
@@ -41,6 +49,7 @@
#include "application.h"
#include "appicon.h"
#include "dock.h"
#include "list.h"
@@ -48,6 +57,19 @@
#include <proplist.h>
#ifdef R6SM
/* requested for SaveYourselfPhase2 */
static Bool sWaitingPhase2 = False;
static SmcConn sSMCConn = NULL;
static WMHandlerID sSMInputHandler = NULL;
/* our SM client ID */
static char *sClientID = NULL;
#endif
static proplist_t sApplications = NULL;
static proplist_t sCommand;
static proplist_t sName;
@@ -288,8 +310,8 @@ execCommand(WScreen *scr, char *command, char *host)
SetupEnvironment(scr);
close(ConnectionNumber(dpy));
CloseDescriptors();
args = malloc(sizeof(char*)*(argc+1));
if (!args)
exit(111);
@@ -506,3 +528,418 @@ wSessionRestoreLastWorkspace(WScreen *scr)
}
#ifdef R6SM
/*
* With full session management support, the part of WMState
* that store client window state will become obsolete,
* but we still need to store state info like the dock and workspaces.
* It is better to keep dock/wspace info in WMState because the user
* might want to keep the dock configuration while not wanting to
* resume a previously saved session.
* So, wmaker specific state info can be saved in
* ~/GNUstep/.AppInfo/WindowMaker/statename.state
* Its better to not put it in the defaults directory because:
* - its not a defaults file (having domain names like wmaker0089504baa
* in the defaults directory wouldn't be very neat)
* - this state file is not meant to be edited by users
*
* The old session code will become obsolete. When wmaker is
* compiled with R6 sm support compiled in, itll be better to
* use a totally rewritten state saving code, but we can keep
* the current code for when R6SM is not compiled in.
*
* This will be confusing to old users (well get lots of "SAVE_SESSION broke!"
* messages), but itll be better.
*
* -readme
*/
/*
* Windows are identified as:
* WM_CLASS(instance.class).WM_WINDOW_ROLE
*
*
*/
static void
saveClientState(WWindow *wwin, proplist_t dict)
{
proplist_t key;
}
static void
smSaveYourselfPhase2Proc(SmcConn smc_conn, SmPointer client_data)
{
SmProp props[4];
SmPropValue prop1val, prop2val, prop3val, prop4val;
char **argv = (char**)client_data;
int argc;
int i, j;
Bool ok = False;
char *statefile = NULL;
char *prefix;
Bool gsPrefix = False;
char *discardCmd = NULL;
time_t t;
FILE *file;
#ifdef DEBUG1
puts("received SaveYourselfPhase2 SM message");
#endif
/* save session state */
/* the file that will contain the state */
prefix = getenv("SM_SAVE_DIR");
if (!prefix) {
prefix = wusergnusteppath();
if (prefix)
gsPrefix = True;
}
if (!prefix) {
prefix = getenv("HOME");
}
if (!prefix)
prefix = ".";
statefile = malloc(strlen(prefix)+64);
if (!statefile) {
if (gsPrefix)
free(prefix);
wwarning(_("end of memory while saving session state"));
goto fail;
}
t = time();
i = 0;
do {
if (gsPrefix)
sprintf(statefile, "%s/.AppInfo/WindowMaker/%l%i.state",
prefix, t, i);
else
sprintf(statefile, "%s/wmaker.%l%i.state", prefix, t, i);
i++;
} while (access(F_OK, statefile)!=-1);
if (gsPrefix)
free(prefix);
/* save the states of all windows we're managing */
file = fopen(statefile, "w");
if (!file) {
wsyserror(_("could not create state file %s"), statefile);
goto fail;
}
fclose(file);
/* set the remaining properties that we didn't set at
* startup time */
for (argc=0, i=0; argv[i]!=NULL; i++) {
if (strcmp(argv[i], "-clientid")==0
|| strcmp(argv[i], "-restore")==0) {
i++;
} else {
argc++;
}
}
prop[0].name = SmRestartCommand;
prop[0].type = SmLISTofARRAY8;
prop[0].vals = malloc(sizeof(SmPropValue)*(argc+4));
prop[0].num_vals = argc+4;
prop[1].name = SmCloneCommand;
prop[1].type = SmLISTofARRAY8;
prop[1].vals = malloc(sizeof(SmPropValue)*(argc));
prop[1].num_vals = argc;
if (!prop[0].vals || !prop[1].vals) {
wwarning(_("end of memory while saving session state"));
goto fail;
}
for (j=0, i=0; i<argc+4; i++) {
if (strcmp(argv[i], "-clientid")==0
|| strcmp(argv[i], "-restore")==0) {
i++;
} else {
prop[0].vals[j].value = argv[i];
prop[0].vals[j].length = strlen(argv[i]);
prop[1].vals[j].value = argv[i];
prop[1].vals[j].length = strlen(argv[i]);
j++;
}
}
prop[0].vals[j].value = "-clientid";
prop[0].vals[j].length = 9;
j++;
prop[0].vals[j].value = sClientID;
prop[0].vals[j].length = strlen(sClientID);
j++;
prop[0].vals[j].value = "-restore";
prop[0].vals[j].length = 11;
j++;
prop[0].vals[j].value = statefile;
prop[0].vals[j].length = strlen(statefile);
discardCmd = malloc(strlen(statefile)+8);
if (!discardCmd)
goto fail;
sprintf(discardCmd, "rm %s", statefile);
prop[2].name = SmDiscardCommand;
prop[2].type = SmARRAY8;
prop[2].vals[0] = discardCmd;
prop[2].num_vals = 1;
SmcSetProperties(sSMCConn, 3, prop);
ok = True;
fail:
SmcSaveYourselfDone(smc_conn, ok);
if (prop[0].vals)
free(prop[0].vals);
if (prop[1].vals)
free(prop[1].vals);
if (discardCmd)
free(discardCmd);
if (!ok) {
remove(statefile);
}
if (statefile)
free(statefile);
}
static void
smSaveYourselfProc(SmcConn smc_conn, SmPointer client_data, int save_type,
Bool shutdown, int interact_style, Bool fast)
{
#ifdef DEBUG1
puts("received SaveYourself SM message");
#endif
if (!SmcRequestSaveYourselfPhase2(smc_conn, smSaveYourselfPhase2Proc,
client_data)) {
SmcSaveYourselfDone(smc_conn, False);
sWaitingPhase2 = False;
} else {
#ifdef DEBUG1
puts("successfull request of SYS phase 2");
#endif
sWaitingPhase2 = True;
}
}
static void
smDieProc(SmcConn smc_conn, SmPointer client_data)
{
#ifdef DEBUG1
puts("received Die SM message");
#endif
wSessionDisconnectManager();
RestoreDesktop(NULL);
ExecExitScript();
Exit(0);
}
static void
smSaveCompleteProc(SmcConn smc_conn)
{
/* it means that we can resume doing things that can change our state */
#ifdef DEBUG1
puts("received SaveComplete SM message");
#endif
}
static void
smShutdownCancelledProc(SmcConn smc_conn, SmPointer client_data)
{
if (sWaitingPhase2) {
sWaitingPhase2 = False;
SmcSaveYourselfDone(smc_conn, False);
}
}
static void
iceMessageProc(int fd, int mask, void *clientData)
{
IceConn iceConn = (IceConn)clientData;
IceProcessMessages(iceConn, NULL, NULL);
}
static void
iceIOErrorHandler(IceConnection ice_conn)
{
/* This is not fatal but can mean the session manager exited.
* If the session manager exited normally we would get a
* Die message, so this probably means an abnormal exit.
* If the sm was the last client of session, then we'll die
* anyway, otherwise we can continue doing our stuff.
*/
wwarning(_("connection to the session manager was lost"));
wSessionDisconnectManager();
}
void
wSessionConnectManager(char **argv, int argc)
{
IceConn iceConn;
char *previous_id = NULL;
char buffer[256];
SmcCallbacks callbacks;
unsigned long mask;
char uid[32];
char pid[32];
SmProp props[4];
SmPropValue prop1val, prop2val, prop3val, prop4val;
char restartStyle;
int i;
mask = SmcSaveYourselfProcMask|SmcDieProcMask|SmcSaveCompleteProcMask
|SmcShutdownCancelledProcMask;
callbacks.save_yourself.callback = smSaveYourselfProc;
callbacks.save_yourself.client_data = argv;
callbacks.die.callback = smDieProc;
callbacks.die.client_data = NULL;
callbacks.save_complete.callback = smSaveCompleteProc;
callbacks.save_complete.client_data = NULL;
callbacks.shutdown_cancelled.callback = smShutdownCancelledProc;
callbacks.shutdown_cancelled.client_data = NULL;
for (i=0; i<argc; i++) {
if (strcmp(argv[i], "-clientid")==0) {
previous_id = argv[i+1];
break;
}
}
/* connect to the session manager */
sSMCConn = SmcOpenConnection(NULL, NULL, SmProtoMajor, SmProtoMinor,
mask, &callbacks, previous_id,
&sClientID, 255, buffer);
if (!sSMCConn) {
return;
}
#ifdef DEBUG1
puts("connected to the session manager");
#endif
/* IceSetIOErrorHandler(iceIOErrorHandler);*/
/* check for session manager clients */
iceConn = SmcGetIceConnection(smcConn);
sSMInputHandler = WMAddInputHandler(IceConnectionNumber(iceConn),
WIReadMask, iceMessageProc, iceConn);
/* setup information about ourselves */
/* program name */
prop1val.value = argv[0];
prop1val.length = strlen(argv[0]);
prop[0].name = SmProgram;
prop[0].type = SmARRAY8;
prop[0].num_vals = 1;
prop[0].vals = &prop1val;
/* The XSMP doc from X11R6.1 says it contains the user name,
* but every client implementation I saw places the uid # */
sprintf(uid, "%i", getuid());
prop2val.value = uid;
prop2val.length = strlen(uid);
prop[1].name = SmUserID;
prop[1].type = SmARRAY8;
prop[1].num_vals = 1;
prop[1].vals = &prop2val;
/* Restart style. We should restart only if we were running when
* the previous session finished. */
restartStyle = SmRestartIfRunning;
prop3val.value = &restartStyle;
prop3val.length = 1;
prop[2].name = SmRestartStyleHint;
prop[2].type = SmCARD8;
prop[2].num_vals = 1;
prop[2].vals = &prop3val;
/* Our PID. Not required but might be usefull */
sprintf(pid, "%i", getpid());
prop4val.value = pid;
prop4val.length = strlen(pid);
prop[3].name = SmProcessID;
prop[3].type = SmARRAY8;
prop[3].num_vals = 1;
prop[3].vals = &prop4val;
/* we'll set the rest of the hints later */
SmcSetProperties(sSMCConn, 4, props);
}
void
_wSessionCloseDescriptors(void)
{
if (sSMCConn)
close(IceConnectionNumber(SmcGetIceConnection(smcConn)));
}
void
wSessionDisconnectManager(void)
{
if (sSMCConn) {
WMDeleteInputHandler(sSMInputHandler);
sSMInputHandler = NULL;
SmcCloseConnection(sSMCConn, 0, NULL);
sSMCConn = NULL;
}
}
void
wSessionRequestShutdown(void)
{
/* request a shutdown to the session manager */
if (sSMCConn)
SmcRequestSaveYourself(sSMCConn, SmSaveBoth, True, SmInteractStyleAny,
False, True);
}
Bool
wSessionIsManaged(void)
{
return sSMCConn!=NULL;
}
#endif /* !R6SM */

View File

@@ -31,4 +31,15 @@ void wSessionRestoreState(WScreen *scr);
void wSessionRestoreLastWorkspace(WScreen *scr);
#ifdef R6SM
void wSessionConnectManager(char **argv, int argc);
void wSessionDisconnectManager(void);
void wSessionRequestShutdown(void);
Bool wSessionIsManaged(void);
#endif
#endif

View File

@@ -37,12 +37,13 @@
extern Atom _XA_WM_DELETE_WINDOW;
extern Time LastTimestamp;
extern int wScreenCount;
/*
*----------------------------------------------------------------------
* RestoreDesktop--
* Puts the desktop in a usable state when exiting.
*
*
* Side effects:
* All frame windows are removed and windows are reparented
* back to root. Windows that are outside the screen are
@@ -54,6 +55,18 @@ void
RestoreDesktop(WScreen *scr)
{
int i;
if (!scr) {
int j;
for (j=0; j<wScreenCount; j++) {
WScreen *scr;
scr = wScreenWithNumber(j);
if (scr) {
RestoreDesktop(scr);
}
}
return;
}
XGrabServer(dpy);
wDestroyInspectorPanels();
@@ -107,7 +120,19 @@ void
WipeDesktop(WScreen *scr)
{
WWindow *wwin;
if (!scr) {
int j;
for (j=0; j<wScreenCount; j++) {
WScreen *scr;
scr = wScreenWithNumber(j);
if (scr) {
WipeDesktop(scr);
}
}
return;
}
wwin = scr->focused_window;
while (wwin) {
if (wwin->protocols.DELETE_WINDOW)

View File

@@ -41,25 +41,6 @@ extern XContext wStackContext;
extern WPreferences wPreferences;
static int
levelToIndex(int level)
{
switch (level) {
case WMNormalWindowLevel:
return 0;
case WMFloatingWindowLevel:
return 1;
case WMDockWindowLevel:
return 2;
case WMSubmenuWindowLevel:
return 3;
case WMMainMenuWindowLevel:
return 4;
default:
return 0;
}
}
/*
*----------------------------------------------------------------------
* RemakeStackList--
@@ -91,7 +72,7 @@ RemakeStackList(WScreen *scr)
for (i=0; i<MAX_WINDOW_LEVELS; i++) {
scr->stacking_list[i] = NULL;
onbotw[i] = NULL;
scr->window_level_count[i] = 0;
/* scr->window_level_count[i] = 0;*/
}
/* verify list integrity */
c=0;
@@ -102,13 +83,13 @@ RemakeStackList(WScreen *scr)
}
if (!frame) continue;
c++;
level = levelToIndex(frame->stacking->window_level);
level = frame->stacking->window_level;
if (onbotw[level])
onbotw[level]->stacking->above = frame;
frame->stacking->under = onbotw[level];
frame->stacking->above = NULL;
onbotw[level] = frame;
scr->window_level_count[level]++;
/* scr->window_level_count[level]++;*/
}
XFree(windows);
#ifdef DEBUG
@@ -209,7 +190,7 @@ void
wRaiseFrame(WCoreWindow *frame)
{
WCoreWindow *wlist=frame;
int level = levelToIndex(frame->stacking->window_level);
int level = frame->stacking->window_level;
int i;
/* already on top */
@@ -312,7 +293,7 @@ wLowerFrame(WCoreWindow *frame)
{
WScreen *scr=frame->screen_ptr;
WCoreWindow *prev, *wlist=frame;
int level = levelToIndex(frame->stacking->window_level);
int level = frame->stacking->window_level;
int i;
/* already in bottom */
@@ -401,10 +382,10 @@ void
AddToStackList(WCoreWindow *frame)
{
WCoreWindow *prev, *tmpw, *wlist;
int index = levelToIndex(frame->stacking->window_level);
int index = frame->stacking->window_level;
frame->screen_ptr->window_count++;
frame->screen_ptr->window_level_count[index]++;
/* frame->screen_ptr->window_level_count[index]++;*/
XSaveContext(dpy, frame->window, wStackContext, (XPointer)frame);
tmpw = frame->screen_ptr->stacking_list[index];
if (!tmpw) {
@@ -474,7 +455,7 @@ MoveInStackListAbove(WCoreWindow *next, WCoreWindow *frame)
if (frame->stacking->window_level != next->stacking->window_level)
ChangeStackingLevel(frame, next->stacking->window_level);
index = levelToIndex(frame->stacking->window_level);
index = frame->stacking->window_level;
tmpw = frame->screen_ptr->stacking_list[index];
if (tmpw == frame)
@@ -541,7 +522,7 @@ MoveInStackListUnder(WCoreWindow *prev, WCoreWindow *frame)
if (frame->stacking->window_level != prev->stacking->window_level)
ChangeStackingLevel(frame, prev->stacking->window_level);
index = levelToIndex(frame->stacking->window_level);
index = frame->stacking->window_level;
tmpw = frame->screen_ptr->stacking_list[index];
if (tmpw == frame)
@@ -562,7 +543,7 @@ MoveInStackListUnder(WCoreWindow *prev, WCoreWindow *frame)
void
RemoveFromStackList(WCoreWindow *frame)
{
int index = levelToIndex(frame->stacking->window_level);
int index = frame->stacking->window_level;
if (XDeleteContext(dpy, frame->window, wStackContext)==XCNOENT) {
#ifdef DEBUG0
@@ -579,7 +560,7 @@ RemoveFromStackList(WCoreWindow *frame)
frame->screen_ptr->stacking_list[index] = frame->stacking->under;
frame->screen_ptr->window_count--;
frame->screen_ptr->window_level_count[index]--;
/* frame->screen_ptr->window_level_count[index]--;*/
}

View File

@@ -70,6 +70,12 @@ extern const char * const sys_siglist[];
#endif
#endif
/* for SunOS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
/****** Global Variables ******/
extern WPreferences wPreferences;
@@ -148,6 +154,9 @@ static void manageAllWindows();
extern void NotifyDeadProcess(pid_t pid, unsigned char status);
#ifdef R6SM
extern void _wSessionCloseDescriptors();
#endif
static int
@@ -199,11 +208,10 @@ catchXError(Display *dpy, XErrorEvent *error)
static int
handleXIO(Display *dpy)
{
exit(0);
Exit(0);
}
/*
*----------------------------------------------------------------------
* delayedAction-
@@ -554,6 +562,16 @@ wScreenForWindow(Window window)
}
void
CloseDescriptors()
{
if (dpy)
close(ConnectionNumber(dpy));
#ifdef R6SM
_wSessionCloseDescriptors();
#endif
}
/*
*----------------------------------------------------------
@@ -738,7 +756,7 @@ StartUp(Bool defaultScreenOnly)
wScreen[wScreenCount] = wScreenInit(DefaultScreen(dpy));
if (!wScreen[wScreenCount]) {
wfatal(_("it seems that there already is a window manager running"));
exit(1);
Exit(1);
}
} else {
wScreen[wScreenCount] = wScreenInit(j);
@@ -800,11 +818,13 @@ StartUp(Bool defaultScreenOnly)
if (wScreenCount == 0) {
wfatal(_("could not manage any screen"));
exit(1);
Exit(1);
}
/* setup defaults file polling */
WMAddTimerHandler(3000, wDefaultsCheckDomains, NULL);
if (!wPreferences.flags.noupdates) {
/* setup defaults file polling */
WMAddTimerHandler(3000, wDefaultsCheckDomains, NULL);
}
}

View File

@@ -42,14 +42,6 @@
#define ANIMATIONS
/*
* mimic N*XTSTEP behaviour as close as possible.
* affected behaviour:
* - disable auto-lower miniwindows
*/
#undef STRICTNS
/*
* undefine USECPP if you don't want your config files to be preprocessed
* by cpp
@@ -114,6 +106,11 @@
#define MWM_HINTS
/* Define if you have a 5 button mouse and want to use button 4
* (in the root window) for switching to the previous workspace
* and 5 for the next */
#undef MOUSE_WS_SWITCH
/*
* Turn on a hack to make mouse and keyboard actions work even if
* the NumLock or ScrollLock modifiers are turned on. They might
@@ -199,6 +196,8 @@
#define DEF_CONFIG_PATHS \
"~/GNUstep/Library/WindowMaker:"PKGDATADIR
#define DEF_MENU_FILE "menu"
/* name of the script to execute at startup */
#define DEF_INIT_SCRIPT "autostart"
@@ -249,6 +248,10 @@
#define DEF_APPMENU_X 10
#define DEF_APPMENU_Y 10
/* Window level where icons reside */
#define NORMAL_ICON_LEVEL WMNormalLevel
/* do not divide main menu and submenu in different tiers,
* opposed to OpenStep */
#define SINGLE_MENULEVEL

View File

@@ -42,14 +42,6 @@
#define ANIMATIONS
/*
* mimic N*XTSTEP behaviour as close as possible.
* affected behaviour:
* - disable auto-lower miniwindows
*/
#undef STRICTNS
/*
* undefine USECPP if you don't want your config files to be preprocessed
* by cpp
@@ -114,6 +106,11 @@
#define MWM_HINTS
/* Define if you have a 5 button mouse and want to use button 4
* (in the root window) for switching to the previous workspace
* and 5 for the next */
#undef MOUSE_WS_SWITCH
/*
* Turn on a hack to make mouse and keyboard actions work even if
* the NumLock or ScrollLock modifiers are turned on. They might
@@ -199,6 +196,8 @@
#define DEF_CONFIG_PATHS \
"~/GNUstep/Library/WindowMaker:"PKGDATADIR
#define DEF_MENU_FILE "menu"
/* name of the script to execute at startup */
#define DEF_INIT_SCRIPT "autostart"
@@ -249,6 +248,10 @@
#define DEF_APPMENU_X 10
#define DEF_APPMENU_Y 10
/* Window level where icons reside */
#define NORMAL_ICON_LEVEL WMNormalLevel
/* do not divide main menu and submenu in different tiers,
* opposed to OpenStep */
#define SINGLE_MENULEVEL

View File

@@ -71,6 +71,7 @@ static proplist_t ANoMouseBindings;
static proplist_t ANoKeyBindings;
static proplist_t ANoAppIcon; /* app */
static proplist_t AKeepOnTop;
static proplist_t AKeepOnBottom;
static proplist_t AOmnipresent;
static proplist_t ASkipWindowList;
static proplist_t AKeepInsideScreen;
@@ -104,6 +105,7 @@ init_wdefaults(WScreen *scr)
ANoKeyBindings = PLMakeString("NoKeyBindings");
ANoAppIcon = PLMakeString("NoAppIcon");
AKeepOnTop = PLMakeString("KeepOnTop");
AKeepOnBottom = PLMakeString("KeepOnBottom");
AOmnipresent = PLMakeString("Omnipresent");
ASkipWindowList = PLMakeString("SkipWindowList");
AKeepInsideScreen = PLMakeString("KeepInsideScreen");
@@ -254,6 +256,10 @@ wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
if (value)
attr->floating = getBool(AKeepOnTop, value);
value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
if (value)
attr->floating = getBool(AKeepOnBottom, value);
value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
if (value)
attr->omnipresent = getBool(AOmnipresent, value);
@@ -522,7 +528,8 @@ wDefaultChangeIcon(WScreen *scr, char *instance, char* class, char *file)
else if (icon_value!=NULL && !same) {
PLInsertDictionaryEntry(dict, key, icon_value);
}
PLSave(dict, YES);
if (!wPreferences.flags.noupdates)
PLSave(dict, YES);
PLRelease(key);
if(icon_value)

View File

@@ -401,6 +401,9 @@ wWindowCheckAttributeSanity(WWindow *wwin, WWindowAttributes *wflags)
if (wwin->transient_for!=None
&& wwin->transient_for!=wwin->screen_ptr->root_win)
wflags->emulate_appicon = 0;
if (wflags->sunken && wflags->floating)
wflags->sunken = 0;
}
@@ -527,11 +530,9 @@ wManageWindow(WScreen *scr, Window window)
motif_hints = NULL;
#endif /* MWM_HINTS */
if (!PropGetClientLeader(window, &wwin->client_leader)) {
wwin->client_leader = None;
} else {
wwin->client_leader = PropGetClientLeader(window);
if (wwin->client_leader!=None)
wwin->main_window = wwin->client_leader;
}
if (wwin->wm_hints)
XFree(wwin->wm_hints);
@@ -642,11 +643,32 @@ wManageWindow(WScreen *scr, Window window)
/* set GNUstep window attributes */
if (wwin->wm_gnustep_attr) {
setupGNUstepHints(&wwin->window_flags, wwin->wm_gnustep_attr);
if (wwin->wm_gnustep_attr->flags & GSWindowLevelAttr) {
window_level = wwin->wm_gnustep_attr->window_level;
switch (wwin->wm_gnustep_attr->window_level) {
case WMNormalWindowLevel:
window_level = WMNormalLevel;
break;
case WMFloatingWindowLevel:
window_level = WMFloatingLevel;
break;
case WMDockWindowLevel:
window_level = WMDockLevel;
break;
case WMSubmenuWindowLevel:
window_level = WMSubmenuLevel;
break;
case WMMainMenuWindowLevel:
window_level = WMMainMenuLevel;
break;
default:
window_level = WMNormalLevel;
break;
}
} else {
/* setup defaults */
window_level = WMNormalWindowLevel;
window_level = WMNormalLevel;
}
} else {
#ifdef MWM_HINTS
@@ -655,9 +677,11 @@ wManageWindow(WScreen *scr, Window window)
}
#endif /* MWM_HINTS */
if (wwin->window_flags.floating)
window_level = WMFloatingWindowLevel;
window_level = WMFloatingLevel;
else if (wwin->window_flags.sunken)
window_level = WMSunkenLevel;
else
window_level = WMNormalWindowLevel;
window_level = WMNormalLevel;
}
#ifdef MWM_HINTS
if (motif_hints)
@@ -1080,7 +1104,7 @@ wManageInternalWindow(WScreen *scr, Window window, Window owner,
foo = WFF_RIGHT_BUTTON;
foo |= WFF_TITLEBAR;
wwin->frame = wFrameWindowCreate(scr, WMFloatingWindowLevel,
wwin->frame = wFrameWindowCreate(scr, WMFloatingLevel,
wwin->frame_x, wwin->frame_y,
width, height, foo,
scr->window_title_texture,
@@ -1474,6 +1498,7 @@ wWindowChangeWorkspace(WWindow *wwin, int workspace)
{
WScreen *scr = wwin->screen_ptr;
WApplication *wapp;
int unmap = 0;
if (workspace >= scr->workspace_count || workspace < 0
|| workspace == wwin->frame->workspace)
@@ -1489,7 +1514,7 @@ wWindowChangeWorkspace(WWindow *wwin, int workspace)
if (wapp) {
wapp->last_workspace = workspace;
}
XUnmapWindow(dpy, wwin->frame->core->window);
unmap = 1;
wwin->flags.mapped = 0;
wSetFocusTo(scr, NULL);
}
@@ -1504,6 +1529,8 @@ wWindowChangeWorkspace(WWindow *wwin, int workspace)
wwin->frame->workspace = workspace;
UpdateSwitchMenu(scr, wwin, ACTION_CHANGE_WORKSPACE);
}
if (unmap)
XUnmapWindow(dpy, wwin->frame->core->window);
}
@@ -2028,13 +2055,21 @@ wWindowSetKeyGrabs(WWindow *wwin)
void
wWindowResetMouseGrabs(WWindow *wwin)
{
/* Mouse grabs can't be done on the client window because of
* ICCCM and because clients that try to do the same will crash.
*
* But there is a problem wich makes tbar buttons of unfocused
* windows not usable as the click goes to the frame window instead
* of the button itself. Must figure a way to fix that.
*/
XUngrabButton(dpy, AnyButton, AnyModifier, wwin->client_win);
if (!wwin->window_flags.no_bind_mouse) {
/* grabs for Meta+drag */
wHackedGrabButton(AnyButton, MOD_MASK, wwin->client_win,
wHackedGrabButton(AnyButton, MOD_MASK, wwin->client_win,
True, ButtonPressMask, GrabModeSync,
GrabModeAsync, None, wCursor[WCUR_ARROW]);
GrabModeAsync, None, None);
}
if (!wwin->flags.focused) {
@@ -2255,9 +2290,7 @@ resizebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
if (event->xbutton.button == Button1)
wRaiseFrame(wwin->frame->core);
if (event->xbutton.state & MOD_MASK) {
/* move the window */
#if 0
if (event->xbutton.window != wwin->frame->resizebar->window) {
if (XGrabPointer(dpy, wwin->frame->resizebar->window, True,
ButtonMotionMask|ButtonReleaseMask|ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
@@ -2267,22 +2300,13 @@ resizebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
#endif
return;
}
#endif
}
if (event->xbutton.state & MOD_MASK) {
/* move the window */
wMouseMoveWindow(wwin, event);
XUngrabPointer(dpy, CurrentTime);
} else {
#if 0
/* resize the window */
if (XGrabPointer(dpy, wwin->frame->resizebar->window, True,
ButtonMotionMask|ButtonReleaseMask|ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
None, CurrentTime)!=GrabSuccess) {
#ifdef DEBUG0
wwarning("pointer grab failed for window resize");
#endif
return;
}
#endif
wMouseResizeWindow(wwin, event);
XUngrabPointer(dpy, CurrentTime);
}
@@ -2385,17 +2409,15 @@ titlebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
"Turn it off or some mouse actions and keyboard shortcuts will not work."));
}
#endif
event->xbutton.state &= ValidModMask;
CloseWindowMenu(wwin->screen_ptr);
if (wPreferences.focus_mode==WKF_CLICK
&& !(event->xbutton.state&ControlMask)) {
wSetFocusTo(wwin->screen_ptr, wwin);
}
if (event->xbutton.button == Button1
|| event->xbutton.button == Button2) {
@@ -2411,13 +2433,36 @@ titlebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
wSelectWindow(wwin, !wwin->flags.selected);
return;
}
if (event->xbutton.window != wwin->frame->titlebar->window
&& XGrabPointer(dpy, wwin->frame->titlebar->window, False,
ButtonMotionMask|ButtonReleaseMask|ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
None, CurrentTime)!=GrabSuccess) {
#ifdef DEBUG0
wwarning("pointer grab failed for window move");
#endif
return;
}
/* move the window */
wMouseMoveWindow(wwin, event);
XUngrabPointer(dpy, CurrentTime);
} else if (event->xbutton.button == Button3 && event->xbutton.state==0
&& !wwin->flags.internal_window) {
WObjDescriptor *desc;
if (event->xbutton.window != wwin->frame->titlebar->window
&& XGrabPointer(dpy, wwin->frame->titlebar->window, False,
ButtonMotionMask|ButtonReleaseMask|ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
None, CurrentTime)!=GrabSuccess) {
#ifdef DEBUG0
wwarning("pointer grab failed for window move");
#endif
return;
}
OpenWindowMenu(wwin, event->xbutton.x_root,
wwin->frame_y+wwin->frame->top_width, False);
@@ -2425,6 +2470,8 @@ titlebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
desc = &wwin->screen_ptr->window_menu->menu->descriptor;
event->xany.send_event = True;
(*desc->handle_mousedown)(desc, event);
XUngrabPointer(dpy, CurrentTime);
}
}

View File

@@ -91,7 +91,8 @@ typedef struct {
unsigned int no_shadeable:1;
unsigned int omnipresent:1;
unsigned int skip_window_list:1;
unsigned int floating:1; /* put in NSFloatingWindowLevel */
unsigned int floating:1; /* put in WMFloatingLevel */
unsigned int sunken:1; /* put in WMSunkenLevel */
unsigned int no_bind_keys:1; /* intercept wm kbd binds
* while window is focused */
unsigned int no_bind_mouse:1; /* intercept mouse events

View File

@@ -62,6 +62,7 @@ static proplist_t ANoMouseBindings;
static proplist_t ANoKeyBindings;
static proplist_t ANoAppIcon;
static proplist_t AKeepOnTop;
static proplist_t AKeepOnBottom;
static proplist_t AOmnipresent;
static proplist_t ASkipWindowList;
static proplist_t AKeepInsideScreen;
@@ -106,6 +107,7 @@ make_keys()
ANoKeyBindings = PLMakeString("NoKeyBindings");
ANoAppIcon = PLMakeString("NoAppIcon");
AKeepOnTop = PLMakeString("KeepOnTop");
AKeepOnBottom = PLMakeString("KeepOnBottom");
AOmnipresent = PLMakeString("Omnipresent");
ASkipWindowList = PLMakeString("SkipWindowList");
AKeepInsideScreen = PLMakeString("KeepInsideScreen");
@@ -494,12 +496,15 @@ saveSettings(WMButton *button, InspectorPanel *panel)
insertAttribute(dict, winDic, AKeepOnTop, value, &different, flags);
value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
insertAttribute(dict, winDic, AOmnipresent, value, &different, flags);
insertAttribute(dict, winDic, AKeepOnBottom, value, &different, flags);
value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
insertAttribute(dict, winDic, AStartMiniaturized, value, &different, flags);
insertAttribute(dict, winDic, AOmnipresent, value, &different, flags);
value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
insertAttribute(dict, winDic, AStartMiniaturized, value, &different, flags);
value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
insertAttribute(dict, winDic, ASkipWindowList, value, &different, flags);
@@ -627,9 +632,6 @@ makeAppIconFor(WApplication *wapp)
} else {
PlaceIcon(scr, &x, &y);
wAppIconMove(wapp->app_icon, x, y);
#ifndef STRICTNS
wLowerFrame(icon->core);
#endif
}
if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
XMapWindow(dpy, icon->core->window);
@@ -677,7 +679,7 @@ applySettings(WMButton *button, InspectorPanel *panel)
WWindowAttributes *wflags = &wwin->window_flags;
WWindowAttributes oldFlags = *wflags;
WApplication *wapp = wApplicationOf(wwin->main_window);
int floating, skip_window_list;
int floating, sunken, skip_window_list;
showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
@@ -686,9 +688,11 @@ applySettings(WMButton *button, InspectorPanel *panel)
wflags->no_close_button = WMGetButtonSelected(panel->attrChk[2]);
wflags->no_miniaturize_button = WMGetButtonSelected(panel->attrChk[3]);
floating = WMGetButtonSelected(panel->attrChk[4]);
wflags->omnipresent = WMGetButtonSelected(panel->attrChk[5]);
wflags->start_miniaturized = WMGetButtonSelected(panel->attrChk[6]);
skip_window_list = WMGetButtonSelected(panel->attrChk[7]);
sunken = WMGetButtonSelected(panel->attrChk[5]);
wflags->omnipresent = WMGetButtonSelected(panel->attrChk[6]);
wflags->start_miniaturized = WMGetButtonSelected(panel->attrChk[7]);
skip_window_list = WMGetButtonSelected(panel->attrChk[8]);
wflags->no_hide_others = WMGetButtonSelected(panel->moreChk[0]);
wflags->no_bind_keys = WMGetButtonSelected(panel->moreChk[1]);
wflags->no_bind_mouse = WMGetButtonSelected(panel->moreChk[2]);
@@ -702,12 +706,21 @@ applySettings(WMButton *button, InspectorPanel *panel)
wUnshadeWindow(wwin);
wflags->no_shadeable = wflags->no_titlebar;
if (wflags->floating != floating) {
int wlevel = ((wflags->floating = floating))
? WMFloatingWindowLevel : WMNormalWindowLevel;
ChangeStackingLevel(wwin->frame->core, wlevel);
if (floating) {
if (!wflags->floating)
ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
} else if (sunken) {
if (!wflags->sunken)
ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
} else {
if (wflags->floating || wflags->sunken)
ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
}
wflags->sunken = sunken;
wflags->floating = floating;
if (wflags->skip_window_list != skip_window_list) {
int action = ((wflags->skip_window_list = skip_window_list))
? ACTION_REMOVE : ACTION_ADD;
@@ -767,7 +780,7 @@ revertSettings(WMButton *button, InspectorPanel *panel)
{
WWindow *wwin = panel->inspected;
WApplication *wapp = wApplicationOf(wwin->main_window);
int i, n, floating, skip_window_list;
int i, n, floating, sunken, skip_window_list;
char *wm_instance = NULL;
char *wm_class = NULL;
@@ -797,7 +810,7 @@ revertSettings(WMButton *button, InspectorPanel *panel)
wwin->window_flags.no_shadeable = wwin->window_flags.no_titlebar;
for (i=0; i < 8; i++) {
for (i=0; i < 9; i++) {
int flag = 0;
switch (i) {
@@ -814,27 +827,18 @@ revertSettings(WMButton *button, InspectorPanel *panel)
flag = wwin->window_flags.no_miniaturize_button;
break;
case 4:
floating = WMGetButtonSelected(panel->attrChk[4]);
if (wwin->window_flags.floating != floating) {
int wlevel = (wwin->window_flags.floating != 0)
? WMFloatingWindowLevel : WMNormalWindowLevel;
ChangeStackingLevel(wwin->frame->core, wlevel);
}
flag = wwin->window_flags.floating;
break;
case 5:
flag = wwin->window_flags.omnipresent;
flag = wwin->window_flags.sunken;
break;
case 6:
flag = wwin->window_flags.no_focusable;
flag = wwin->window_flags.omnipresent;
break;
case 7:
skip_window_list = WMGetButtonSelected(panel->attrChk[7]);
if (wwin->window_flags.skip_window_list != skip_window_list) {
int action = (wwin->window_flags.skip_window_list != 0)
? ACTION_REMOVE : ACTION_ADD;
UpdateSwitchMenu(wwin->screen_ptr, wwin, action);
}
flag = wwin->window_flags.no_focusable;
break;
case 8:
flag = wwin->window_flags.skip_window_list;
break;
}
@@ -988,6 +992,8 @@ createInspectorForWindow(WWindow *wwin)
WMMoveWidget(panel->saveBtn, 15, 310);
WMSetButtonText(panel->saveBtn, _("Save"));
WMResizeWidget(panel->saveBtn, btn_width, 28);
if (wPreferences.flags.noupdates)
WMSetButtonEnabled(panel->saveBtn, False);
panel->applyBtn = WMCreateCommandButton(panel->win);
WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
@@ -1072,7 +1078,7 @@ createInspectorForWindow(WWindow *wwin)
WMMoveWidget(panel->attrFrm, 15, 50);
WMResizeWidget(panel->attrFrm, frame_width, 240);
for (i=0; i < 8; i++) {
for (i=0; i < 9; i++) {
char *caption = NULL;
int flag = 0;
@@ -1094,18 +1100,22 @@ createInspectorForWindow(WWindow *wwin)
flag = wwin->window_flags.no_miniaturize_button;
break;
case 4:
caption = _("Keep on top");
caption = _("Keep on top / floating");
flag = wwin->window_flags.floating;
break;
case 5:
caption = _("Keep on bottom / sunken");
flag = wwin->window_flags.sunken;
break;
case 6:
caption = _("Omnipresent");
flag = wwin->window_flags.omnipresent;
break;
case 6:
case 7:
caption = _("Start Miniaturized");
flag = wwin->window_flags.start_miniaturized;
break;
case 7:
case 8:
caption = _("Skip window list");
flag = wwin->window_flags.skip_window_list;
break;

View File

@@ -56,8 +56,8 @@ typedef struct InspectorPanel {
/* second page. attributes */
WMFrame *attrFrm;
WMButton *attrChk[8];
WMButton *attrChk[9];
/* 3rd page. more attributes */
WMFrame *moreFrm;
WMButton *moreChk[7];