From 93344d05ef849a1fe480f2a8f5471cbc993085b3b0cd852f2e44e09107919890 Mon Sep 17 00:00:00 2001 From: Togan Muftuoglu Date: Tue, 18 Sep 2012 14:53:16 +0000 Subject: [PATCH] Accepting request 134873 from home:computersalat:branches:X11:windowmanagers fix for bnc#780348 OBS-URL: https://build.opensuse.org/request/show/134873 OBS-URL: https://build.opensuse.org/package/show/X11:windowmanagers/WindowMaker?expand=0&rev=19 --- WindowMaker-81eefca4e.patch | 3579 +++++++++++++++++++++++++++++++++++ WindowMaker.changes | 11 + WindowMaker.spec | 4 + 3 files changed, 3594 insertions(+) create mode 100644 WindowMaker-81eefca4e.patch diff --git a/WindowMaker-81eefca4e.patch b/WindowMaker-81eefca4e.patch new file mode 100644 index 0000000..df9f719 --- /dev/null +++ b/WindowMaker-81eefca4e.patch @@ -0,0 +1,3579 @@ +Index: WINGs/array.c +=================================================================== +--- WINGs/array.c.orig ++++ WINGs/array.c +@@ -198,6 +198,9 @@ void *WMGetFromArray(WMArray * array, in + + void *WMPopFromArray(WMArray * array) + { ++ if (array->itemCount <= 0) ++ return NULL; ++ + array->itemCount--; + + return array->items[array->itemCount]; +Index: WPrefs.app/WindowHandling.c +=================================================================== +--- WPrefs.app/WindowHandling.c.orig ++++ WPrefs.app/WindowHandling.c +@@ -82,7 +82,8 @@ static char *placements[] = { + "random", + "manual", + "cascade", +- "smart" ++ "smart", ++ "center" + }; + + static void sliderCallback(WMWidget * w, void *data) +@@ -151,6 +152,8 @@ static int getPlacement(char *str) + return 3; + else if (strcasecmp(str, "smart") == 0) + return 4; ++ else if (strcasecmp(str, "center") == 0) ++ return 5; + else + wwarning(_("bad option value %s in WindowPlacement. Using default value"), str); + return 0; +@@ -266,6 +269,7 @@ static void createPanel(Panel * p) + WMAddPopUpButtonItem(panel->placP, _("Manual")); + WMAddPopUpButtonItem(panel->placP, _("Cascade")); + WMAddPopUpButtonItem(panel->placP, _("Smart")); ++ WMAddPopUpButtonItem(panel->placP, _("Center")); + + panel->porigL = WMCreateLabel(panel->placF); + WMResizeWidget(panel->porigL, 120, 32); +Index: src/WindowMaker.h +=================================================================== +--- src/WindowMaker.h.orig ++++ src/WindowMaker.h +@@ -153,6 +153,7 @@ typedef enum { + #define WPM_SMART 2 + #define WPM_RANDOM 3 + #define WPM_AUTO 4 ++#define WPM_CENTER 5 + + /* text justification */ + #define WTJ_CENTER 0 +@@ -447,19 +448,12 @@ typedef struct WPreferences { + } flags; /* internal flags */ + } WPreferences; + +- +- + /****** Global Variables ******/ + extern Display *dpy; + extern unsigned int ValidModMask; + extern char WProgramState; + extern char WProgramSigState; + +- +-/****** Global Functions ******/ +-extern void wAbort(Bool dumpCore); +- +- + /****** Notifications ******/ + extern const char *WMNManaged; + extern const char *WMNUnmanaged; +@@ -476,4 +470,3 @@ extern const char *WMNWorkspaceNameChang + + extern const char *WMNResetStacking; + #endif +- +Index: src/actions.c +=================================================================== +--- src/actions.c.orig ++++ src/actions.c +@@ -35,7 +35,7 @@ + #include "window.h" + #include "client.h" + #include "icon.h" +-#include "funcs.h" ++#include "colormap.h" + #include "application.h" + #include "actions.h" + #include "stacking.h" +@@ -45,6 +45,7 @@ + #include "winspector.h" + #include "workspace.h" + #include "xinerama.h" ++#include "usermenu.h" + + /****** Global Variables ******/ + +@@ -286,14 +287,20 @@ void wUnshadeWindow(WWindow *wwin) + /* Set the old coordinates using the current values */ + static void save_old_geometry(WWindow *wwin, int directions) + { +- if (directions & MAX_HORIZONTAL || ! wwin->old_geometry.width) { +- wwin->old_geometry.width = wwin->client.width; ++ /* never been saved? */ ++ if (! wwin->old_geometry.width) ++ directions |= SAVE_GEOMETRY_X | SAVE_GEOMETRY_WIDTH; ++ if (! wwin->old_geometry.height) ++ directions |= SAVE_GEOMETRY_Y | SAVE_GEOMETRY_HEIGHT; ++ ++ if (directions & SAVE_GEOMETRY_X) + wwin->old_geometry.x = wwin->frame_x; +- } +- if (directions & MAX_VERTICAL || ! wwin->old_geometry.height) { +- wwin->old_geometry.height = wwin->client.height; ++ if (directions & SAVE_GEOMETRY_Y) + wwin->old_geometry.y = wwin->frame_y; +- } ++ if (directions & SAVE_GEOMETRY_WIDTH) ++ wwin->old_geometry.width = wwin->client.width; ++ if (directions & SAVE_GEOMETRY_HEIGHT) ++ wwin->old_geometry.height = wwin->client.height; + } + + static void remember_geometry(WWindow *wwin, int *x, int *y, int *w, int *h) +@@ -311,13 +318,36 @@ static void remember_geometry(WWindow *w + *h = wwin->old_geometry.height ? wwin->old_geometry.height : wwin->client.height; + } + ++/* Remember geometry for unmaximizing */ ++void update_saved_geometry(WWindow *wwin) ++{ ++ /* NOT if we aren't already maximized ++ * we'll save geometry when maximizing */ ++ if (!wwin->flags.maximized) ++ return; ++ ++ /* NOT if we are fully maximized */ ++ if ((wwin->flags.maximized & MAX_MAXIMUS) || ++ ((wwin->flags.maximized & MAX_HORIZONTAL) && ++ (wwin->flags.maximized & MAX_VERTICAL))) ++ return; ++ ++ /* save the co-ordinate in the axis in which we AREN'T maximized */ ++ if (wwin->flags.maximized & MAX_HORIZONTAL) ++ save_old_geometry(wwin, SAVE_GEOMETRY_Y); ++ if (wwin->flags.maximized & MAX_VERTICAL) ++ save_old_geometry(wwin, SAVE_GEOMETRY_X); ++} ++ + #define IS_MAX_HORIZONTALLY(directions) ((directions & MAX_HORIZONTAL) | (directions & MAX_LEFTHALF) | (directions & MAX_RIGHTHALF)) + void wMaximizeWindow(WWindow *wwin, int directions) + { + int new_x, new_y; + unsigned int new_width, new_height, half_scr_width; +- int maximus_x, maximus_y; +- unsigned int maximus_width, maximus_height; ++ int maximus_x = 0; ++ int maximus_y = 0; ++ unsigned int maximus_width = 0; ++ unsigned int maximus_height = 0; + WArea usableArea, totalArea; + Bool has_border = 1; + int save_directions = 0; +@@ -333,17 +363,20 @@ void wMaximizeWindow(WWindow *wwin, int + adj_size = FRAME_BORDER_WIDTH * 2 * has_border; + + /* save old coordinates before we change the current values ++ * always if the window is not currently maximized at all + * but never if the window has been Maximusized */ +- if (!(wwin->flags.old_maximized & MAX_MAXIMUS)) { ++ if (!wwin->flags.maximized) ++ save_directions |= SAVE_GEOMETRY_ALL; ++ else if (!(wwin->flags.old_maximized & MAX_MAXIMUS)) { + if ((directions & MAX_VERTICAL) && + !(wwin->flags.maximized & MAX_VERTICAL)) +- save_directions |= MAX_VERTICAL; ++ save_directions |= SAVE_GEOMETRY_Y | SAVE_GEOMETRY_HEIGHT; + if (IS_MAX_HORIZONTALLY(directions) && + !IS_MAX_HORIZONTALLY(wwin->flags.maximized)) +- save_directions |= MAX_HORIZONTAL; ++ save_directions |= SAVE_GEOMETRY_X | SAVE_GEOMETRY_WIDTH; + } + if ((directions & MAX_MAXIMUS) && !wwin->flags.maximized) +- save_directions |= MAX_VERTICAL | MAX_HORIZONTAL; ++ save_directions |= SAVE_GEOMETRY_ALL; + save_old_geometry(wwin, save_directions); + + totalArea.x1 = 0; +@@ -442,6 +475,8 @@ void wMaximizeWindow(WWindow *wwin, int + new_y -= wwin->frame->top_width; + new_height += wwin->frame->top_width - 1; + } ++ wwin->maximus_x = new_x; ++ wwin->maximus_y = new_y; + wwin->flags.old_maximized |= MAX_MAXIMUS; + } + +@@ -670,9 +705,16 @@ void wUnmaximizeWindow(WWindow *wwin) + wwin->flags.skip_next_animation = 1; + wUnshadeWindow(wwin); + } ++ + /* Use old coordinates if they are set, current values otherwise */ + remember_geometry(wwin, &x, &y, &w, &h); + ++ /* unMaximusize relative to original position */ ++ if (wwin->flags.maximized & MAX_MAXIMUS) { ++ x += wwin->frame_x - wwin->maximus_x; ++ y += wwin->frame_y - wwin->maximus_y; ++ } ++ + wwin->flags.maximized = 0; + wwin->flags.old_maximized = 0; + wWindowConfigure(wwin, x, y, w, h); +@@ -1764,9 +1806,8 @@ void wArrangeIcons(WScreen *scr, Bool ar + + if (aicon->x_pos != X || aicon->y_pos != Y) { + #ifdef ANIMATIONS +- if (!wPreferences.no_animations) { ++ if (!wPreferences.no_animations) + SlideWindow(aicon->icon->core->window, aicon->x_pos, aicon->y_pos, X, Y); +- } + #endif /* ANIMATIONS */ + } + wAppIconMove(aicon, X, Y); +@@ -1793,18 +1834,9 @@ void wArrangeIcons(WScreen *scr, Bool ar + head = wGetHeadForWindow(wwin); + + if (arrangeAll || !wwin->flags.icon_moved) { +- if (wwin->icon_x != X || wwin->icon_y != Y) { +-#ifdef ANIMATIONS +- if (wPreferences.no_animations) { +- XMoveWindow(dpy, wwin->icon->core->window, X, Y); +- } else { +- SlideWindow(wwin->icon->core->window, wwin->icon_x, +- wwin->icon_y, X, Y); +- } +-#else +- XMoveWindow(dpy, wwin->icon->core->window, X, Y); +-#endif /* ANIMATIONS */ +- } ++ if (wwin->icon_x != X || wwin->icon_y != Y) ++ move_window(wwin->icon->core->window, wwin->icon_x, wwin->icon_y, X, Y); ++ + wwin->icon_x = X; + wwin->icon_y = Y; + +@@ -1891,7 +1923,7 @@ static void shade_animate(WWindow *wwin, + int y, s, w, h; + time_t time0 = time(NULL); + +- if (wwin->flags.skip_next_animation && wPreferences.no_animations) ++ if (wwin->flags.skip_next_animation || wPreferences.no_animations) + return; + + switch(what) { +Index: src/actions.h +=================================================================== +--- src/actions.h.orig ++++ src/actions.h +@@ -31,6 +31,12 @@ + #define MAX_IGNORE_XINERAMA (1 << 5) + #define MAX_KEYBOARD (1 << 6) + ++#define SAVE_GEOMETRY_X (1 << 0) ++#define SAVE_GEOMETRY_Y (1 << 1) ++#define SAVE_GEOMETRY_WIDTH (1 << 2) ++#define SAVE_GEOMETRY_HEIGHT (1 << 3) ++#define SAVE_GEOMETRY_ALL SAVE_GEOMETRY_X | SAVE_GEOMETRY_Y | SAVE_GEOMETRY_WIDTH | SAVE_GEOMETRY_HEIGHT ++ + void wSetFocusTo(WScreen *scr, WWindow *wwin); + + int wMouseMoveWindow(WWindow *wwin, XEvent *ev); +@@ -71,6 +77,7 @@ void wFullscreenWindow(WWindow *wwin); + void wUnfullscreenWindow(WWindow *wwin); + + void animateResize(WScreen *scr, int x, int y, int w, int h, int fx, int fy, int fw, int fh); ++void update_saved_geometry(WWindow *wwin); + + #endif + +Index: src/appicon.c +=================================================================== +--- src/appicon.c.orig ++++ src/appicon.c +@@ -26,6 +26,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "WindowMaker.h" + #include "window.h" +@@ -35,13 +38,14 @@ + #include "actions.h" + #include "stacking.h" + #include "dock.h" +-#include "funcs.h" ++#include "main.h" + #include "defaults.h" + #include "workspace.h" + #include "superfluous.h" + #include "menu.h" + #include "framewin.h" + #include "dialog.h" ++#include "xinerama.h" + #include "client.h" + #ifdef XDND + #include "xdnd.h" +@@ -55,12 +59,52 @@ + /**** Global variables ****/ + extern Cursor wCursor[WCUR_LAST]; + extern WPreferences wPreferences; ++extern WDDomain *WDWindowAttributes; + + #define MOD_MASK wPreferences.modifier_mask + + void appIconMouseDown(WObjDescriptor * desc, XEvent * event); + static void iconDblClick(WObjDescriptor * desc, XEvent * event); + static void iconExpose(WObjDescriptor * desc, XEvent * event); ++static void wApplicationSaveIconPathFor(char *iconPath, char *wm_instance, char *wm_class); ++static WAppIcon *wAppIconCreate(WWindow * leader_win); ++static void add_to_appicon_list(WScreen *scr, WAppIcon *appicon); ++static void remove_from_appicon_list(WScreen *scr, WAppIcon *appicon); ++ ++/* This function is used if the application is a .app. It checks if it has an icon in it ++ * like for example /usr/local/GNUstep/Applications/WPrefs.app/WPrefs.tiff ++ */ ++static void wApplicationExtractDirPackIcon(WScreen * scr, char *path, char *wm_instance, char *wm_class) ++{ ++ char *iconPath = NULL; ++ char *tmp = NULL; ++ ++ if (strstr(path, ".app")) { ++ tmp = wmalloc(strlen(path) + 16); ++ ++ if (scr->flags.supports_tiff) { ++ strcpy(tmp, path); ++ strcat(tmp, ".tiff"); ++ if (access(tmp, R_OK) == 0) ++ iconPath = tmp; ++ } ++ ++ if (!iconPath) { ++ strcpy(tmp, path); ++ strcat(tmp, ".xpm"); ++ if (access(tmp, R_OK) == 0) ++ iconPath = tmp; ++ } ++ ++ if (!iconPath) ++ wfree(tmp); ++ ++ if (iconPath) { ++ wApplicationSaveIconPathFor(iconPath, wm_instance, wm_class); ++ wfree(iconPath); ++ } ++ } ++} + + WAppIcon *wAppIconCreateForDock(WScreen * scr, char *command, char *wm_instance, char *wm_class, int tile) + { +@@ -72,12 +116,7 @@ WAppIcon *wAppIconCreateForDock(WScreen + dicon->yindex = -1; + dicon->xindex = -1; + +- dicon->prev = NULL; +- dicon->next = scr->app_icon_list; +- if (scr->app_icon_list) +- scr->app_icon_list->prev = dicon; +- +- scr->app_icon_list = dicon; ++ add_to_appicon_list(scr, dicon); + + if (command) + dicon->command = wstrdup(command); +@@ -114,7 +153,87 @@ WAppIcon *wAppIconCreateForDock(WScreen + return dicon; + } + +-WAppIcon *wAppIconCreate(WWindow * leader_win) ++void makeAppIconFor(WApplication * wapp) ++{ ++ /* If app_icon, work is done, return */ ++ if (wapp->app_icon) ++ return; ++ ++ /* Create the icon */ ++ wapp->app_icon = wAppIconCreate(wapp->main_window_desc); ++ ++ /* Now, paint the icon */ ++ if (!WFLAGP(wapp->main_window_desc, no_appicon)) ++ paint_app_icon(wapp); ++} ++ ++void paint_app_icon(WApplication *wapp) ++{ ++ WIcon *icon; ++ WScreen *scr = wapp->main_window_desc->screen_ptr; ++ WDock *clip = scr->workspaces[scr->current_workspace]->clip; ++ int x = 0, y = 0; ++ ++ if (!wapp || !wapp->app_icon) ++ return; ++ ++ icon = wapp->app_icon->icon; ++ wapp->app_icon->main_window = wapp->main_window; ++ ++ /* If the icon is docked, don't continue */ ++ if (wapp->app_icon->docked) ++ return; ++ ++ if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) { ++ wapp->app_icon->attracted = 1; ++ if (!icon->shadowed) { ++ icon->shadowed = 1; ++ icon->force_paint = 1; ++ } ++ wDockAttachIcon(clip, wapp->app_icon, x, y); ++ } else { ++ PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc)); ++ wAppIconMove(wapp->app_icon, x, y); ++ wLowerFrame(icon->core); ++ } ++ ++ if (!clip || !wapp->app_icon->attracted || !clip->collapsed) ++ XMapWindow(dpy, icon->core->window); ++ ++ if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted) ++ wArrangeIcons(scr, True); ++} ++ ++void removeAppIconFor(WApplication * wapp) ++{ ++ if (!wapp->app_icon) ++ return; ++ ++ if (wapp->app_icon->docked && !wapp->app_icon->attracted) { ++ wapp->app_icon->running = 0; ++ /* since we keep it, we don't care if it was attracted or not */ ++ wapp->app_icon->attracted = 0; ++ wapp->app_icon->icon->shadowed = 0; ++ wapp->app_icon->main_window = None; ++ wapp->app_icon->pid = 0; ++ wapp->app_icon->icon->owner = NULL; ++ wapp->app_icon->icon->icon_win = None; ++ wapp->app_icon->icon->force_paint = 1; ++ wAppIconPaint(wapp->app_icon); ++ } else if (wapp->app_icon->docked) { ++ wapp->app_icon->running = 0; ++ wDockDetach(wapp->app_icon->dock, wapp->app_icon); ++ } else { ++ wAppIconDestroy(wapp->app_icon); ++ } ++ ++ wapp->app_icon = NULL; ++ ++ if (wPreferences.auto_arrange_icons) ++ wArrangeIcons(wapp->main_window_desc->screen_ptr, True); ++} ++ ++static WAppIcon *wAppIconCreate(WWindow * leader_win) + { + WAppIcon *aicon; + WScreen *scr = leader_win->screen_ptr; +@@ -125,12 +244,11 @@ WAppIcon *wAppIconCreate(WWindow * leade + aicon->yindex = -1; + aicon->xindex = -1; + +- aicon->prev = NULL; +- aicon->next = scr->app_icon_list; +- if (scr->app_icon_list) +- scr->app_icon_list->prev = aicon; +- +- scr->app_icon_list = aicon; ++ /* When no_appicon is set we want to avoid having it on the list ++ * because otherwise there will be a hole when the icons are ++ * arranged with wArrangeIcons() */ ++ if (!WFLAGP(leader_win, no_appicon)) ++ add_to_appicon_list(scr, aicon); + + if (leader_win->wm_class) + aicon->wm_class = wstrdup(leader_win->wm_class); +@@ -173,16 +291,7 @@ void wAppIconDestroy(WAppIcon * aicon) + if (aicon->wm_class) + wfree(aicon->wm_class); + +- if (aicon == scr->app_icon_list) { +- if (aicon->next) +- aicon->next->prev = NULL; +- scr->app_icon_list = aicon->next; +- } else { +- if (aicon->next) +- aicon->next->prev = aicon->prev; +- if (aicon->prev) +- aicon->prev->next = aicon->next; +- } ++ remove_from_appicon_list(scr, aicon); + + aicon->destroyed = 1; + wrelease(aicon); +@@ -275,20 +384,23 @@ void wAppIconPaint(WAppIcon * aicon) + 0, 0, wPreferences.icon_size, wPreferences.icon_size); + } + +-Bool wAppIconSave(WAppIcon *aicon) ++/* Save the application icon, if it's a dockapp then use it with dock = True */ ++void save_appicon(WAppIcon *aicon, Bool dock) + { + char *path; + +- if (!aicon->docked || aicon->attracted) return True; ++ if (!aicon) ++ return; ++ ++ if (dock && (!aicon->docked || aicon->attracted)) ++ return; + + path = wIconStore(aicon->icon); + if (!path) +- return False; ++ return; + + wApplicationSaveIconPathFor(path, aicon->wm_instance, aicon->wm_class); +- + wfree(path); +- return True; + } + + #define canBeDocked(wwin) ((wwin) && ((wwin)->wm_class||(wwin)->wm_instance)) +@@ -759,3 +871,120 @@ void appIconMouseDown(WObjDescriptor * d + } + } + } ++ ++/* This function save the application icon and store the path in the Dictionary */ ++static void wApplicationSaveIconPathFor(char *iconPath, char *wm_instance, char *wm_class) ++{ ++ WMPropList *dict = WDWindowAttributes->dictionary; ++ WMPropList *adict, *key, *iconk; ++ WMPropList *val; ++ char *tmp; ++ ++ tmp = get_name_for_instance_class(wm_instance, wm_class); ++ key = WMCreatePLString(tmp); ++ wfree(tmp); ++ ++ adict = WMGetFromPLDictionary(dict, key); ++ iconk = WMCreatePLString("Icon"); ++ ++ if (adict) { ++ val = WMGetFromPLDictionary(adict, iconk); ++ } else { ++ /* no dictionary for app, so create one */ ++ adict = WMCreatePLDictionary(NULL, NULL); ++ WMPutInPLDictionary(dict, key, adict); ++ WMReleasePropList(adict); ++ val = NULL; ++ } ++ ++ if (!val) { ++ val = WMCreatePLString(iconPath); ++ WMPutInPLDictionary(adict, iconk, val); ++ WMReleasePropList(val); ++ } else { ++ val = NULL; ++ } ++ ++ WMReleasePropList(key); ++ WMReleasePropList(iconk); ++ ++ if (val && !wPreferences.flags.noupdates) ++ UpdateDomainFile(WDWindowAttributes); ++} ++ ++static WAppIcon *findDockIconFor(WDock *dock, Window main_window) ++{ ++ WAppIcon *aicon = NULL; ++ ++ aicon = wDockFindIconForWindow(dock, main_window); ++ if (!aicon) { ++ wDockTrackWindowLaunch(dock, main_window); ++ aicon = wDockFindIconForWindow(dock, main_window); ++ } ++ return aicon; ++} ++ ++void create_appicon_from_dock(WWindow *wwin, WApplication *wapp, Window main_window) ++{ ++ WScreen *scr = wwin->screen_ptr; ++ wapp->app_icon = NULL; ++ ++ if (scr->last_dock) ++ wapp->app_icon = findDockIconFor(scr->last_dock, main_window); ++ ++ /* check main dock if we did not find it in last dock */ ++ if (!wapp->app_icon && scr->dock) ++ wapp->app_icon = findDockIconFor(scr->dock, main_window); ++ ++ /* finally check clips */ ++ if (!wapp->app_icon) { ++ int i; ++ for (i = 0; i < scr->workspace_count; i++) { ++ WDock *dock = scr->workspaces[i]->clip; ++ if (dock) ++ wapp->app_icon = findDockIconFor(dock, main_window); ++ if (wapp->app_icon) ++ break; ++ } ++ } ++ ++ /* If created, then set some flags */ ++ if (wapp->app_icon) { ++ WWindow *mainw = wapp->main_window_desc; ++ ++ wapp->app_icon->running = 1; ++ wapp->app_icon->icon->force_paint = 1; ++ wapp->app_icon->icon->owner = mainw; ++ if (mainw->wm_hints && (mainw->wm_hints->flags & IconWindowHint)) ++ wapp->app_icon->icon->icon_win = mainw->wm_hints->icon_window; ++ ++ wAppIconPaint(wapp->app_icon); ++ save_appicon(wapp->app_icon, True); ++ } ++} ++ ++/* Add the appicon to the appiconlist */ ++static void add_to_appicon_list(WScreen *scr, WAppIcon *appicon) ++{ ++ appicon->prev = NULL; ++ appicon->next = scr->app_icon_list; ++ if (scr->app_icon_list) ++ scr->app_icon_list->prev = appicon; ++ ++ scr->app_icon_list = appicon; ++} ++ ++/* Remove the appicon from the appiconlist */ ++static void remove_from_appicon_list(WScreen *scr, WAppIcon *appicon) ++{ ++ if (appicon == scr->app_icon_list) { ++ if (appicon->next) ++ appicon->next->prev = NULL; ++ scr->app_icon_list = appicon->next; ++ } else { ++ if (appicon->next) ++ appicon->next->prev = appicon->prev; ++ if (appicon->prev) ++ appicon->prev->next = appicon->next; ++ } ++} +Index: src/appicon.h +=================================================================== +--- src/appicon.h.orig ++++ src/appicon.h +@@ -69,13 +69,15 @@ typedef struct WAppIcon { + unsigned int lock:1; /* do not allow to be destroyed */ + } WAppIcon; + +-WAppIcon *wAppIconCreate(WWindow *leader_win); +-WAppIcon * wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, +- char *wm_class, int tile); ++WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, ++ char *wm_class, int tile); + ++void create_appicon_from_dock(WWindow *wwin, WApplication *wapp, Window main_window); + void wAppIconDestroy(WAppIcon *aicon); + void wAppIconPaint(WAppIcon *aicon); + void wAppIconMove(WAppIcon *aicon, int x, int y); +-Bool wAppIconChangeImage(WAppIcon *icon, char *file); +-Bool wAppIconSave(WAppIcon *aicon); ++void makeAppIconFor(WApplication * wapp); ++void removeAppIconFor(WApplication * wapp); ++void save_appicon(WAppIcon *aicon, Bool dock); ++void paint_app_icon(WApplication *wapp); + #endif +Index: src/application.c +=================================================================== +--- src/application.c.orig ++++ src/application.c +@@ -21,42 +21,25 @@ + #include "wconfig.h" + + #include +- +-#include + #include + +-#include +-#include +-#include +-#include +- + #include "WindowMaker.h" + #include "menu.h" + #include "window.h" + #ifdef USER_MENU + #include "usermenu.h" + #endif /* USER_MENU */ +-#include "icon.h" + #include "appicon.h" + #include "application.h" + #include "appmenu.h" + #include "properties.h" +-#include "funcs.h" +-#include "stacking.h" +-#include "actions.h" +-#include "defaults.h" + #include "workspace.h" + #include "dock.h" + +-#include "xinerama.h" +- + /******** Global variables ********/ + + extern XContext wAppWinContext; + extern XContext wWinContext; +-extern WPreferences wPreferences; +- +-extern WDDomain *WDWindowAttributes; + + /******** Local variables ********/ + +@@ -65,19 +48,15 @@ static WWindow *makeMainWindow(WScreen * + WWindow *wwin; + XWindowAttributes attr; + +- if (!XGetWindowAttributes(dpy, window, &attr)) { ++ if (!XGetWindowAttributes(dpy, window, &attr)) + return NULL; +- } + + wwin = wWindowCreate(); + wwin->screen_ptr = scr; + wwin->client_win = window; + wwin->main_window = window; + wwin->wm_hints = XGetWMHints(dpy, window); +- /* if (!MyXFetchName(dpy, window, &(wwin->frame->title))) { +- wwin->frame->title = NULL; +- } +- */ ++ + PropGetWMClass(window, &wwin->wm_class, &wwin->wm_instance); + + wDefaultFillAttributes(scr, wwin->wm_instance, wwin->wm_class, +@@ -98,122 +77,6 @@ WApplication *wApplicationOf(Window wind + return wapp; + } + +-static WAppIcon *findDockIconFor(WDock * dock, Window main_window) +-{ +- WAppIcon *aicon = NULL; +- +- aicon = wDockFindIconForWindow(dock, main_window); +- if (!aicon) { +- wDockTrackWindowLaunch(dock, main_window); +- aicon = wDockFindIconForWindow(dock, main_window); +- } +- return aicon; +-} +- +-static void extractIcon(WWindow * wwin) +-{ +- char *progname; +- +- /* Get the application name */ +- progname = GetProgramNameForWindow(wwin->client_win); +- if (progname) { +- /* Save the icon path if the application is ".app" */ +- wApplicationExtractDirPackIcon(wwin->screen_ptr, progname, wwin->wm_instance, wwin->wm_class); +- wfree(progname); +- } +-} +- +-void wApplicationSaveIconPathFor(char *iconPath, char *wm_instance, char *wm_class) +-{ +- WMPropList *dict = WDWindowAttributes->dictionary; +- WMPropList *adict, *key, *iconk; +- WMPropList *val; +- char *tmp; +- int i; +- +- i = 0; +- if (wm_instance) +- i += strlen(wm_instance); +- if (wm_class) +- i += strlen(wm_class); +- +- tmp = wmalloc(i + 8); +- *tmp = 0; +- if (wm_class && wm_instance) { +- sprintf(tmp, "%s.%s", wm_instance, wm_class); +- } else { +- if (wm_instance) +- strcat(tmp, wm_instance); +- if (wm_class) +- strcat(tmp, wm_class); +- } +- +- key = WMCreatePLString(tmp); +- wfree(tmp); +- +- adict = WMGetFromPLDictionary(dict, key); +- iconk = WMCreatePLString("Icon"); +- +- if (adict) { +- val = WMGetFromPLDictionary(adict, iconk); +- } else { +- /* no dictionary for app, so create one */ +- adict = WMCreatePLDictionary(NULL, NULL); +- WMPutInPLDictionary(dict, key, adict); +- WMReleasePropList(adict); +- val = NULL; +- } +- +- if (!val) { +- val = WMCreatePLString(iconPath); +- WMPutInPLDictionary(adict, iconk, val); +- WMReleasePropList(val); +- } else { +- val = NULL; +- } +- +- WMReleasePropList(key); +- WMReleasePropList(iconk); +- +- if (val && !wPreferences.flags.noupdates) +- UpdateDomainFile(WDWindowAttributes); +-} +- +-/* This function is used if the application is a .app. It checks if it has an icon in it +- * like for example /usr/local/GNUstep/Applications/WPrefs.app/WPrefs.tiff +- */ +-void wApplicationExtractDirPackIcon(WScreen * scr, char *path, char *wm_instance, char *wm_class) +-{ +- char *iconPath = NULL; +- char *tmp = NULL; +- +- if (strstr(path, ".app")) { +- tmp = wmalloc(strlen(path) + 16); +- +- if (scr->flags.supports_tiff) { +- strcpy(tmp, path); +- strcat(tmp, ".tiff"); +- if (access(tmp, R_OK) == 0) +- iconPath = tmp; +- } +- +- if (!iconPath) { +- strcpy(tmp, path); +- strcat(tmp, ".xpm"); +- if (access(tmp, R_OK) == 0) +- iconPath = tmp; +- } +- +- if (!iconPath) +- wfree(tmp); +- +- if (iconPath) { +- wApplicationSaveIconPathFor(iconPath, wm_instance, wm_class); +- wfree(iconPath); +- } +- } +-} +- + WApplication *wApplicationCreate(WWindow * wwin) + { + WScreen *scr = wwin->screen_ptr; +@@ -229,18 +92,16 @@ WApplication *wApplicationCreate(WWindow + int foo; + unsigned int bar; + /* check if the window is valid */ +- if (!XGetGeometry(dpy, main_window, &root, &foo, &foo, &bar, &bar, &bar, &bar)) { ++ if (!XGetGeometry(dpy, main_window, &root, &foo, &foo, &bar, &bar, &bar, &bar)) + return NULL; +- } + } + + wapp = wApplicationOf(main_window); + if (wapp) { + wapp->refcount++; + if (wapp->app_icon && wapp->app_icon->docked && +- wapp->app_icon->relaunching && wapp->main_window_desc->fake_group) { ++ wapp->app_icon->relaunching && wapp->main_window_desc->fake_group) + wDockFinishLaunch(wapp->app_icon->dock, wapp->app_icon); +- } + + return wapp; + } +@@ -263,8 +124,6 @@ WApplication *wApplicationCreate(WWindow + wapp->main_window_desc->fake_group = wwin->fake_group; + wapp->main_window_desc->net_icon_image = RRetainImage(wwin->net_icon_image); + +- extractIcon(wapp->main_window_desc); +- + leader = wWindowFor(main_window); + if (leader) + leader->main_window = main_window; +@@ -273,107 +132,27 @@ WApplication *wApplicationCreate(WWindow + #ifdef USER_MENU + if (!wapp->menu) + wapp->menu = wUserMenuGet(scr, wapp->main_window_desc); +-#endif /* USER_MENU */ ++#endif + +- /* +- * Set application wide attributes from the leader. +- */ ++ /* Set application wide attributes from the leader */ + wapp->flags.hidden = WFLAGP(wapp->main_window_desc, start_hidden); + wapp->flags.emulated = WFLAGP(wapp->main_window_desc, emulate_appicon); + + /* application descriptor */ + XSaveContext(dpy, main_window, wAppWinContext, (XPointer) wapp); + +- if (!WFLAGP(wapp->main_window_desc, no_appicon)) { +- wapp->app_icon = NULL; +- if (scr->last_dock) +- wapp->app_icon = findDockIconFor(scr->last_dock, main_window); +- +- /* check main dock if we did not find it in last dock */ +- if (!wapp->app_icon && scr->dock) +- wapp->app_icon = findDockIconFor(scr->dock, main_window); +- +- /* finally check clips */ +- if (!wapp->app_icon) { +- int i; +- for (i = 0; i < scr->workspace_count; i++) { +- WDock *dock = scr->workspaces[i]->clip; +- if (dock) +- wapp->app_icon = findDockIconFor(dock, main_window); +- if (wapp->app_icon) +- break; +- } +- } +- +- if (wapp->app_icon) { +- WWindow *mainw = wapp->main_window_desc; +- +- wapp->app_icon->running = 1; +- wapp->app_icon->icon->force_paint = 1; +- wapp->app_icon->icon->owner = mainw; +- if (mainw->wm_hints && (mainw->wm_hints->flags & IconWindowHint)) +- wapp->app_icon->icon->icon_win = mainw->wm_hints->icon_window; +- wAppIconPaint(wapp->app_icon); +- wAppIconSave(wapp->app_icon); +- } else { +- wapp->app_icon = wAppIconCreate(wapp->main_window_desc); +- } +- } else { +- wapp->app_icon = NULL; +- } ++ /* First try to create an icon from the dock or clip */ ++ create_appicon_from_dock(wwin, wapp, main_window); + +- if (wapp->app_icon) +- wapp->app_icon->main_window = main_window; +- +- if (wapp->app_icon && !wapp->app_icon->docked) { +- WIcon *icon = wapp->app_icon->icon; +- WDock *clip = scr->workspaces[scr->current_workspace]->clip; +- int x = 0, y = 0; +- +- if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) { +- wapp->app_icon->attracted = 1; +- if (!icon->shadowed) { +- icon->shadowed = 1; +- icon->force_paint = 1; +- /* wAppIconPaint() is done in wDockAttachIcon() below */ +- } +- wDockAttachIcon(clip, wapp->app_icon, x, y); +- } else { +- PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc)); +- wAppIconMove(wapp->app_icon, x, y); +- wLowerFrame(icon->core); +- } +- +- if (!clip || !wapp->app_icon->attracted || !clip->collapsed) +- XMapWindow(dpy, icon->core->window); +- } +- +- if (wPreferences.auto_arrange_icons && wapp->app_icon && !wapp->app_icon->attracted) +- wArrangeIcons(scr, True); +- +- if (wapp->app_icon) { +- char *tmp, *path; +- struct stat dummy; ++ /* ++ * In case it was not found in the dock, make it from scratch. ++ * Note: makeAppIconFor() returns early if wapp->app_icon exists ++ */ ++ makeAppIconFor(wapp); + +- tmp = wDefaultGetIconFile(scr, wapp->app_icon->wm_instance, wapp->app_icon->wm_class, True); ++ /* Save the app_icon in a file */ ++ save_appicon(wapp->app_icon, False); + +- /* If the icon was saved by us from the client supplied icon, but is +- * missing, recreate it. */ +- if (tmp && strstr(tmp, "Library/WindowMaker/CachedPixmaps") != NULL && +- stat(tmp, &dummy) != 0 && errno == ENOENT) { +- wmessage(_("recreating missing icon '%s'"), tmp); +- path = wIconStore(wapp->app_icon->icon); +- if (path) { +- wfree(path); +- } +- wIconUpdate(wapp->app_icon->icon); +- wAppIconPaint(wapp->app_icon); +- } +- +- /* if the displayed icon was supplied by the client, save the icon */ +- if (!tmp || strstr(tmp, "Library/WindowMaker/CachedPixmaps") != NULL) +- wAppIconSave(wapp->app_icon); +- } + return wapp; + } + +@@ -417,25 +196,9 @@ void wApplicationDestroy(WApplication * + wAppMenuDestroy(wapp->menu); + wApplicationDeactivate(wapp); + +- if (wapp->app_icon) { +- if (wapp->app_icon->docked && !wapp->app_icon->attracted) { +- wapp->app_icon->running = 0; +- /* since we keep it, we don't care if it was attracted or not */ +- wapp->app_icon->attracted = 0; +- wapp->app_icon->icon->shadowed = 0; +- wapp->app_icon->main_window = None; +- wapp->app_icon->pid = 0; +- wapp->app_icon->icon->owner = NULL; +- wapp->app_icon->icon->icon_win = None; +- wapp->app_icon->icon->force_paint = 1; +- wAppIconPaint(wapp->app_icon); +- } else if (wapp->app_icon->docked) { +- wapp->app_icon->running = 0; +- wDockDetach(wapp->app_icon->dock, wapp->app_icon); +- } else { +- wAppIconDestroy(wapp->app_icon); +- } +- } ++ /* Remove application icon */ ++ removeAppIconFor(wapp); ++ + wwin = wWindowFor(wapp->main_window_desc->client_win); + + wWindowDestroy(wapp->main_window_desc); +@@ -445,9 +208,6 @@ void wApplicationDestroy(WApplication * + XSaveContext(dpy, wwin->client_win, wWinContext, (XPointer) & wwin->client_descriptor); + } + wfree(wapp); +- +- if (wPreferences.auto_arrange_icons) +- wArrangeIcons(scr, True); + } + + void wApplicationActivate(WApplication *wapp) +@@ -469,4 +229,3 @@ void wApplicationDeactivate(WApplication + } + #endif + } +- +Index: src/application.h +=================================================================== +--- src/application.h.orig ++++ src/application.h +@@ -48,10 +48,6 @@ typedef struct WApplication { + WApplication *wApplicationCreate(struct WWindow *wwin); + WApplication *wApplicationOf(Window window); + void wApplicationDestroy(WApplication *wapp); +-void wApplicationExtractDirPackIcon(WScreen *scr,char *path, char *wm_instance, +- char *wm_class); +-void wApplicationSaveIconPathFor(char *iconPath, char *wm_instance, +- char *wm_class); + + void wAppBounce(WApplication *); + void wAppBounceWhileUrgent(WApplication *); +Index: src/client.c +=================================================================== +--- src/client.c.orig ++++ src/client.c +@@ -37,7 +37,7 @@ + #include "actions.h" + #include "icon.h" + #include "client.h" +-#include "funcs.h" ++#include "colormap.h" + #include "stacking.h" + #include "appicon.h" + #include "appmenu.h" +Index: src/colormap.c +=================================================================== +--- src/colormap.c.orig ++++ src/colormap.c +@@ -92,26 +92,6 @@ void wColormapInstallForWindow(WScreen * + XSync(dpy, False); + } + +-void wColormapInstallRoot(WScreen * scr) +-{ +- if (scr->root_colormap_install_count == 0) { +- wColormapInstallForWindow(scr, NULL); +- scr->original_cmap_window = scr->cmap_window; +- } +- scr->root_colormap_install_count++; +-} +- +-void wColormapUninstallRoot(WScreen * scr) +-{ +- if (scr->root_colormap_install_count > 0) +- scr->root_colormap_install_count--; +- +- if (scr->root_colormap_install_count == 0) { +- wColormapInstallForWindow(scr, scr->original_cmap_window); +- scr->original_cmap_window = NULL; +- } +-} +- + void wColormapAllowClientInstallation(WScreen * scr, Bool starting) + { + scr->flags.colormap_stuff_blocked = starting; +Index: src/colormap.h +=================================================================== +--- /dev/null ++++ src/colormap.h +@@ -0,0 +1,27 @@ ++/* ++ * Window Maker window manager ++ * ++ * Copyright (c) 2000-2003 Alfredo K. Kojima ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef WMCOLORMAP_H ++#define WMCOLORMAP_H ++ ++void wColormapInstallForWindow(WScreen *scr, WWindow *wwin); ++void wColormapAllowClientInstallation(WScreen * scr, Bool starting); ++ ++#endif /* WMCOLORMAP_H */ +Index: src/defaults.c +=================================================================== +--- src/defaults.c.orig ++++ src/defaults.c +@@ -56,7 +56,7 @@ + #include "keybind.h" + #include "xmodifier.h" + #include "icon.h" +-#include "funcs.h" ++#include "main.h" + #include "actions.h" + #include "dock.h" + #include "workspace.h" +@@ -204,6 +204,7 @@ static WOptionEnumeration sePlacements[] + {"Cascade", WPM_CASCADE, 0}, + {"Random", WPM_RANDOM, 0}, + {"Manual", WPM_MANUAL, 0}, ++ {"Center", WPM_CENTER, 0}, + {NULL, 0, 0} + }; + +@@ -803,7 +804,6 @@ WDDomain *wDefaultsInitDomain(char *doma + WDDomain *db; + struct stat stbuf; + static int inited = 0; +- char path[PATH_MAX]; + char *the_path; + WMPropList *shared_dict = NULL; + +@@ -832,32 +832,19 @@ WDDomain *wDefaultsInitDomain(char *doma + } + + /* global system dictionary */ +- snprintf(path, sizeof(path), "%s/%s/%s", SYSCONFDIR, GLOBAL_DEFAULTS_SUBDIR, domain); +- if (stat(path, &stbuf) >= 0) { +- shared_dict = WMReadPropListFromFile(path); +- if (shared_dict) { +- if (requireDictionary && !WMIsPLDictionary(shared_dict)) { +- wwarning(_("Domain %s (%s) of global defaults database is corrupted!"), +- domain, path); +- WMReleasePropList(shared_dict); +- shared_dict = NULL; +- } else { +- if (db->dictionary && WMIsPLDictionary(shared_dict) && +- WMIsPLDictionary(db->dictionary)) { +- WMMergePLDictionaries(shared_dict, db->dictionary, True); +- WMReleasePropList(db->dictionary); +- db->dictionary = shared_dict; +- if (stbuf.st_mtime > db->timestamp) +- db->timestamp = stbuf.st_mtime; +- } else if (!db->dictionary) { +- db->dictionary = shared_dict; +- if (stbuf.st_mtime > db->timestamp) +- db->timestamp = stbuf.st_mtime; +- } +- } +- } else { +- wwarning(_("could not load domain %s from global defaults database (%s)"), domain, path); +- } ++ shared_dict = readGlobalDomain(domain, requireDictionary); ++ ++ if (shared_dict && db->dictionary && WMIsPLDictionary(shared_dict) && ++ WMIsPLDictionary(db->dictionary)) { ++ WMMergePLDictionaries(shared_dict, db->dictionary, True); ++ WMReleasePropList(db->dictionary); ++ db->dictionary = shared_dict; ++ if (stbuf.st_mtime > db->timestamp) ++ db->timestamp = stbuf.st_mtime; ++ } else if (!db->dictionary) { ++ db->dictionary = shared_dict; ++ if (stbuf.st_mtime > db->timestamp) ++ db->timestamp = stbuf.st_mtime; + } + + return db; +@@ -969,22 +956,12 @@ void wDefaultsCheckDomains(void* arg) + for (i = 0; i < wScreenCount; i++) { + scr = wScreenWithNumber(i); + if (scr) { +- RImage *image; +- + wDefaultUpdateIcons(scr); + + /* Update the panel image if changed */ + /* Don't worry. If the image is the same these + * functions will have no performance impact. */ +- image = wDefaultGetImage(scr, "Logo", "WMPanel", wPreferences.icon_size); +- +- if (!image) { +- wwarning(_("could not load logo image for panels: %s"), +- RMessageForError(RErrorCode)); +- } else { +- WMSetApplicationIconImage(scr->wmscreen, image); +- RReleaseImage(image); +- } ++ create_logo_image(scr); + } + } + } +Index: src/dock.c +=================================================================== +--- src/dock.c.orig ++++ src/dock.c +@@ -43,8 +43,9 @@ + #include "actions.h" + #include "stacking.h" + #include "dock.h" ++#include "dockedapp.h" + #include "dialog.h" +-#include "funcs.h" ++#include "main.h" + #include "properties.h" + #include "menu.h" + #include "client.h" +@@ -60,10 +61,6 @@ + #define CLIP_FORWARD 2 + + /**** Global variables ****/ +- +-/* in dockedapp.c */ +-extern void DestroyDockAppSettingsPanel(); +-extern void ShowDockAppSettingsPanel(WAppIcon * aicon); + extern Cursor wCursor[WCUR_LAST]; + extern WPreferences wPreferences; + extern XContext wWinContext; +@@ -548,7 +545,7 @@ static void keepIconsCallback(WMenu *men + wAppIconPaint(aicon); + } + } +- wAppIconSave(aicon); ++ save_appicon(aicon, True); + } + WMFreeArray(selectedIcons); + } +@@ -595,18 +592,9 @@ static void colectIconsCallback(WMenu *m + if (!aicon->docked && wDockFindFreeSlot(clip, &x, &y)) { + x_pos = clip->x_pos + x * ICON_SIZE; + y_pos = clip->y_pos + y * ICON_SIZE; +- if (aicon->x_pos != x_pos || aicon->y_pos != y_pos) { +-#ifdef ANIMATIONS +- if (wPreferences.no_animations) { +- XMoveWindow(dpy, aicon->icon->core->window, x_pos, y_pos); +- } else { +- SlideWindow(aicon->icon->core->window, +- aicon->x_pos, aicon->y_pos, x_pos, y_pos); +- } +-#else +- XMoveWindow(dpy, aicon->icon->core->window, x_pos, y_pos); +-#endif /* ANIMATIONS */ +- } ++ if (aicon->x_pos != x_pos || aicon->y_pos != y_pos) ++ move_window(aicon->icon->core->window, aicon->x_pos, aicon->y_pos, x_pos, y_pos); ++ + aicon->attracted = 1; + if (!aicon->icon->shadowed) { + aicon->icon->shadowed = 1; +@@ -1173,7 +1161,7 @@ static void dockIconPaint(WAppIcon *btn) + wClipIconPaint(btn); + else { + wAppIconPaint(btn); +- wAppIconSave(btn); ++ save_appicon(btn, True); + } + } + +@@ -1961,7 +1949,7 @@ Bool wDockAttachIcon(WDock *dock, WAppIc + MoveInStackListUnder(dock->icon_array[index - 1]->icon->core, icon->icon->core); + wAppIconMove(icon, icon->x_pos, icon->y_pos); + wAppIconPaint(icon); +- wAppIconSave(icon); ++ save_appicon(icon, True); + + if (wPreferences.auto_arrange_icons) + wArrangeIcons(dock->screen_ptr, True); +@@ -2089,7 +2077,7 @@ static Bool moveIconBetweenDocks(WDock * + icon->icon->shadowed = 0; + icon->icon->force_paint = 1; + } +- wAppIconSave(icon); ++ save_appicon(icon, True); + } + + if (src->auto_collapse || src->auto_raise_lower) +Index: src/dockedapp.c +=================================================================== +--- src/dockedapp.c.orig ++++ src/dockedapp.c +@@ -31,6 +31,7 @@ + #include "icon.h" + #include "appicon.h" + #include "dock.h" ++#include "dockedapp.h" + #include "dialog.h" + #include "funcs.h" + #include "defaults.h" +@@ -40,45 +41,6 @@ + /**** Global variables ****/ + extern WPreferences wPreferences; + +-typedef struct _AppSettingsPanel { +- WMWindow *win; +- WAppIcon *editedIcon; +- +- WWindow *wwin; +- +- WMLabel *iconLabel; +- WMLabel *nameLabel; +- +- WMFrame *commandFrame; +- WMTextField *commandField; +- +- WMFrame *dndCommandFrame; +- WMTextField *dndCommandField; +- WMLabel *dndCommandLabel; +- +- WMFrame *pasteCommandFrame; +- WMTextField *pasteCommandField; +- WMLabel *pasteCommandLabel; +- +- WMFrame *iconFrame; +- WMTextField *iconField; +- WMButton *browseBtn; +- +- WMButton *autoLaunchBtn; +- WMButton *lockBtn; +- +- WMButton *okBtn; +- WMButton *cancelBtn; +- +- Window parent; +- +- /* kluge */ +- unsigned int destroyed:1; +- unsigned int choosingIcon:1; +-} AppSettingsPanel; +- +-void DestroyDockAppSettingsPanel(AppSettingsPanel * panel); +- + static void updateCommand(WAppIcon * icon, char *command) + { + if (icon->command) +Index: src/dockedapp.h +=================================================================== +--- /dev/null ++++ src/dockedapp.h +@@ -0,0 +1,66 @@ ++/* ++ * Window Maker window manager ++ * ++ * Copyright (c) 1997-2003 Alfredo K. Kojima ++ * Copyright (c) 1998-2003 Dan Pascu ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef WMDOCKEDAPP_H_ ++#define WMDOCKEDAPP_H_ ++ ++ ++typedef struct _AppSettingsPanel { ++ WMWindow *win; ++ WAppIcon *editedIcon; ++ ++ WWindow *wwin; ++ ++ WMLabel *iconLabel; ++ WMLabel *nameLabel; ++ ++ WMFrame *commandFrame; ++ WMTextField *commandField; ++ ++ WMFrame *dndCommandFrame; ++ WMTextField *dndCommandField; ++ WMLabel *dndCommandLabel; ++ ++ WMFrame *pasteCommandFrame; ++ WMTextField *pasteCommandField; ++ WMLabel *pasteCommandLabel; ++ ++ WMFrame *iconFrame; ++ WMTextField *iconField; ++ WMButton *browseBtn; ++ ++ WMButton *autoLaunchBtn; ++ WMButton *lockBtn; ++ ++ WMButton *okBtn; ++ WMButton *cancelBtn; ++ ++ Window parent; ++ ++ /* kluge */ ++ unsigned int destroyed:1; ++ unsigned int choosingIcon:1; ++} AppSettingsPanel; ++ ++void DestroyDockAppSettingsPanel(AppSettingsPanel *panel); ++void ShowDockAppSettingsPanel(WAppIcon *aicon); ++ ++#endif +Index: src/event.c +=================================================================== +--- src/event.c.orig ++++ src/event.c +@@ -54,7 +54,7 @@ + #include "window.h" + #include "actions.h" + #include "client.h" +-#include "funcs.h" ++#include "main.h" + #include "keybind.h" + #include "application.h" + #include "stacking.h" +@@ -66,6 +66,8 @@ + #include "balloon.h" + #include "xinerama.h" + #include "wmspec.h" ++#include "rootmenu.h" ++#include "colormap.h" + + /******** Global Variables **********/ + extern XContext wWinContext; +Index: src/funcs.h +=================================================================== +--- src/funcs.h.orig ++++ src/funcs.h +@@ -32,13 +32,8 @@ typedef void (WDeathHandler)(pid_t pid, + + void Shutdown(WShutdownMode mode); + void RestoreDesktop(WScreen *scr); +-void Exit(int status) __attribute__((noreturn)); +-void Restart(char *manager, Bool abortOnFailure); +-void SetupEnvironment(WScreen *scr); + void DispatchEvent(XEvent *event); + void UpdateSwitchMenu(WScreen *scr, WWindow *wwin, int action); +-void wRootMenuBindShortcuts(Window window); +-void OpenRootMenu(WScreen *scr, int x, int y, int keyboard); + void OpenSwitchMenu(WScreen *scr, int x, int y, int keyboard); + void InitializeSwitchMenu(void); + void OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard); +@@ -46,16 +41,10 @@ void OpenWindowMenu2(WWindow *wwin, int + void OpenMiniwindowMenu(WWindow *wwin, int x, int y); + void CloseWindowMenu(WScreen *scr); + void DestroyWindowMenu(WScreen *scr); +-void wColormapInstallForWindow(WScreen *scr, WWindow *wwin); +-void wColormapInstallRoot(WScreen *scr); +-void wColormapUninstallRoot(WScreen *scr); +-void wColormapAllowClientInstallation(WScreen *scr, Bool starting); + void PlaceIcon(WScreen *scr, int *x_ret, int *y_ret, int head); + void StartWindozeCycle(WWindow *wwin, XEvent *event, Bool next, Bool class_only); + void SendHelperMessage(WScreen *scr, char type, int workspace, char *msg); + void UnescapeWM_CLASS(char *str, char **name, char **class); +-void ExecuteShellCommand(WScreen *scr, char *command); +-void ExecExitScript(); + void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, + unsigned int width, unsigned int height); + +@@ -86,14 +75,13 @@ char * FindImage(char *paths, char *file + char * GetShortcutString(char *text); + char * EscapeWM_CLASS(char *name, char *class); + +-Bool wRootMenuPerformShortcut(XEvent *event); +-Bool RelaunchWindow(WWindow *wwin); + Bool IsDoubleClick(WScreen *scr, XEvent *event); + Bool UpdateDomainFile(WDDomain *domain); + + WWindow * NextToFocusAfter(WWindow *wwin); + WWindow * NextToFocusBefore(WWindow *wwin); + ++void move_window(Window win, int from_x, int from_y, int to_x, int to_y); + void SlideWindow(Window win, int from_x, int from_y, int to_x, int to_y); + + RImage * wGetImageForWindowName(WScreen *scr, char *winstance, char *wclass); +@@ -111,7 +99,6 @@ Bool wGetIconName(Display *dpy, Window w + + /* Free returned string it when done. (applies to the next 2 functions) */ + char * GetCommandForWindow(Window win); +-char * GetProgramNameForWindow(Window win); + + Bool GetCommandForPid(int pid, char ***argv, int *argc); + +Index: src/icon.c +=================================================================== +--- src/icon.c.orig ++++ src/icon.c +@@ -49,6 +49,7 @@ + extern WPreferences wPreferences; + + #define MOD_MASK wPreferences.modifier_mask ++#define CACHE_ICON_PATH "/Library/WindowMaker/CachedPixmaps" + + extern Cursor wCursor[WCUR_LAST]; + +@@ -68,16 +69,8 @@ static void appearanceObserver(void *sel + WIcon *icon = (WIcon *) self; + uintptr_t flags = (uintptr_t)WMGetNotificationClientData(notif); + +- if (flags & WTextureSettings) { ++ if ((flags & WTextureSettings) || (flags & WFontSettings)) + icon->force_paint = 1; +- } +- if (flags & WFontSettings) { +- icon->force_paint = 1; +- } +- /* +- if (flags & WColorSettings) { +- } +- */ + + wIconPaint(icon); + +@@ -163,9 +156,8 @@ WIcon *wIconCreateWithIconFile(WScreen * + + if (iconfile) { + icon->file_image = RLoadImage(scr->rcontext, iconfile, 0); +- if (!icon->file_image) { ++ if (!icon->file_image) + wwarning(_("error loading image file \"%s\": %s"), iconfile, RMessageForError(RErrorCode)); +- } + + icon->file_image = wIconValidateIconSize(scr, icon->file_image, wPreferences.icon_size); + +@@ -397,62 +389,78 @@ Bool wIconChangeImageFile(WIcon * icon, + return !error; + } + +-static char *getnameforicon(WWindow * wwin) ++static char *get_name_for_wwin(WWindow *wwin) + { +- char *prefix, *suffix; +- char *path; ++ return get_name_for_instance_class(wwin->wm_instance, wwin->wm_class); ++} ++ ++char *get_name_for_instance_class(char *wm_instance, char *wm_class) ++{ ++ char *suffix; + int len; + +- if (wwin->wm_class && wwin->wm_instance) { +- int len = strlen(wwin->wm_class) + strlen(wwin->wm_instance) + 2; ++ if (wm_class && wm_instance) { ++ len = strlen(wm_class) + strlen(wm_instance) + 2; + suffix = wmalloc(len); +- snprintf(suffix, len, "%s.%s", wwin->wm_instance, wwin->wm_class); +- } else if (wwin->wm_class) { +- int len = strlen(wwin->wm_class) + 1; ++ snprintf(suffix, len, "%s.%s", wm_instance, wm_class); ++ } else if (wm_class) { ++ len = strlen(wm_class) + 1; + suffix = wmalloc(len); +- snprintf(suffix, len, "%s", wwin->wm_class); +- } else if (wwin->wm_instance) { +- int len = strlen(wwin->wm_instance) + 1; ++ snprintf(suffix, len, "%s", wm_class); ++ } else if (wm_instance) { ++ len = strlen(wm_instance) + 1; + suffix = wmalloc(len); +- snprintf(suffix, len, "%s", wwin->wm_instance); ++ snprintf(suffix, len, "%s", wm_instance); + } else { + return NULL; + } + ++ return suffix; ++} ++ ++static char *get_icon_cache_path(void) ++{ ++ char *prefix, *path; ++ int len, ret; ++ + prefix = wusergnusteppath(); +- len = strlen(prefix) + 64 + strlen(suffix); +- path = wmalloc(len + 1); +- snprintf(path, len, "%s/Library/WindowMaker", prefix); +- +- if (access(path, F_OK) != 0) { +- if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR)) { +- werror(_("could not create directory %s"), path); +- wfree(path); +- wfree(suffix); +- return NULL; +- } +- } +- strcat(path, "/CachedPixmaps"); +- if (access(path, F_OK) != 0) { +- if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) != 0) { +- werror(_("could not create directory %s"), path); +- wfree(path); +- wfree(suffix); +- return NULL; +- } +- } ++ len = strlen(prefix) + strlen(CACHE_ICON_PATH) + 2; ++ path = wmalloc(len); ++ snprintf(path, len, "%s%s/", prefix, CACHE_ICON_PATH); + +- strcat(path, "/"); +- strcat(path, suffix); +- strcat(path, ".xpm"); +- wfree(suffix); ++ /* If the folder exists, exit */ ++ if (access(path, F_OK) == 0) ++ return path; + +- return path; ++ /* Create the folder */ ++ ret = wmkdirhier((const char *) path); ++ ++ /* Exit 1 on success, 0 on failure */ ++ if (ret == 1) ++ return path; ++ ++ /* Fail */ ++ wfree(path); ++ return NULL; ++} ++ ++static RImage *get_wwindow_image_from_wmhints(WWindow *wwin, WIcon *icon) ++{ ++ RImage *image = NULL; ++ XWMHints *hints = wwin->wm_hints; ++ ++ if (hints && (hints->flags & IconPixmapHint) && hints->icon_pixmap != None) ++ image = RCreateImageFromDrawable(icon->core->screen_ptr->rcontext, ++ hints->icon_pixmap, ++ (hints->flags & IconMaskHint) ++ ? hints->icon_mask : None); ++ ++ return image; + } + + /* + * wIconStore-- +- * Stores the client supplied icon at ~/GNUstep/Library/WindowMaker/CachedPixmaps ++ * Stores the client supplied icon at CACHE_ICON_PATH + * and returns the path for that icon. Returns NULL if there is no + * client supplied icon or on failure. + * +@@ -461,29 +469,38 @@ static char *getnameforicon(WWindow * ww + */ + char *wIconStore(WIcon * icon) + { +- char *path; ++ char *path, *dir_path, *file; ++ int len = 0; + RImage *image = NULL; + WWindow *wwin = icon->owner; + + if (!wwin) + return NULL; + +- path = getnameforicon(wwin); +- if (!path) ++ dir_path = get_icon_cache_path(); ++ if (!dir_path) + return NULL; + ++ file = get_name_for_wwin(wwin); ++ if (!file) { ++ wfree(dir_path); ++ return NULL; ++ } ++ ++ len = strlen(dir_path) + strlen(file) + 5; ++ path = wmalloc(len); ++ snprintf(path, len, "%s%s.xpm", dir_path, file); ++ wfree(dir_path); ++ wfree(file); ++ + /* If icon exists, exit */ + if (access(path, F_OK) == 0) +- return path; ++ return path; + +- if (wwin->net_icon_image) { ++ if (wwin->net_icon_image) + image = RRetainImage(wwin->net_icon_image); +- } else if (wwin->wm_hints && (wwin->wm_hints->flags & IconPixmapHint) +- && wwin->wm_hints->icon_pixmap != None) { +- image = RCreateImageFromDrawable(icon->core->screen_ptr->rcontext, +- wwin->wm_hints->icon_pixmap, (wwin->wm_hints->flags & IconMaskHint) +- ? wwin->wm_hints->icon_mask : None); +- } ++ else ++ image = get_wwindow_image_from_wmhints(wwin, icon); + + if (!image) { + wfree(path); +@@ -612,7 +629,6 @@ void get_pixmap_icon_from_user_icon(WScr + } else { + wwarning(_("could not find default icon \"%s\""), file); + } +- /* FIXME: Probably wfree(file) here! */ + } + + image = wIconValidateIconSize(scr, image, wPreferences.icon_size); +@@ -699,7 +715,7 @@ int get_pixmap_icon_from_wm_hints(WScree + + if (!XGetGeometry(dpy, wwin->wm_hints->icon_pixmap, &jw, &ji, &ji, &w, &h, &ju, &d)) { + icon->owner->wm_hints->flags &= ~IconPixmapHint; +- return(1); ++ return 1; + } + + pixmap = XCreatePixmap(dpy, icon->core->window, wPreferences.icon_size, +Index: src/icon.h +=================================================================== +--- src/icon.h.orig ++++ src/icon.h +@@ -67,7 +67,8 @@ Bool wIconChangeImageFile(WIcon *icon, c + + RImage * wIconValidateIconSize(WScreen *scr, RImage *icon, int max_size); + +-char * wIconStore(WIcon *icon); ++char *wIconStore(WIcon *icon); ++char *get_name_for_instance_class(char *wm_instance, char *wm_class); + + #ifdef NEWAPPICON + void wIconSetHighlited(WIcon *icon, Bool flag); +Index: src/main.c +=================================================================== +--- src/main.c.orig ++++ src/main.c +@@ -485,7 +485,7 @@ void wAbort(Bool dumpCore) + exit(1); + } + +-void print_help() ++static void print_help(void) + { + printf(_("Usage: %s [options]\n"), ProgName); + puts(_("The Window Maker window manager for the X window system")); +@@ -511,7 +511,7 @@ void print_help() + puts(_(" --help show this message")); + } + +-void check_defaults() ++static void check_defaults(void) + { + char *path; + +@@ -537,7 +537,7 @@ void check_defaults() + * files have changed, using linux kernel inotify mechanism + */ + +-static void inotifyWatchConfig() ++static void inotifyWatchConfig(void) + { + char *watchPath = NULL; + inotifyFD = inotify_init(); /* Initialise an inotify instance */ +@@ -563,7 +563,7 @@ static void inotifyWatchConfig() + } + #endif /* HAVE_INOTIFY */ + +-static void execInitScript() ++static void execInitScript(void) + { + char *file, *paths; + +@@ -581,7 +581,7 @@ static void execInitScript() + } + } + +-void ExecExitScript() ++void ExecExitScript(void) + { + char *file, *paths; + +Index: src/main.h +=================================================================== +--- /dev/null ++++ src/main.h +@@ -0,0 +1,33 @@ ++/* ++ * Window Maker window manager ++ * ++ * Copyright (c) 1997-2003 Alfredo K. Kojima ++ * Copyright (c) 1998-2003 Dan Pascu ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef WMMAIN_H_ ++#define WMMAIN_H_ ++ ++void Exit(int status) __attribute__((noreturn)); ++void Restart(char *manager, Bool abortOnFailure); ++void SetupEnvironment(WScreen *scr); ++void ExecuteShellCommand(WScreen *scr, char *command); ++Bool RelaunchWindow(WWindow *wwin); ++void wAbort(Bool dumpCore); ++void ExecExitScript(void); ++ ++#endif +Index: src/menu.c +=================================================================== +--- src/menu.c.orig ++++ src/menu.c +@@ -42,6 +42,7 @@ + #include "xinerama.h" + #include "workspace.h" + #include "dialog.h" ++#include "rootmenu.h" + + /****** Global Variables ******/ + +Index: src/misc.c +=================================================================== +--- src/misc.c.orig ++++ src/misc.c +@@ -247,6 +247,18 @@ static void eatExpose(void) + } + } + ++void move_window(Window win, int from_x, int from_y, int to_x, int to_y) ++{ ++#ifdef ANIMATIONS ++ if (wPreferences.no_animations) ++ XMoveWindow(dpy, win, to_x, to_y); ++ else ++ SlideWindow(win, from_x, from_y, to_x, to_y); ++#else ++ XMoveWindow(dpy, win, to_x, to_y); ++#endif ++} ++ + void SlideWindow(Window win, int from_x, int from_y, int to_x, int to_y) + { + time_t time0 = time(NULL); +@@ -1094,9 +1106,3 @@ char *GetCommandForWindow(Window win) + { + return getCommandForWindow(win, 0); + } +- +-/* Free result when done */ +-char *GetProgramNameForWindow(Window win) +-{ +- return getCommandForWindow(win, 1); +-} +Index: src/monitor.c +=================================================================== +--- src/monitor.c.orig ++++ src/monitor.c +@@ -37,7 +37,7 @@ + #include "screen.h" + #include "window.h" + #include "dialog.h" +-#include "funcs.h" ++#include "main.h" + + /****** Global Variables ******/ + extern WPreferences wPreferences; +Index: src/moveres.c +=================================================================== +--- src/moveres.c.orig ++++ src/moveres.c +@@ -1471,7 +1471,6 @@ int wKeyboardMoveResizeWindow(WWindow * + + if (opaqueMoveResize) { + XUngrabServer(dpy); +- wwin->flags.user_changed_width = 1; + wWindowConfigure(wwin, src_x + off_x, src_y + off_y, ww, wh - vert_border); + }; + +@@ -1518,15 +1517,11 @@ int wKeyboardMoveResizeWindow(WWindow * + } + } + } else { +- if (wwin->client.width != ww) { +- wwin->flags.user_changed_width = 1; ++ if (wwin->client.width != ww) + wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_MAXIMUS); +- } + +- if (wwin->client.height != wh - vert_border) { +- wwin->flags.user_changed_height = 1; ++ if (wwin->client.height != wh - vert_border) + wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS); +- } + + wWindowConfigure(wwin, src_x + off_x, src_y + off_y, ww, wh - vert_border); + wWindowSynthConfigureNotify(wwin); +@@ -1540,6 +1535,8 @@ int wKeyboardMoveResizeWindow(WWindow * + wArrangeIcons(scr, True); + } + ++ update_saved_geometry(wwin); ++ + return 1; + } + } +@@ -1801,6 +1798,10 @@ int wMouseMoveWindow(WWindow * wwin, XEv + head != wGetHeadForWindow(wwin)) { + wArrangeIcons(scr, True); + } ++ ++ if (started) ++ update_saved_geometry(wwin); ++ + return started; + } + +@@ -2047,7 +2048,6 @@ void wMouseResizeWindow(WWindow * wwin, + showGeometry(wwin, fx, fy, fx + fw, fy + fh, res); + /* Now, continue drawing */ + XUngrabServer(dpy); +- wwin->flags.user_changed_width = 1; + moveGeometryDisplayCentered(scr, fx + fw / 2, fy + fh / 2); + wWindowConfigure(wwin, fx, fy, fw, fh - vert_border); + showGeometry(wwin, fx, fy, fx + fw, fy + fh, res); +@@ -2072,15 +2072,11 @@ void wMouseResizeWindow(WWindow * wwin, + WMUnmapWidget(scr->gview); + XUngrabServer(dpy); + +- if (wwin->client.width != fw) { +- wwin->flags.user_changed_width = 1; ++ if (wwin->client.width != fw) + wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_MAXIMUS); +- } + +- if (wwin->client.height != fh - vert_border) { +- wwin->flags.user_changed_height = 1; ++ if (wwin->client.height != fh - vert_border) + wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS); +- } + + wWindowConfigure(wwin, fx, fy, fw, fh - vert_border); + wWindowSynthConfigureNotify(wwin); +Index: src/placement.c +=================================================================== +--- src/placement.c.orig ++++ src/placement.c +@@ -361,6 +361,46 @@ smartPlaceWindow(WWindow *wwin, int *x_r + } + + static Bool ++center_place_window(WWindow *wwin, int *x_ret, int *y_ret, ++ unsigned int width, unsigned int height, WArea usableArea) ++{ ++ WScreen *scr = wwin->screen_ptr; ++ int try_x, try_y; ++ int swidth, sheight; ++ WWindow *win; ++ ++ set_width_height(wwin, &width, &height); ++ swidth = usableArea.x2 - usableArea.x1; ++ sheight = usableArea.y2 - usableArea.y1; ++ ++ if (width > swidth || height > sheight) ++ return False; ++ ++ try_x = (usableArea.x1 + usableArea.x2 - width) / 2; ++ try_y = (usableArea.y1 + usableArea.y2 - height) / 2; ++ ++ for (win = scr->focused_window; win != NULL; win = win->next) { ++ int w = win->frame->core->width; ++ int h = win->frame->core->height; ++ int x = win->frame_x; ++ int y = win->frame_y; ++ ++ if ((x < (try_x + width)) && ((x + w) > try_x) && ++ (y < (try_y + height)) && ((y + h) > try_y) && ++ (win->flags.mapped || ++ (win->flags.shaded && ++ win->frame->workspace == scr->current_workspace && ++ !(win->flags.miniaturized || win->flags.hidden)))) ++ return False; ++ } ++ ++ *x_ret = try_x; ++ *y_ret = try_y; ++ ++ return True; ++} ++ ++static Bool + autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, + unsigned int width, unsigned int height, int tryCount, WArea usableArea) + { +@@ -502,6 +542,11 @@ void PlaceWindow(WWindow *wwin, int *x_r + smartPlaceWindow(wwin, x_ret, y_ret, width, height, usableArea); + break; + ++ case WPM_CENTER: ++ if (center_place_window(wwin, x_ret, y_ret, width, height, usableArea)) ++ break; ++ /* fall through to auto placement */ ++ + case WPM_AUTO: + if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 0, usableArea)) { + break; +@@ -513,7 +558,7 @@ void PlaceWindow(WWindow *wwin, int *x_r + automagicness aren't going to want to place their window */ + + case WPM_CASCADE: +- if (wPreferences.window_placement == WPM_AUTO) ++ if (wPreferences.window_placement == WPM_AUTO || wPreferences.window_placement == WPM_CENTER) + scr->cascade_index++; + + cascadeWindow(scr, wwin, x_ret, y_ret, width, height, h, usableArea); +Index: src/rootmenu.c +=================================================================== +--- src/rootmenu.c.orig ++++ src/rootmenu.c +@@ -42,6 +42,7 @@ + #include "actions.h" + #include "menu.h" + #include "funcs.h" ++#include "main.h" + #include "dialog.h" + #include "keybind.h" + #include "stacking.h" +@@ -994,8 +995,9 @@ static WMenu *parseCascade(WScreen * scr + separateline(line, &title, &command, ¶ms, &shortcut); + + if (command == NULL || !command[0]) { +- freeline(title, command, params, shortcut); + wwarning(_("%s:missing command in menu config: %s"), file_name, line); ++ freeline(title, command, params, shortcut); ++ wfree(line); + goto error; + } + +@@ -1006,7 +1008,7 @@ static WMenu *parseCascade(WScreen * scr + + cascade = wMenuCreate(scr, M_(title), False); + cascade->on_destroy = removeShortcutsForMenu; +- if (parseCascade(scr, cascade, file, file_name) == NULL) { ++ if (!parseCascade(scr, cascade, file, file_name)) { + wMenuDestroy(cascade, True); + } else { + wMenuEntrySetCascade(menu, wMenuAddCallback(menu, M_(title), NULL, NULL), cascade); +@@ -1014,12 +1016,14 @@ static WMenu *parseCascade(WScreen * scr + } else if (strcasecmp(command, "END") == 0) { + /* end of menu */ + freeline(title, command, params, shortcut); ++ wfree(line); + return menu; + } else { + /* normal items */ + addMenuEntry(menu, M_(title), shortcut, command, params, file_name); + } + freeline(title, command, params, shortcut); ++ wfree(line); + } + + wwarning(_("%s:syntax error in menu file:END declaration missing"), file_name); +@@ -1071,6 +1075,8 @@ static WMenu *readMenuFile(WScreen * scr + + if (command == NULL || !command[0]) { + wwarning(_("%s:missing command in menu config: %s"), file_name, line); ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } + if (strcasecmp(command, "MENU") == 0) { +@@ -1078,14 +1084,20 @@ static WMenu *readMenuFile(WScreen * scr + menu->on_destroy = removeShortcutsForMenu; + if (!parseCascade(scr, menu, file, file_name)) { + wMenuDestroy(menu, True); ++ menu = NULL; + } ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } else { + wwarning(_("%s:invalid menu file. MENU command is missing"), file_name); ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } ++ freeline(title, command, params, shortcut); ++ wfree(line); + } +- freeline(title, command, params, shortcut); + + #ifdef USECPP + if (cpp) { +@@ -1112,6 +1124,7 @@ static WMenu *readMenuPipe(WScreen * scr + char *line; + char *filename; + char flat_file[MAXLINE]; ++ char cmd[MAXLINE]; + int i; + #ifdef USECPP + char *args; +@@ -1131,10 +1144,10 @@ static WMenu *readMenuPipe(WScreen * scr + if (!args) { + wwarning(_("could not make arguments for menu file preprocessor")); + } else { +- snprintf(command, sizeof(command), "%s | %s %s", filename, CPP_PATH, args); ++ snprintf(cmd, sizeof(cmd), "%s | %s %s", filename, CPP_PATH, args); + + wfree(args); +- file = popen(command, "r"); ++ file = popen(cmd, "r"); + if (!file) { + werror(_("%s:could not open/preprocess menu file"), filename); + } +@@ -1156,6 +1169,8 @@ static WMenu *readMenuPipe(WScreen * scr + + if (command == NULL || !command[0]) { + wwarning(_("%s:missing command in menu config: %s"), filename, line); ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } + if (strcasecmp(command, "MENU") == 0) { +@@ -1163,14 +1178,21 @@ static WMenu *readMenuPipe(WScreen * scr + menu->on_destroy = removeShortcutsForMenu; + if (!parseCascade(scr, menu, file, filename)) { + wMenuDestroy(menu, True); ++ menu = NULL; + } ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } else { + wwarning(_("%s:no title given for the root menu"), filename); ++ freeline(title, command, params, shortcut); ++ wfree(line); + break; + } ++ ++ freeline(title, command, params, shortcut); ++ wfree(line); + } +- freeline(title, command, params, shortcut); + + pclose(file); + +Index: src/rootmenu.h +=================================================================== +--- src/rootmenu.h.orig ++++ src/rootmenu.h +@@ -22,23 +22,8 @@ + #ifndef WMROOTMENU_H + #define WMROOTMENU_H + +-#include "WindowMaker.h" +- +- +-typedef void *WRootMenuData; +- +- +-typedef struct _WRootMenuReader { +- Bool (*checkMenuChange)(char *path, time_t lastAccessTime); +- +- WRootMenuData (*openMenuFile)(char *path); +- Bool (*hasMoreData)(WRootMenuData *data); +- Bool (*nextCommand)(WRootMenuData *data, +- char **title, +- char **command, +- char **parameter, +- char **shortcut); +- void (*closeMenuFile)(WRootMenuData *data); +-} WRootMenuReader; ++Bool wRootMenuPerformShortcut(XEvent * event); ++void wRootMenuBindShortcuts(Window window); ++void OpenRootMenu(WScreen * scr, int x, int y, int keyboard); + + #endif /* WMROOTMENU_H */ +Index: src/screen.c +=================================================================== +--- src/screen.c.orig ++++ src/screen.c +@@ -46,6 +46,7 @@ + #include "pixmap.h" + #include "menu.h" + #include "funcs.h" ++#include "main.h" + #include "actions.h" + #include "properties.h" + #include "dock.h" +@@ -55,6 +56,7 @@ + #include "balloon.h" + #include "geomview.h" + #include "wmspec.h" ++#include "rootmenu.h" + + #include "xinerama.h" + +@@ -359,7 +361,6 @@ static void allocGCs(WScreen * scr) + static void createPixmaps(WScreen * scr) + { + WPixmap *pix; +- RImage *image; + + /* load pixmaps */ + pix = wPixmapCreateFromXBMData(scr, (char *)MENU_RADIO_INDICATOR_XBM_DATA, +@@ -402,7 +403,17 @@ static void createPixmaps(WScreen * scr) + pix->shared = 1; + scr->menu_shade_indicator = pix; + +- image = wDefaultGetImage(scr, "Logo", "WMPanel", wPreferences.icon_size); ++ create_logo_image(scr); ++ ++ scr->dock_dots = make3Dots(scr); ++ ++ /* titlebar button pixmaps */ ++ allocButtonPixmaps(scr); ++} ++ ++void create_logo_image(WScreen *scr) ++{ ++ RImage *image = wDefaultGetImage(scr, "Logo", "WMPanel", wPreferences.icon_size); + + if (!image) { + wwarning(_("could not load logo image for panels: %s"), RMessageForError(RErrorCode)); +@@ -410,11 +421,6 @@ static void createPixmaps(WScreen * scr) + WMSetApplicationIconImage(scr->wmscreen, image); + RReleaseImage(image); + } +- +- scr->dock_dots = make3Dots(scr); +- +- /* titlebar button pixmaps */ +- allocButtonPixmaps(scr); + } + + /* +Index: src/screen.h +=================================================================== +--- src/screen.h.orig ++++ src/screen.h +@@ -310,7 +310,7 @@ WScreen *wScreenSearchForRootWindow(Wind + WScreen *wScreenForWindow(Window window); /* slower than above functions */ + + void wScreenFinish(WScreen *scr); +- + void wScreenUpdateUsableArea(WScreen *scr); + ++void create_logo_image(WScreen *scr); + #endif +Index: src/session.c +=================================================================== +--- src/session.c.orig ++++ src/session.c +@@ -76,7 +76,7 @@ + #include "session.h" + #include "framewin.h" + #include "workspace.h" +-#include "funcs.h" ++#include "main.h" + #include "properties.h" + #include "application.h" + #include "appicon.h" +Index: src/session.h +=================================================================== +--- src/session.h.orig ++++ src/session.h +@@ -22,30 +22,8 @@ + #ifndef WMSESSION_H_ + #define WMSESSION_H_ + +- +-typedef struct { +- int x; +- int y; +- unsigned int w; /* client size */ +- unsigned int h; +- +- int workspace; +- unsigned shortcuts; /* mask like 1<scr_width, sh = scr->scr_height; +-#define KAB_PRECISION 4 + int px[PIECES]; + short py[PIECES]; + char pvx[PIECES], pvy[PIECES]; +@@ -127,8 +134,8 @@ void DoKaboom(WScreen * scr, Window win, + } + + XFreePixmap(dpy, tmp); +-} + #endif /* NORMAL_ICON_KABOOM */ ++} + + Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y) + { +@@ -230,10 +237,9 @@ Pixmap MakeGhostIcon(WScreen * scr, Draw + return pixmap; + } + +-#ifdef WINDOW_BIRTH_ZOOM +- + void DoWindowBirth(WWindow *wwin) + { ++#ifdef WINDOW_BIRTH_ZOOM + int center_x, center_y; + int width = wwin->frame->core->width; + int height = wwin->frame->core->height; +@@ -245,20 +251,8 @@ void DoWindowBirth(WWindow *wwin) + center_y = wwin->frame_y + (height - h) / 2; + + animateResize(scr, center_x, center_y, 1, 1, wwin->frame_x, wwin->frame_y, width, height); +-} +-#else +-void DoWindowBirth(WWindow *wwin) +-{ +- /* dummy stub */ +-} + #endif +- +-#define BOUNCE_HZ 25 +-#define BOUNCE_DELAY (1000/BOUNCE_HZ) +-#define BOUNCE_HEIGHT 24 +-#define BOUNCE_LENGTH 0.3 +-#define BOUNCE_DAMP 0.6 +-#define URGENT_BOUNCE_DELAY 3000 ++} + + typedef struct AppBouncerData { + WApplication *wapp; +Index: src/superfluous.h +=================================================================== +--- src/superfluous.h.orig ++++ src/superfluous.h +@@ -21,9 +21,10 @@ + #ifndef WMSUPERFLUOUS_H + #define WMSUPERFLUOUS_H + +-#define PIECES ((64/ICON_KABOOM_PIECE_SIZE)*(64/ICON_KABOOM_PIECE_SIZE)) ++#include "dock.h" + +-extern void DoKaboom(WScreen *scr, Window win, int x, int y); +-extern Pixmap MakeGhostDock(WDock *dock, int sx, int dx, int y); +-extern Pixmap MakeGhostIcon(WScreen *scr, Drawable drawable); +-#endif /* WMSUPERFLUOUS_H */ ++void DoKaboom(WScreen *scr, Window win, int x, int y); ++Pixmap MakeGhostDock(WDock *dock, int sx, int dx, int y); ++Pixmap MakeGhostIcon(WScreen *scr, Drawable drawable); ++void DoWindowBirth(WWindow *wwin); ++#endif +Index: src/usermenu.c +=================================================================== +--- src/usermenu.c.orig ++++ src/usermenu.c +@@ -74,6 +74,7 @@ + #include "actions.h" + #include "funcs.h" + #include "keybind.h" ++#include "xmodifier.h" + + #include "framewin.h" + +Index: src/wdefaults.c +=================================================================== +--- src/wdefaults.c.orig ++++ src/wdefaults.c +@@ -42,6 +42,10 @@ + #include "defaults.h" + #include "icon.h" + ++#define APPLY_VAL(value, flag, attrib) \ ++ if (value) {attr->flag = getBool(attrib, value); \ ++ if (mask) mask->flag = 1;} ++ + /* Global stuff */ + extern WPreferences wPreferences; + extern WDDomain *WDWindowAttributes; +@@ -125,6 +129,7 @@ static void init_wdefaults(WScreen * scr + No = WMCreatePLString("No"); + } + ++/* Returns the correct WMPropList, using instance+class or instance, or class, or default */ + static WMPropList *get_value(WMPropList * dict_win, WMPropList * dict_class, WMPropList * dict_name, + WMPropList * dict_any, WMPropList * option, WMPropList * default_value, + Bool useGlobalDefault) +@@ -161,6 +166,28 @@ static WMPropList *get_value(WMPropList + return default_value; + } + ++static WMPropList *get_value_from_instanceclass(char *value) ++{ ++ WMPropList *key, *val = NULL; ++ ++ if (!value) ++ return NULL; ++ ++ key = WMCreatePLString(value); ++ ++ WMPLSetCaseSensitive(True); ++ ++ if (WDWindowAttributes->dictionary) ++ val = key ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key) : NULL; ++ ++ if (key) ++ WMReleasePropList(key); ++ ++ WMPLSetCaseSensitive(False); ++ ++ return val; ++} ++ + /* + *---------------------------------------------------------------------- + * wDefaultFillAttributes-- +@@ -176,58 +203,27 @@ void + wDefaultFillAttributes(WScreen * scr, char *instance, char *class, + WWindowAttributes * attr, WWindowAttributes * mask, Bool useGlobalDefault) + { +- WMPropList *value, *key1, *key2, *key3, *dw, *dc, *dn, *da; ++ WMPropList *value, *dw, *dc, *dn, *da; ++ char *buffer; + +- if (class && instance) { +- char *buffer; ++ dw = dc = dn = da = NULL; + +- buffer = wmalloc(strlen(class) + strlen(instance) + 2); +- sprintf(buffer, "%s.%s", instance, class); +- key1 = WMCreatePLString(buffer); ++ if (!ANoTitlebar) ++ init_wdefaults(scr); ++ ++ if (class && instance) { ++ buffer = StrConcatDot(instance, class); ++ dw = get_value_from_instanceclass(buffer); + wfree(buffer); +- } else { +- key1 = NULL; + } + +- if (instance) +- key2 = WMCreatePLString(instance); +- else +- key2 = NULL; +- +- if (class) +- key3 = WMCreatePLString(class); +- else +- key3 = NULL; +- +- if (!ANoTitlebar) +- init_wdefaults(scr); ++ dn = get_value_from_instanceclass(instance); ++ dc = get_value_from_instanceclass(class); + + WMPLSetCaseSensitive(True); + +- if (WDWindowAttributes->dictionary) { +- dw = key1 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key1) : NULL; +- dn = key2 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key2) : NULL; +- dc = key3 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key3) : NULL; +- if (useGlobalDefault) +- da = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow); +- else +- da = NULL; +- } else { +- dw = NULL; +- dn = NULL; +- dc = NULL; +- da = NULL; +- } +- if (key1) +- WMReleasePropList(key1); +- if (key2) +- WMReleasePropList(key2); +- if (key3) +- WMReleasePropList(key3); +- +-#define APPLY_VAL(value, flag, attrib) \ +- if (value) {attr->flag = getBool(attrib, value); \ +- if (mask) mask->flag = 1;} ++ if ((WDWindowAttributes->dictionary) && (useGlobalDefault)) ++ da = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow); + + /* get the data */ + value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault); +@@ -317,7 +313,7 @@ wDefaultFillAttributes(WScreen * scr, ch + WMPLSetCaseSensitive(False); + } + +-static WMPropList *get_generic_value(WScreen *scr, char *instance, char *class, ++static WMPropList *get_generic_value(char *instance, char *class, + WMPropList *option, Bool noDefault) + { + WMPropList *value, *key, *dict; +@@ -378,28 +374,6 @@ static WMPropList *get_generic_value(WSc + return value; + } + +-/* Get the name of the Icon File. If noDefault is False, then, default value included */ +-char *wDefaultGetIconFile(WScreen * scr, char *instance, char *class, Bool noDefault) +-{ +- WMPropList *value; +- char *tmp; +- +- if (!ANoTitlebar) +- init_wdefaults(scr); +- +- if (!WDWindowAttributes->dictionary) +- return NULL; +- +- value = get_generic_value(scr, instance, class, AIcon, noDefault); +- +- if (!value) +- return NULL; +- +- tmp = getString(AIcon, value); +- +- return tmp; +-} +- + RImage *wDefaultGetImage(WScreen * scr, char *winstance, char *wclass, int max_size) + { + char *file_name; +@@ -442,7 +416,7 @@ int wDefaultGetStartWorkspace(WScreen * + if (!WDWindowAttributes->dictionary) + return -1; + +- value = get_generic_value(scr, instance, class, AStartWorkspace, False); ++ value = get_generic_value(instance, class, AStartWorkspace, False); + + if (!value) + return -1; +@@ -458,6 +432,28 @@ int wDefaultGetStartWorkspace(WScreen * + return w; + } + ++/* Get the name of the Icon File. If noDefault is False, then, default value included */ ++char *wDefaultGetIconFile(WScreen *scr, char *instance, char *class, Bool noDefault) ++{ ++ WMPropList *value; ++ char *tmp; ++ ++ if (!ANoTitlebar) ++ init_wdefaults(scr); ++ ++ if (!WDWindowAttributes->dictionary) ++ return NULL; ++ ++ value = get_generic_value(instance, class, AIcon, noDefault); ++ ++ if (!value) ++ return NULL; ++ ++ tmp = getString(AIcon, value); ++ ++ return tmp; ++} ++ + void wDefaultChangeIcon(WScreen * scr, char *instance, char *class, char *file) + { + WDDomain *db = WDWindowAttributes; +@@ -477,8 +473,8 @@ void wDefaultChangeIcon(WScreen * scr, c + + if (instance && class) { + char *buffer; +- buffer = wmalloc(strlen(instance) + strlen(class) + 2); +- sprintf(buffer, "%s.%s", instance, class); ++ ++ buffer = StrConcatDot(instance, class); + key = WMCreatePLString(buffer); + wfree(buffer); + } else if (instance) { +Index: src/window.c +=================================================================== +--- src/window.c.orig ++++ src/window.c +@@ -50,6 +50,7 @@ + #include "actions.h" + #include "client.h" + #include "funcs.h" ++#include "colormap.h" + #include "keybind.h" + #include "stacking.h" + #include "defaults.h" +@@ -57,6 +58,8 @@ + #include "xinerama.h" + #include "appmenu.h" + #include "appicon.h" ++#include "superfluous.h" ++#include "rootmenu.h" + + #ifdef MWM_HINTS + # include "motif.h" +@@ -82,9 +85,6 @@ extern Atom _XA_WINDOWMAKER_STATE; + extern WPreferences wPreferences; + extern Time LastTimestamp; + +-/* superfluous... */ +-extern void DoWindowBirth(WWindow *wwin); +- + /***** Local Stuff *****/ + static WWindowState *windowState = NULL; + static FocusMode getFocusMode(WWindow *wwin); +@@ -421,18 +421,6 @@ void wWindowSetupInitialAttributes(WWind + wwin->client_flags.no_focusable = 1; + } + +-Bool wWindowCanReceiveFocus(WWindow *wwin) +-{ +- if (!wwin->flags.mapped && (!wwin->flags.shaded || wwin->flags.hidden)) +- return False; +- if (WFLAGP(wwin, no_focusable) || wwin->flags.miniaturized) +- return False; +- if (wwin->frame->workspace != wwin->screen_ptr->current_workspace) +- return False; +- +- return True; +-} +- + Bool wWindowObscuresWindow(WWindow *wwin, WWindow *obscured) + { + int w1, h1, w2, h2; +@@ -1748,8 +1736,6 @@ void wWindowUpdateName(WWindow *wwin, ch + if (!wwin->frame) + return; + +- wwin->flags.wm_name_changed = 1; +- + if (!newTitle) + title = DEF_WINDOW_TITLE; /* the hint was removed */ + else +Index: src/window.h +=================================================================== +--- src/window.h.orig ++++ src/window.h +@@ -199,6 +199,9 @@ typedef struct WWindow { + unsigned int width, height; /* original geometry of the window */ + } bfs_geometry; /* (before fullscreen) */ + ++ int maximus_x; /* size after Maximusizing */ ++ int maximus_y; ++ + /* client window info */ + short old_border_width; /* original border width of client_win*/ + Window client_win; /* the window we're managing */ +@@ -264,11 +267,6 @@ typedef struct WWindow { + app */ + unsigned int is_dockapp:1; /* 1 if the window belongs to a DockApp */ + +- unsigned int buttons_dont_fit:1; +- unsigned int rebuild_texture:1; /* the window was resized and +- * gradients should be re-rendered */ +- unsigned int needs_full_repaint:1;/* does a full repaint of the +- * window next time it's painted */ + unsigned int icon_moved:1; /* icon for this window was moved + * by the user */ + unsigned int selected:1; /* multiple window selection */ +@@ -279,19 +277,9 @@ typedef struct WWindow { + unsigned int inspector_open:1; /* attrib inspector is already open */ + + unsigned int destroyed:1; /* window was already destroyed */ +- + unsigned int menu_open_for_me:1; /* window commands menu */ +- +- unsigned int waiting_save_ack:1; /* waiting for SAVE_YOURSELF ack */ +- + unsigned int obscured:1; /* window is obscured */ + +- unsigned int dragged_while_fmaximized; +- +- unsigned int user_changed_width:1; +- unsigned int user_changed_height:1; +- unsigned int wm_name_changed:1; +- unsigned int net_state_from_client:1; /* state hint was set by client */ + unsigned int net_skip_pager:1; + unsigned int net_handle_icon:1; + unsigned int net_show_desktop:1; +@@ -341,7 +329,6 @@ typedef struct WSavedState { + unsigned window_shortcuts; /* mask like 1< + #include ++#include + + #include "WindowMaker.h" + #include "actions.h" + #include "menu.h" +-#include "funcs.h" ++#include "main.h" + #include "window.h" + #include "client.h" + #include "application.h" +@@ -246,7 +247,7 @@ static void updateWorkspaceMenu(WMenu * + static char *getShortcutString(WShortKey key) + { + char *tmp = NULL; +- char *k = XKeysymToString(XKeycodeToKeysym(dpy, key.keycode, 0)); ++ char *k = XKeysymToString(XkbKeycodeToKeysym(dpy, key.keycode, 0, 0)); + if (!k) return NULL; + + char **m = wPreferences.modifier_labels; +@@ -576,11 +577,10 @@ static void updateMenuForWindow(WMenu * + wMenuRealize(menu); + } + +-void OpenWindowMenu(WWindow * wwin, int x, int y, int keyboard) ++static WMenu *open_window_menu_core(WWindow *wwin, int x, int y) + { +- WMenu *menu; + WScreen *scr = wwin->screen_ptr; +- WMRect rect; ++ WMenu *menu; + + wwin->flags.menu_open_for_me = 1; + +@@ -598,18 +598,18 @@ void OpenWindowMenu(WWindow * wwin, int + menu = scr->window_menu; + if (menu->flags.mapped) { + wMenuUnmap(menu); +- if (menu->entries[0]->clientdata == wwin) { +- return; +- } ++ if (menu->entries[0]->clientdata == wwin) ++ return NULL; + } + + updateMenuForWindow(menu, wwin); + +- x -= menu->frame->core->width / 2; +- if (x + menu->frame->core->width > wwin->frame_x + wwin->frame->core->width) +- x = wwin->frame_x + wwin->frame->core->width - menu->frame->core->width; +- if (x < wwin->frame_x) +- x = wwin->frame_x; ++ return menu; ++} ++ ++static void prepare_menu_position(WMenu *menu, int x, int y) ++{ ++ WMRect rect; + + rect = wGetRectForHead(menu->frame->screen_ptr, + wGetHeadForPointerLocation(menu->frame->screen_ptr)); +@@ -617,6 +617,25 @@ void OpenWindowMenu(WWindow * wwin, int + x = rect.pos.x - menu->frame->core->width / 2; + if (y < rect.pos.y) + y = rect.pos.y; ++} ++ ++void OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard) ++{ ++ WMenu *menu; ++ ++ menu = open_window_menu_core(wwin, x, y); ++ if (!menu) ++ return; ++ ++ /* Specific menu position */ ++ x -= menu->frame->core->width / 2; ++ if (x + menu->frame->core->width > wwin->frame_x + wwin->frame->core->width) ++ x = wwin->frame_x + wwin->frame->core->width - menu->frame->core->width; ++ if (x < wwin->frame_x) ++ x = wwin->frame_x; ++ ++ /* Common menu position */ ++ prepare_menu_position(menu, x, y); + + if (!wwin->flags.internal_window) + wMenuMapAt(menu, x, y, keyboard); +@@ -627,31 +646,12 @@ void OpenWindowMenu2(WWindow *wwin, int + int i; + WMenu *menu; + WScreen *scr = wwin->screen_ptr; +- WMRect rect; +- +- wwin->flags.menu_open_for_me = 1; + +- if (!scr->window_menu) { +- scr->window_menu = createWindowMenu(scr); +- +- /* hack to save some memory allocation/deallocation */ +- wfree(scr->window_menu->entries[MC_MINIATURIZE]->text); +- wfree(scr->window_menu->entries[MC_MAXIMIZE]->text); +- wfree(scr->window_menu->entries[MC_SHADE]->text); +- } else { +- updateWorkspaceMenu(scr->workspace_submenu); +- } +- +- menu = scr->window_menu; +- if (menu->flags.mapped) { +- wMenuUnmap(menu); +- if (menu->entries[0]->clientdata == wwin) { +- return; +- } +- } +- +- updateMenuForWindow(menu, wwin); ++ menu = open_window_menu_core(wwin, x, y); ++ if (!menu) ++ return; + ++ /* Specific menu position */ + for (i = 0; i < scr->workspace_submenu->entry_no; i++) { + scr->workspace_submenu->entries[i]->clientdata = wwin; + wMenuSetEnabled(scr->workspace_submenu, i, True); +@@ -659,12 +659,8 @@ void OpenWindowMenu2(WWindow *wwin, int + + x -= menu->frame->core->width / 2; + +- rect = wGetRectForHead(menu->frame->screen_ptr, +- wGetHeadForPointerLocation(menu->frame->screen_ptr)); +- if (x < rect.pos.x - menu->frame->core->width / 2) +- x = rect.pos.x - menu->frame->core->width / 2; +- if (y < rect.pos.y) +- y = rect.pos.y; ++ /* Common menu position */ ++ prepare_menu_position(menu, x, y); + + if (!wwin->flags.internal_window) + wMenuMapAt(menu, x, y, keyboard); +@@ -673,30 +669,10 @@ void OpenWindowMenu2(WWindow *wwin, int + void OpenMiniwindowMenu(WWindow * wwin, int x, int y) + { + WMenu *menu; +- WScreen *scr = wwin->screen_ptr; +- +- wwin->flags.menu_open_for_me = 1; + +- if (!scr->window_menu) { +- scr->window_menu = createWindowMenu(scr); +- +- /* hack to save some memory allocation/deallocation */ +- wfree(scr->window_menu->entries[MC_MINIATURIZE]->text); +- wfree(scr->window_menu->entries[MC_MAXIMIZE]->text); +- wfree(scr->window_menu->entries[MC_SHADE]->text); +- } else { +- updateWorkspaceMenu(scr->workspace_submenu); +- } +- +- menu = scr->window_menu; +- if (menu->flags.mapped) { +- wMenuUnmap(menu); +- if (menu->entries[0]->clientdata == wwin) { +- return; +- } +- } +- +- updateMenuForWindow(menu, wwin); ++ menu = open_window_menu_core(wwin, x, y); ++ if (!menu) ++ return; + + x -= menu->frame->core->width / 2; + +Index: src/winspector.c +=================================================================== +--- src/winspector.c.orig ++++ src/winspector.c +@@ -47,7 +47,6 @@ + #include "dock.h" + #include "client.h" + #include "wmspec.h" +-#include "xinerama.h" + + #include + +@@ -163,11 +162,11 @@ static WMPropList *Yes, *No; + #define PHEIGHT 360 + + static char *spec_text; +-static void applySettings(WMButton * button, InspectorPanel * panel); ++static void applySettings(WMButton *button, InspectorPanel *panel); + + #define UNDEFINED_POS 0xffffff + +-static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel); ++static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel); + + static void make_keys(void) + { +@@ -213,20 +212,19 @@ static void make_keys(void) + No = WMCreatePLString("No"); + } + +-static void freeInspector(InspectorPanel * panel) ++static void freeInspector(InspectorPanel *panel) + { + panel->destroyed = 1; ++ + if (panel->choosingIcon) + return; + + WMDestroyWidget(panel->win); +- + XDestroyWindow(dpy, panel->parent); +- + wfree(panel); + } + +-static void destroyInspector(WCoreWindow * foo, void *data, XEvent * event) ++static void destroyInspector(WCoreWindow *foo, void *data, XEvent *event) + { + InspectorPanel *panel; + InspectorPanel *tmp; +@@ -272,7 +270,7 @@ void wDestroyInspectorPanels(void) + } + } + +-static void changePage(WMPopUpButton * bPtr, InspectorPanel * panel) ++static void changePage(WMPopUpButton *bPtr, InspectorPanel *panel) + { + int page; + +@@ -312,7 +310,7 @@ static void changePage(WMPopUpButton * b + #define UPDATE_TEXT_FIELD 2 + #define REVERT_TO_DEFAULT 4 + +-static int showIconFor(WMScreen * scrPtr, InspectorPanel * panel, char *wm_instance, char *wm_class, int flags) ++static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, char *wm_instance, char *wm_class, int flags) + { + WMPixmap *pixmap = (WMPixmap *) NULL; + char *file = NULL, *path = NULL; +@@ -386,7 +384,7 @@ static void updateIcon(WMButton * button + } + #endif + +-static int getBool(WMPropList * value) ++static int getBool(WMPropList *value) + { + char *val; + +@@ -425,7 +423,7 @@ static int getBool(WMPropList * value) + */ + + static int +-insertAttribute(WMPropList * dict, WMPropList * window, WMPropList * attr, WMPropList * value, int flags) ++insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags) + { + WMPropList *def_win, *def_value = NULL; + int update = 0; +@@ -457,7 +455,7 @@ insertAttribute(WMPropList * dict, WMPro + return modified; + } + +-static void saveSettings(WMButton * button, InspectorPanel * panel) ++static void saveSettings(WMButton *button, InspectorPanel *panel) + { + WWindow *wwin = panel->inspected; + WDDomain *db = WDWindowAttributes; +@@ -674,72 +672,7 @@ static void saveSettings(WMButton * butt + WMPLSetCaseSensitive(False); + } + +-static void makeAppIconFor(WApplication * wapp) +-{ +- WScreen *scr = wapp->main_window_desc->screen_ptr; +- +- if (wapp->app_icon) +- return; +- +- if (!WFLAGP(wapp->main_window_desc, no_appicon)) +- wapp->app_icon = wAppIconCreate(wapp->main_window_desc); +- else +- wapp->app_icon = NULL; +- +- if (wapp->app_icon) { +- WIcon *icon = wapp->app_icon->icon; +- WDock *clip = scr->workspaces[scr->current_workspace]->clip; +- int x = 0, y = 0; +- +- wapp->app_icon->main_window = wapp->main_window; +- +- if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) { +- wapp->app_icon->attracted = 1; +- if (!wapp->app_icon->icon->shadowed) { +- wapp->app_icon->icon->shadowed = 1; +- wapp->app_icon->icon->force_paint = 1; +- } +- wDockAttachIcon(clip, wapp->app_icon, x, y); +- } else { +- PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc)); +- wAppIconMove(wapp->app_icon, x, y); +- } +- if (!clip || !wapp->app_icon->attracted || !clip->collapsed) +- XMapWindow(dpy, icon->core->window); +- +- if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted) +- wArrangeIcons(wapp->main_window_desc->screen_ptr, True); +- } +-} +- +-static void removeAppIconFor(WApplication * wapp) +-{ +- if (!wapp->app_icon) +- return; +- +- if (wapp->app_icon->docked && !wapp->app_icon->attracted) { +- wapp->app_icon->running = 0; +- /* since we keep it, we don't care if it was attracted or not */ +- wapp->app_icon->attracted = 0; +- wapp->app_icon->icon->shadowed = 0; +- wapp->app_icon->main_window = None; +- wapp->app_icon->pid = 0; +- wapp->app_icon->icon->owner = NULL; +- wapp->app_icon->icon->icon_win = None; +- wapp->app_icon->icon->force_paint = 1; +- wAppIconPaint(wapp->app_icon); +- } else if (wapp->app_icon->docked) { +- wapp->app_icon->running = 0; +- wDockDetach(wapp->app_icon->dock, wapp->app_icon); +- } else { +- wAppIconDestroy(wapp->app_icon); +- } +- wapp->app_icon = NULL; +- if (wPreferences.auto_arrange_icons) +- wArrangeIcons(wapp->main_window_desc->screen_ptr, True); +-} +- +-static void applySettings(WMButton * button, InspectorPanel * panel) ++static void applySettings(WMButton *button, InspectorPanel *panel) + { + WWindow *wwin = panel->inspected; + WApplication *wapp = wApplicationOf(wwin->main_window); +@@ -861,7 +794,7 @@ static void applySettings(WMButton * but + } + } + +-static void revertSettings(WMButton * button, InspectorPanel * panel) ++static void revertSettings(WMButton *button, InspectorPanel *panel) + { + WWindow *wwin = panel->inspected; + WApplication *wapp = wApplicationOf(wwin->main_window); +@@ -884,7 +817,7 @@ static void revertSettings(WMButton * bu + + wWindowSetupInitialAttributes(wwin, &level, &workspace); + +- for (i = 0; i < 11; i++) { ++ for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) { + int flag = 0; + + switch (i) { +@@ -924,7 +857,7 @@ static void revertSettings(WMButton * bu + } + WMSetButtonSelected(panel->attrChk[i], flag); + } +- for (i = 0; i < 12; i++) { ++ for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) { + int flag = 0; + + switch (i) { +@@ -970,7 +903,7 @@ static void revertSettings(WMButton * bu + WMSetButtonSelected(panel->moreChk[i], flag); + } + if (panel->appFrm && wapp) { +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) { + int flag = 0; + + switch (i) { +@@ -1005,7 +938,7 @@ static void revertSettings(WMButton * bu + applySettings(panel->applyBtn, panel); + } + +-static void chooseIconCallback(WMWidget * self, void *clientData) ++static void chooseIconCallback(WMWidget *self, void *clientData) + { + char *file; + InspectorPanel *panel = (InspectorPanel *) clientData; +@@ -1032,7 +965,7 @@ static void chooseIconCallback(WMWidget + } + } + +-static void textEditedObserver(void *observerData, WMNotification * notification) ++static void textEditedObserver(void *observerData, WMNotification *notification) + { + InspectorPanel *panel = (InspectorPanel *) observerData; + +@@ -1045,7 +978,7 @@ static void textEditedObserver(void *obs + */ + } + +-static void selectSpecification(WMWidget * bPtr, void *data) ++static void selectSpecification(WMWidget *bPtr, void *data) + { + InspectorPanel *panel = (InspectorPanel *) data; + char *str; +@@ -1070,7 +1003,7 @@ static void selectSpecification(WMWidget + wfree(str); + } + +-static void selectWindow(WMWidget * bPtr, void *data) ++static void selectWindow(WMWidget *bPtr, void *data) + { + InspectorPanel *panel = (InspectorPanel *) data; + WWindow *wwin = panel->inspected; +@@ -1104,7 +1037,7 @@ static void selectWindow(WMWidget * bPtr + } + } + +-static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel) ++static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel) + { + WScreen *scr = wwin->screen_ptr; + InspectorPanel *panel; +@@ -1246,13 +1179,13 @@ static InspectorPanel *createInspectorFo + + WMSetLabelTextAlignment(panel->specLbl, WALeft); + +- /**** attributes ****/ ++ /**** attributes ****/ + panel->attrFrm = WMCreateFrame(panel->win); + WMSetFrameTitle(panel->attrFrm, _("Attributes")); + WMMoveWidget(panel->attrFrm, 15, 45); + WMResizeWidget(panel->attrFrm, frame_width, 250); + +- for (i = 0; i < 11; i++) { ++ for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) { + char *caption = NULL; + int flag = 0; + char *descr = NULL; +@@ -1328,19 +1261,13 @@ static InspectorPanel *createInspectorFo + WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i])); + } + +- /**** more attributes ****/ ++ /**** more attributes ****/ + panel->moreFrm = WMCreateFrame(panel->win); + WMSetFrameTitle(panel->moreFrm, _("Advanced")); + WMMoveWidget(panel->moreFrm, 15, 45); + WMResizeWidget(panel->moreFrm, frame_width, 265); + +- for (i = 0; +-#ifdef XKB_BUTTON_HINT +- i < 12; +-#else +- i < 11; +-#endif +- i++) { ++ for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) { + char *caption = NULL; + int flag = 0; + char *descr = NULL; +@@ -1486,16 +1413,15 @@ static InspectorPanel *createInspectorFo + WMMoveWidget(panel->wsP, 20, 30); + WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20); + WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular")); +- for (i = 0; i < wwin->screen_ptr->workspace_count; i++) { ++ ++ for (i = 0; i < wwin->screen_ptr->workspace_count; i++) + WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name); +- } + + i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class); +- if (i >= 0 && i <= wwin->screen_ptr->workspace_count) { ++ if (i >= 0 && i <= wwin->screen_ptr->workspace_count) + WMSetPopUpButtonSelectedItem(panel->wsP, i + 1); +- } else { ++ else + WMSetPopUpButtonSelectedItem(panel->wsP, 0); +- } + + /* application wide attributes */ + if (wwin->main_window != None) { +@@ -1506,7 +1432,7 @@ static InspectorPanel *createInspectorFo + WMMoveWidget(panel->appFrm, 15, 50); + WMResizeWidget(panel->appFrm, frame_width, 240); + +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) { + char *caption = NULL; + int flag = 0; + char *descr = NULL; +@@ -1537,7 +1463,6 @@ static InspectorPanel *createInspectorFo + WMResizeWidget(panel->appChk[i], 205, 20); + WMSetButtonSelected(panel->appChk[i], flag); + WMSetButtonText(panel->appChk[i], caption); +- + WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i])); + } + +@@ -1638,7 +1563,7 @@ static InspectorPanel *createInspectorFo + return panel; + } + +-void wShowInspectorForWindow(WWindow * wwin) ++void wShowInspectorForWindow(WWindow *wwin) + { + if (wwin->flags.inspector_open) + return; +@@ -1650,7 +1575,7 @@ void wShowInspectorForWindow(WWindow * w + wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False); + } + +-void wHideInspectorForWindow(WWindow * wwin) ++void wHideInspectorForWindow(WWindow *wwin) + { + WWindow *pwin = wwin->inspector->frame; + +@@ -1660,7 +1585,7 @@ void wHideInspectorForWindow(WWindow * w + wClientSetState(pwin, IconicState, None); + } + +-void wUnhideInspectorForWindow(WWindow * wwin) ++void wUnhideInspectorForWindow(WWindow *wwin) + { + WWindow *pwin = wwin->inspector->frame; + +@@ -1671,7 +1596,7 @@ void wUnhideInspectorForWindow(WWindow * + wClientSetState(pwin, NormalState, None); + } + +-WWindow *wGetWindowOfInspectorForWindow(WWindow * wwin) ++WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin) + { + if (wwin->inspector) { + assert(wwin->flags.inspector_open != 0); +@@ -1681,7 +1606,7 @@ WWindow *wGetWindowOfInspectorForWindow( + return NULL; + } + +-void wCloseInspectorForWindow(WWindow * wwin) ++void wCloseInspectorForWindow(WWindow *wwin) + { + WWindow *pwin = wwin->inspector->frame; /* the inspector window */ + +Index: src/wmspec.c +=================================================================== +--- src/wmspec.c.orig ++++ src/wmspec.c +@@ -795,9 +795,7 @@ static void updateWorkspaceHint(WWindow + static void updateStateHint(WWindow * wwin, Bool changedWorkspace, Bool del) + { /* changeable */ + if (del) { +- if (!wwin->flags.net_state_from_client) { +- XDeleteProperty(dpy, wwin->client_win, net_wm_state); +- } ++ XDeleteProperty(dpy, wwin->client_win, net_wm_state); + } else { + Atom state[15]; /* nr of defined state atoms */ + int i = 0; +Index: src/xmodifier.c +=================================================================== +--- src/xmodifier.c.orig ++++ src/xmodifier.c +@@ -33,6 +33,7 @@ Perpetrator: Sudish Joseph + #include + #include ++#include + + #include + #include "xmodifier.h" +@@ -160,7 +161,7 @@ static void x_reset_modifier_mapping(Dis + for (column = 0; column < 4; column += 2) { + KeyCode code = x_modifier_keymap->modifiermap[modifier_index * mkpm + + modifier_key]; +- KeySym sym = (code ? XKeycodeToKeysym(display, code, column) : 0); ++ KeySym sym = (code ? XkbKeycodeToKeysym(display, code, 0, column) : 0); + if (sym == last_sym) + continue; + last_sym = sym; +Index: util/wmaker.inst.in +=================================================================== +--- util/wmaker.inst.in.orig ++++ util/wmaker.inst.in +@@ -262,22 +262,17 @@ show_end_message() { + echo + echo "Installation Finished" + echo +-if test -z "#LITE#" ; then +- echo "There are menus in 2 different file formats. The plain text format and" +- echo "the property list format. The plain text format is more flexible, but" +- echo "the menu in the property list format can be edited graphically. The" +- echo "menu that will be used by default is the property list one. Read" +- echo " $GSDIR/Library/WindowMaker/README" +- echo "for information on how to change it." +- if [ "${inst_menu%.*}" = "menu" ]; then +- echo "However, since you have locale set to $LOCALE and plmenu for such locale" +- echo "was not found, your WMRootMenu contains path to text formated menu:" +- echo " $GSDIR/Library/WindowMaker/$inst_menu" +- fi +-else +- echo "Your copy of Window Maker is configured especially for KDE." +- echo "Window Maker application menus are not available." +-fi ++echo "There are menus in 2 different file formats. The plain text format and" ++echo "the property list format. The plain text format is more flexible, but" ++echo "the menu in the property list format can be edited graphically. The" ++echo "menu that will be used by default is the property list one. Read" ++echo " $GSDIR/Library/WindowMaker/README" ++echo "for information on how to change it." ++ if [ "${inst_menu%.*}" = "menu" ]; then ++echo "However, since you have locale set to $LOCALE and plmenu for such locale" ++echo "was not found, your WMRootMenu contains path to text formated menu:" ++echo " $GSDIR/Library/WindowMaker/$inst_menu" ++ fi + } + + wmaker_found=0 +Index: util/wmmenugen_parse_xdg.c +=================================================================== +--- util/wmmenugen_parse_xdg.c.orig ++++ util/wmmenugen_parse_xdg.c +@@ -119,13 +119,11 @@ void parse_xdg(const char *file, void (* + continue; + + if (strcmp(p, "[Desktop Entry]") == 0) { +- if (InGroup) { +- /* if currently processing a group, we've just hit the +- * end of its definition, try processing it +- */ +- if (xdg_to_wm(&xdg, &wm)) { +- (*addWMMenuEntryCallback)(wm); +- } ++ /* if currently processing a group, we've just hit the ++ * end of its definition, try processing it ++ */ ++ if (InGroup && xdg_to_wm(&xdg, &wm)) { ++ (*addWMMenuEntryCallback)(wm); + } + init_xdg_storage(&xdg); + init_wm_storage(&wm); +@@ -180,8 +178,10 @@ void parse_xdg(const char *file, void (* + + fclose(fp); + +- /* at the end of the file, might as well try to menuize what we have */ +- if (xdg_to_wm(&xdg, &wm)) ++ /* at the end of the file, might as well try to menuize what we have ++ * unless there was no group at all or it was marked as hidden ++ */ ++ if (InGroup && xdg_to_wm(&xdg, &wm)) + (*addWMMenuEntryCallback)(wm); + + } +Index: util/wmsetbg.c +=================================================================== +--- util/wmsetbg.c.orig ++++ util/wmsetbg.c +@@ -175,9 +175,18 @@ applyImage(RContext * rc, BackgroundText + switch (toupper(type)) { + case 'S': + case 'M': ++ case 'F': + if (toupper(type) == 'S') { + w = width; + h = height; ++ } else if(toupper(type) == 'F') { ++ if (image->width * height > image->height * width) { ++ w = (height * image->width) / image->height; ++ h = height; ++ } else { ++ w = width; ++ h = (width * image->height) / image->width; ++ } + } else { + if (image->width * height > image->height * width) { + w = width; +@@ -465,7 +474,7 @@ BackgroundTexture *parseTexture(RContext + + texture->pixmap = pixmap; + } else if (strcasecmp(type, "cpixmap") == 0 +- || strcasecmp(type, "spixmap") == 0 ++ || strcasecmp(type, "spixmap") == 0 || strcasecmp(type, "fpixmap") == 0 + || strcasecmp(type, "mpixmap") == 0 || strcasecmp(type, "tpixmap") == 0) { + XColor color; + Pixmap pixmap = None; +@@ -528,6 +537,7 @@ BackgroundTexture *parseTexture(RContext + case 'S': + case 'M': + case 'C': ++ case 'F': + { + Pixmap tpixmap = + XCreatePixmap(dpy, root, scrWidth, scrHeight, DefaultDepth(dpy, scr)); +@@ -1136,6 +1146,7 @@ void print_help() + puts(" -e, --center center image"); + puts(" -s, --scale scale image (default)"); + puts(" -a, --maxscale scale image and keep aspect ratio"); ++ puts(" -f, --fillscale scale image to fill screen and keep aspect ratio"); + puts(" -u, --update-wmaker update WindowMaker domain database"); + puts(" -D, --update-domain update database"); + puts(" -c, --colors colors per channel to use"); +@@ -1227,6 +1238,8 @@ int main(int argc, char **argv) + style = "cpixmap"; + } else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--maxscale") == 0) { + style = "mpixmap"; ++ } else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fillscale") == 0) { ++ style = "fpixmap"; + } else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dither") == 0) { + render_mode = RDitheredRendering; + obey_user++; diff --git a/WindowMaker.changes b/WindowMaker.changes index 171f76e..95b3ce1 100644 --- a/WindowMaker.changes +++ b/WindowMaker.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Tue Sep 18 11:48:57 UTC 2012 - chris@computersalat.de + +- fix for bnc#780348 + * added WindowMaker-81eefca4e.patch + * this patch provides fixes for + o WMRootMenu + (SuSE, OPEN_MENU, "| xdg_menu --format WindowMaker --charset UTF-8") + o More (un)maximize tweaks ("jumping window") + * http://repo.or.cz/w/wmaker-crm.git/commit/81eefca4ef70414d73048300058e5007f402dd7f + ------------------------------------------------------------------- Fri May 25 08:44:59 UTC 2012 - chris@computersalat.de diff --git a/WindowMaker.spec b/WindowMaker.spec index 11adc96..6ef144c 100644 --- a/WindowMaker.spec +++ b/WindowMaker.spec @@ -32,6 +32,9 @@ Source6: windowmaker Source7: %{name}-rpmlintrc Patch1: %{name}-config.patch Patch2: %{name}-menu.patch +# Patch-Upstream: fix for jumping window, WMRootMenu +## git diff wmaker-0.95.3..81eefca4e +Patch100: %{name}-81eefca4e.patch # BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: fontconfig-devel @@ -90,6 +93,7 @@ mkdir menu_orig cp %{name}/{menu.*,plmenu.*} menu_orig %patch1 %patch2 +%patch100 cp %{S:4} . cp %{S:6} . %if 0%{?suse_version} < 1140