From 3c046182788196ebfedd015661871db27e8f59ae Mon Sep 17 00:00:00 2001 From: kojima Date: Thu, 16 Sep 1999 02:58:56 +0000 Subject: [PATCH] fixed many bugs, removed linked list --- src/Makefile.am | 2 - src/Makefile.in | 11 +- src/actions.c | 10 +- src/appicon.c | 2 +- src/defaults.c | 36 ++++- src/dock.c | 145 +++++++++++++------ src/dock.h | 2 +- src/event.c | 180 +++++++++++++---------- src/funcs.h | 8 ++ src/list.c | 226 ----------------------------- src/list.h | 60 -------- src/main.c | 52 ++++++- src/menu.c | 93 ++++++------ src/misc.c | 79 +++++++++-- src/moveres.c | 415 +++++++++++++++++++++++++++--------------------------- src/placement.c | 230 +++++++++++++++++------------- src/plugin.c | 24 ++-- src/rootmenu.c | 65 +++++---- src/screen.c | 15 +- src/screen.h | 4 +- src/session.c | 9 +- src/superfluous.c | 188 +++++++++++++++++++++++-- src/wconfig.h.in | 8 +- src/wdefaults.c | 17 ++- src/window.c | 189 ++++++++++++++----------- src/winmenu.c | 30 ++-- src/winspector.c | 87 +++++++----- src/workspace.c | 15 +- 28 files changed, 1205 insertions(+), 997 deletions(-) delete mode 100644 src/list.c delete mode 100644 src/list.h diff --git a/src/Makefile.am b/src/Makefile.am index 0873d2ca..c2a283cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,8 +43,6 @@ wmaker_SOURCES = \ keybind.h \ kwm.h \ kwm.c \ - list.c \ - list.h \ main.c \ menu.c \ menu.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 09fd8973..ece1060b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -59,12 +59,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ -AS = @AS@ CC = @CC@ CPP_PATH = @CPP_PATH@ DFLAGS = @DFLAGS@ DLLIBS = @DLLIBS@ -DLLTOOL = @DLLTOOL@ GFXLIBS = @GFXLIBS@ HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@ ICONEXT = @ICONEXT@ @@ -79,7 +77,6 @@ MAKEINFO = @MAKEINFO@ MOFILES = @MOFILES@ NLSDIR = @NLSDIR@ NM = @NM@ -OBJDUMP = @OBJDUMP@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ @@ -100,7 +97,7 @@ bin_PROGRAMS = wmaker EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h -wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c extend_pixmaps.h framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c list.c list.h main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c plugin.c plugin.h properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xdnd.h xdnd.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h +wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c extend_pixmaps.h framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c plugin.c plugin.h properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xdnd.h xdnd.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h CPPFLAGS = @CPPFLAGS@ @DFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\" @@ -124,8 +121,8 @@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ wmaker_OBJECTS = actions.o appicon.o application.o appmenu.o balloon.o \ client.o colormap.o defaults.o dialog.o dock.o dockedapp.o event.o \ -framewin.o gnome.o icon.o kwm.o list.o main.o menu.o misc.o motif.o \ -moveres.o openlook.o pixmap.o placement.o plugin.o properties.o proplist.o \ +framewin.o gnome.o icon.o kwm.o main.o menu.o misc.o motif.o moveres.o \ +openlook.o pixmap.o placement.o plugin.o properties.o proplist.o \ resources.o rootmenu.o screen.o session.o shutdown.o stacking.o \ startup.o superfluous.o switchmenu.o texture.o usermenu.o xdnd.o \ xmodifier.o xutil.o wcore.o wdefaults.o window.o winmenu.o winspector.o \ @@ -144,7 +141,7 @@ wconfig.h.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(wmaker_SOURCES) OBJECTS = $(wmaker_OBJECTS) diff --git a/src/actions.c b/src/actions.c index 8858a8e8..ce60c7ab 100644 --- a/src/actions.c +++ b/src/actions.c @@ -46,7 +46,6 @@ #include "dock.h" #include "appmenu.h" #include "winspector.h" -#include "list.h" #include "workspace.h" #ifdef GNOME_STUFF @@ -1766,15 +1765,20 @@ void wSelectWindow(WWindow *wwin, Bool flag) { WScreen *scr = wwin->screen_ptr; + if (flag) { wwin->flags.selected = 1; XSetWindowBorder(dpy, wwin->frame->core->window, scr->white_pixel); - scr->selected_windows = list_cons(wwin, scr->selected_windows); + if (!scr->selected_windows) + scr->selected_windows = WMCreateBag(4); + WMPutInBag(scr->selected_windows, wwin); } else { wwin->flags.selected = 0; XSetWindowBorder(dpy, wwin->frame->core->window, scr->frame_border_pixel); - scr->selected_windows = list_remove_elem(scr->selected_windows, wwin); + if (scr->selected_windows) { + WMRemoveFromBag(scr->selected_windows, wwin); + } } } diff --git a/src/appicon.c b/src/appicon.c index 353852de..0c81aac3 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -377,7 +377,7 @@ updateDockNumbers(WScreen *scr) length = strlen(ws_numbers); XClearArea(dpy, dicon->icon->core->window, 2, 2, 50, - scr->icon_title_font->y+1, False); + WMFontHeight(scr->icon_title_font)+1, False); XSetForeground(dpy, numbers_gc, scr->black_pixel); WMDrawString(scr->wmscreen, dicon->icon->core->window, numbers_gc, diff --git a/src/defaults.c b/src/defaults.c index 35eec188..ccea8732 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -256,6 +256,7 @@ static WOptionEnumeration seSpeeds[] = { }; static WOptionEnumeration seMouseButtons[] = { + {"None", -1, 0}, {"Left", Button1, 0}, {"Button1", Button1, 1}, {"Middle", Button2, 0}, {"Button2", Button2, 1}, {"Right", Button3, 0}, {"Button3", Button3, 1}, @@ -898,7 +899,7 @@ wDefaultsInitDomain(char *domain, Bool requireDictionary) } /* global system dictionary */ - sprintf(path, "%s/%s", SYSCONFDIR, domain); + sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain); if (stat(path, &stbuf)>=0) { shared_dict = ReadProplistFromFile(path); if (shared_dict) { @@ -922,8 +923,8 @@ wDefaultsInitDomain(char *domain, Bool requireDictionary) } } } else { - wwarning(_("could not load domain %s from global defaults database"), - domain); + wwarning(_("could not load domain %s from global defaults database (%s)"), + domain, path); } } @@ -1108,6 +1109,7 @@ wReadDefaults(WScreen *scr, proplist_t new_dict) proplist_t plvalue, old_value; WDefaultEntry *entry; int i, must_update; + int update_workspace_back = 0; /* kluge :/ */ int needs_refresh; void *tdata; proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict @@ -1146,16 +1148,33 @@ wReadDefaults(WScreen *scr, proplist_t new_dict) } else if (!PLIsEqual(plvalue, old_value)) { /* value has changed */ } else { - /* value was not changed since last time */ - continue; + + if (strcmp(entry->key, "WorkspaceBack") == 0 + && update_workspace_back + && scr->flags.backimage_helper_launched) { + } else { + /* value was not changed since last time */ + continue; + } } if (plvalue) { #ifdef DEBUG - printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue)); + printf("Updating %s to %s\n", entry->key, + PLGetDescription(plvalue)); #endif /* convert data */ if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) { + /* + * If the WorkspaceSpecificBack data has been changed + * so that the helper will be launched now, we must be + * sure to send the default background texture config + * to the helper. + */ + if (strcmp(entry->key, "WorkspaceSpecificBack") == 0 + && !scr->flags.backimage_helper_launched) { + update_workspace_back = 1; + } if (entry->update) { needs_refresh |= (*entry->update)(scr, entry, tdata, entry->extra_data); @@ -2014,7 +2033,7 @@ getTextRenderer(WScreen *scr, WDefaultEntry *entry, proplist_t value, { proplist_t elem; char *val, *lib, *func, **argv; - int argc, i, changed; + int argc, changed; if (strcmp(entry->key, "FTitleColor")==0) { wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_FTITLE]); @@ -2057,6 +2076,8 @@ getTextRenderer(WScreen *scr, WDefaultEntry *entry, proplist_t value, } else if (PLIsString(value)) { return getColor(scr, entry, value, addr, ret); } + + return False; } #endif /* DRAWSTRING_PLUGIN */ @@ -2841,6 +2862,7 @@ setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value, SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path); } + } for (i = 0; i < PLGetNumberOfElements(value); i++) { diff --git a/src/dock.c b/src/dock.c index c948a414..a559e4fc 100644 --- a/src/dock.c +++ b/src/dock.c @@ -54,7 +54,6 @@ #include "framewin.h" #include "superfluous.h" -#include "list.h" #include @@ -313,17 +312,17 @@ numberOfSelectedIcons(WDock *dock) } -static LinkedList* +static WMBag* getSelected(WDock *dock) { - LinkedList *ret=NULL; + WMBag *ret = WMCreateBag(8); WAppIcon *btn; int i; for (i=1; imax_icons; i++) { btn = dock->icon_array[i]; if (btn && btn->icon->selected) { - ret = list_cons(btn, ret); + WMPutInBag(ret, btn); } } @@ -482,8 +481,9 @@ omnipresentCallback(WMenu *menu, WMenuEntry *entry) WAppIcon *clickedIcon = entry->clientdata; WAppIcon *aicon; WDock *dock; - LinkedList *selectedIcons; + WMBag *selectedIcons; int failed; + int i; assert(entry->clientdata!=NULL); @@ -491,18 +491,19 @@ omnipresentCallback(WMenu *menu, WMenuEntry *entry) selectedIcons = getSelected(dock); - if (!selectedIcons) - selectedIcons = list_cons(clickedIcon, NULL); + if (!WMGetBagItemCount(selectedIcons)) + WMPutInBag(selectedIcons, clickedIcon); failed = 0; - while (selectedIcons) { - aicon = selectedIcons->head; + for (i = 0; i < WMGetBagItemCount(selectedIcons); i++) { + aicon = WMGetFromBag(selectedIcons, i); + if (wClipMakeIconOmnipresent(aicon, !aicon->omnipresent) == WO_FAILED) failed++; else if (aicon->icon->selected) wIconSelect(aicon->icon); - list_remove_head(&selectedIcons); } + WMFreeBag(selectedIcons); if (failed > 1) { wMessageDialog(dock->screen_ptr, _("Warning"), @@ -530,8 +531,9 @@ removeIconsCallback(WMenu *menu, WMenuEntry *entry) WAppIcon *clickedIcon = (WAppIcon*)entry->clientdata; WDock *dock; WAppIcon *aicon; - LinkedList *selectedIcons; + WMBag *selectedIcons; int keepit; + int i; assert(clickedIcon!=NULL); @@ -539,20 +541,23 @@ removeIconsCallback(WMenu *menu, WMenuEntry *entry) selectedIcons = getSelected(dock); - if (selectedIcons) { + if (WMGetBagItemCount(selectedIcons)) { if (wMessageDialog(dock->screen_ptr, _("Workspace Clip"), _("All selected icons will be removed!"), _("OK"), _("Cancel"), NULL)!=WAPRDefault) { + WMFreeBag(selectedIcons); return; } } else { - if (clickedIcon->xindex==0 && clickedIcon->yindex==0) + if (clickedIcon->xindex==0 && clickedIcon->yindex==0) { + WMFreeBag(selectedIcons); return; - selectedIcons = list_cons(clickedIcon, NULL); + } + WMPutInBag(selectedIcons, clickedIcon); } - while (selectedIcons) { - aicon = selectedIcons->head; + for (i = 0; i < WMGetBagItemCount(selectedIcons); i++) { + aicon = WMGetFromBag(selectedIcons, i); keepit = aicon->running && wApplicationOf(aicon->main_window); wDockDetach(dock, aicon); if (keepit) { @@ -562,8 +567,8 @@ removeIconsCallback(WMenu *menu, WMenuEntry *entry) if (!dock->mapped || dock->collapsed) XMapWindow(dpy, aicon->icon->core->window); } - list_remove_head(&selectedIcons); } + WMFreeBag(selectedIcons); if (wPreferences.auto_arrange_icons) wArrangeIcons(dock->screen_ptr, True); @@ -576,16 +581,18 @@ keepIconsCallback(WMenu *menu, WMenuEntry *entry) WAppIcon *clickedIcon = (WAppIcon*)entry->clientdata; WDock *dock; WAppIcon *aicon; - LinkedList *selectedIcons; + WMBag *selectedIcons; + int i; assert(clickedIcon!=NULL); dock = clickedIcon->dock; selectedIcons = getSelected(dock); - if (!selectedIcons && clickedIcon!=dock->screen_ptr->clip_icon) { + if (!WMGetBagItemCount(selectedIcons) + && clickedIcon!=dock->screen_ptr->clip_icon) { char *command = NULL; - + if (!clickedIcon->command && !clickedIcon->editing) { clickedIcon->editing = 1; if (wInputDialog(dock->screen_ptr, _("Keep Icon"), @@ -602,15 +609,16 @@ keepIconsCallback(WMenu *menu, WMenuEntry *entry) clickedIcon->editing = 0; if (command) free(command); + WMFreeBag(selectedIcons); return; } } - selectedIcons = list_cons(clickedIcon, NULL); + WMPutInBag(selectedIcons, clickedIcon); } - while (selectedIcons) { - aicon = selectedIcons->head; + for (i = 0; i < WMGetBagItemCount(selectedIcons); i++) { + aicon = WMGetFromBag(selectedIcons, i); if (aicon->icon->selected) wIconSelect(aicon->icon); if (aicon && aicon->attracted && aicon->command) { @@ -621,8 +629,8 @@ keepIconsCallback(WMenu *menu, WMenuEntry *entry) wAppIconPaint(aicon); } } - list_remove_head(&selectedIcons); } + WMFreeBag(selectedIcons); } @@ -740,7 +748,7 @@ selectIconsCallback(WMenu *menu, WMenuEntry *entry) { WAppIcon *clickedIcon = (WAppIcon*)entry->clientdata; WDock *dock; - LinkedList *selectedIcons; + WMBag *selectedIcons; WAppIcon *btn; int i; @@ -749,7 +757,7 @@ selectIconsCallback(WMenu *menu, WMenuEntry *entry) selectedIcons = getSelected(dock); - if (!selectedIcons) { + if (!WMGetBagItemCount(selectedIcons)) { for (i=1; imax_icons; i++) { btn = dock->icon_array[i]; if (btn && !btn->icon->selected) { @@ -757,12 +765,12 @@ selectIconsCallback(WMenu *menu, WMenuEntry *entry) } } } else { - while(selectedIcons) { - btn = selectedIcons->head; + for (i = 0; i < WMGetBagItemCount(selectedIcons); i++) { + btn = WMGetFromBag(selectedIcons, i); wIconSelect(btn->icon); - list_remove_head(&selectedIcons); } } + WMFreeBag(selectedIcons); wMenuPaint(menu); } @@ -906,7 +914,7 @@ switchWSCommand(WMenu *menu, WMenuEntry *entry) WAppIcon *btn, *icon = (WAppIcon*) entry->clientdata; WScreen *scr = icon->icon->core->screen_ptr; WDock *src, *dest; - LinkedList *selectedIcons; + WMBag *selectedIcons; int x, y; if (entry->order == scr->current_workspace) @@ -916,14 +924,14 @@ switchWSCommand(WMenu *menu, WMenuEntry *entry) selectedIcons = getSelected(src); - if (selectedIcons) { - while(selectedIcons) { - btn = selectedIcons->head; + if (WMGetBagItemCount(selectedIcons)) { + int i; + for (i = 0; i < WMGetBagItemCount(selectedIcons); i++) { + btn = WMGetFromBag(selectedIcons, i); if (wDockFindFreeSlot(dest, &x, &y)) { moveIconBetweenDocks(src, dest, btn, x, y); XUnmapWindow(dpy, btn->icon->core->window); } - list_remove_head(&selectedIcons); } } else if (icon != scr->clip_icon) { if (wDockFindFreeSlot(dest, &x, &y)) { @@ -931,6 +939,7 @@ switchWSCommand(WMenu *menu, WMenuEntry *entry) XUnmapWindow(dpy, icon->icon->core->window); } } + WMFreeBag(selectedIcons); } @@ -1432,7 +1441,7 @@ dockSaveState(WDock *dock) int i; proplist_t icon_info; proplist_t list=NULL, dock_state=NULL; - proplist_t value; + proplist_t value, key; char buffer[256]; list = PLMakeArrayFromElements(NULL); @@ -1448,18 +1457,25 @@ dockSaveState(WDock *dock) PLRelease(icon_info); } } - - dock_state = PLMakeDictionaryFromEntries(dApplications, list, NULL); - - PLRelease(list); + + dock_state = PLMakeDictionaryFromEntries(dApplications, list, + NULL); if (dock->type == WM_DOCK) { + sprintf(buffer, "Applications%i", dock->screen_ptr->scr_height); + key = PLMakeString(buffer); + PLInsertDictionaryEntry(dock_state, key, list); + PLRelease(key); + + sprintf(buffer, "%i,%i", (dock->on_right_side ? -ICON_SIZE : 0), dock->y_pos); value = PLMakeString(buffer); PLInsertDictionaryEntry(dock_state, dPosition, value); PLRelease(value); } + PLRelease(list); + value = (dock->lowered ? dYes : dNo); PLInsertDictionaryEntry(dock_state, dLowered, value); @@ -1486,12 +1502,36 @@ dockSaveState(WDock *dock) void -wDockSaveState(WScreen *scr) +wDockSaveState(WScreen *scr, proplist_t old_state) { proplist_t dock_state; + proplist_t keys; dock_state = dockSaveState(scr->dock); + /* + * Copy saved states of docks with different sizes. + */ + if (old_state) { + int i; + proplist_t tmp; + + keys = PLGetAllDictionaryKeys(old_state); + for (i = 0; i < PLGetNumberOfElements(keys); i++) { + tmp = PLGetArrayElement(keys, i); + + if (strncasecmp(PLGetString(tmp), "applications", 12) == 0 + && !PLGetDictionaryEntry(dock_state, tmp)) { + + PLInsertDictionaryEntry(dock_state, + tmp, + PLGetDictionaryEntry(old_state, tmp)); + } + } + PLRelease(keys); + } + + PLInsertDictionaryEntry(scr->session_state, dDock, dock_state); PLRelease(dock_state); @@ -1871,8 +1911,29 @@ wDockRestoreState(WScreen *scr, proplist_t dock_state, int type) /* application list */ - - apps = PLGetDictionaryEntry(dock_state, dApplications); + + { + proplist_t tmp; + char buffer[64]; + + /* + * When saving, it saves the dock state in + * Applications and Applicationsnnn + * + * When loading, it will first try Applicationsnnn. + * If it does not exist, use Applications as default. + */ + + sprintf(buffer, "Applications%i", scr->scr_height); + + tmp = PLMakeString(buffer); + apps = PLGetDictionaryEntry(dock_state, tmp); + PLRelease(tmp); + + if (!apps) { + apps = PLGetDictionaryEntry(dock_state, dApplications); + } + } if (!apps) { goto finish; diff --git a/src/dock.h b/src/dock.h index 40463661..db444de0 100644 --- a/src/dock.h +++ b/src/dock.h @@ -79,7 +79,7 @@ void wDockShowIcons(WDock *dock); void wDockLower(WDock *dock); void wDockRaise(WDock *dock); void wDockRaiseLower(WDock *dock); -void wDockSaveState(WScreen *scr); +void wDockSaveState(WScreen *scr, proplist_t old_state); Bool wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y); Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y, diff --git a/src/event.c b/src/event.c index 80dd12b3..9de886b1 100644 --- a/src/event.c +++ b/src/event.c @@ -56,7 +56,7 @@ #include "framewin.h" #include "properties.h" #include "balloon.h" -#include "list.h" + #ifdef GNOME_STUFF # include "gnome.h" #endif @@ -149,11 +149,10 @@ static int deadProcessPtr=0; typedef struct DeathHandler { WDeathHandler *callback; pid_t pid; - struct DeathHandler *next; void *client_data; } DeathHandler; -static DeathHandler *deathHandler=NULL; +static WMBag *deathHandlers=NULL; @@ -165,14 +164,15 @@ wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata) handler = malloc(sizeof(DeathHandler)); if (!handler) return 0; - + handler->pid = pid; handler->callback = callback; handler->client_data = cdata; - - handler->next = deathHandler; - - deathHandler = handler; + + if (!deathHandlers) + deathHandlers = WMCreateBag(8); + + WMPutInBag(deathHandlers, handler); return handler; } @@ -182,34 +182,23 @@ wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata) void wDeleteDeathHandler(WMagicNumber id) { - DeathHandler *tmp, *handler=(DeathHandler*)id; + DeathHandler *handler=(DeathHandler*)id; - if (!handler || !deathHandler) + if (!handler || !deathHandlers) return; - tmp = deathHandler; - if (tmp==handler) { - deathHandler = handler->next; - free(handler); - } else { - while (tmp->next) { - if (tmp->next==handler) { - tmp->next=handler->next; - free(handler); - break; - } - tmp = tmp->next; - } - } + WMRemoveFromBag(deathHandlers, handler); + + free(handler); } void DispatchEvent(XEvent *event) { - if (deathHandler) + if (deathHandlers) handleDeadProcess(NULL); - + if (WCHECK_STATE(WSTATE_NEED_EXIT)) { WCHANGE_STATE(WSTATE_EXITING); /* received SIGTERM */ @@ -232,8 +221,8 @@ DispatchEvent(XEvent *event) * the stuff above */ if (!event) return; - - saveTimestamp(event); + + saveTimestamp(event); switch (event->type) { case MapRequest: handleMapRequest(event); @@ -379,7 +368,7 @@ handleDeadProcess(void *foo) wWindowDeleteSavedStatesForPID(deadProcesses[i].pid); } - if (!deathHandler) { + if (!deathHandlers) { deadProcessPtr=0; return; } @@ -388,11 +377,10 @@ handleDeadProcess(void *foo) while (deadProcessPtr>0) { deadProcessPtr--; - tmp = deathHandler; - while (tmp) { - DeathHandler *t; - - t = tmp->next; + for (i = WMGetBagItemCount(deathHandlers)-1; i >= 0; i--) { + tmp = WMGetFromBag(deathHandlers, i); + if (!tmp) + continue; if (tmp->pid == deadProcesses[deadProcessPtr].pid) { (*tmp->callback)(tmp->pid, @@ -400,7 +388,6 @@ handleDeadProcess(void *foo) tmp->client_data); wDeleteDeathHandler(tmp); } - tmp = t; } } } @@ -474,7 +461,7 @@ handleMapRequest(XEvent *ev) Window window = ev->xmaprequest.window; #ifdef DEBUG - printf("got map request for %x\n", (unsigned)window); + dprintf("got map request for %x\n", (unsigned)window); #endif if ((wwin = wWindowFor(window))) { @@ -553,7 +540,7 @@ handleDestroyNotify(XEvent *event) Window window = event->xdestroywindow.window; #ifdef DEBUG - puts("got destroy notify"); + dputs("got destroy notify"); #endif wwin = wWindowFor(window); @@ -590,7 +577,7 @@ handleExpose(XEvent *event) XEvent ev; #ifdef DEBUG - puts("got expose"); + dputs("got expose"); #endif while (XCheckTypedWindowEvent(dpy, event->xexpose.window, Expose, &ev)); @@ -614,7 +601,7 @@ handleButtonPress(XEvent *event) WScreen *scr; #ifdef DEBUG - puts("got button press"); + dputs("got button press"); #endif scr = wScreenForRootWindow(event->xbutton.root); @@ -721,7 +708,7 @@ handleMapNotify(XEvent *event) WWindow *wwin; #ifdef DEBUG - puts("got map"); + dputs("got map"); #endif wwin = wWindowFor(event->xmap.event); @@ -746,7 +733,7 @@ handleUnmapNotify(XEvent *event) Bool withdraw = False; #ifdef DEBUG - puts("got unmap"); + dputs("got unmap"); #endif /* only process windows with StructureNotify selected @@ -800,7 +787,7 @@ handleConfigureRequest(XEvent *event) WWindow *wwin; #ifdef DEBUG - puts("got configure request"); + dputs("got configure request"); #endif if (!(wwin=wWindowFor(event->xconfigurerequest.window))) { /* @@ -824,7 +811,7 @@ handlePropertyNotify(XEvent *event) WScreen *scr; #ifdef DEBUG - puts("got property notify"); + dputs("got property notify"); #endif if ((wwin=wWindowFor(event->xproperty.window))) { if (!XGetGeometry(dpy, wwin->client_win, &jr, &ji, &ji, @@ -854,7 +841,7 @@ handleClientMessage(XEvent *event) WObjDescriptor *desc; #ifdef DEBUG - puts("got client message"); + dputs("got client message"); #endif /* handle transition from Normal to Iconic state */ if (event->xclient.message_type == _XA_WM_CHANGE_STATE @@ -983,6 +970,7 @@ raiseWindow(WScreen *scr) static void handleEnterNotify(XEvent *event) { + WMenu *menu; WWindow *wwin; WObjDescriptor *desc = NULL; XEvent ev; @@ -990,7 +978,7 @@ handleEnterNotify(XEvent *event) #ifdef DEBUG - puts("got enter notify"); + dputs("got enter notify"); #endif if (XCheckTypedWindowEvent(dpy, event->xcrossing.window, LeaveNotify, @@ -1003,6 +991,28 @@ handleEnterNotify(XEvent *event) } } +/* start my fix scrolled menus */ + if (wPreferences.scrollable_menus) { + if (scr->flags.jump_back_pending || + event->xcrossing.x_root <= 1 || + event->xcrossing.x_root >= (scr->scr_width - 2) || + event->xcrossing.y_root <= 1 || + event->xcrossing.y_root >= (scr->scr_height - 2)) { + +#ifdef DEBUG + debug_puts("pointer at screen edge in EnterNotify event, fear"); +#endif + + menu = wMenuUnderPointer(scr); + if (menu!=NULL) { + wMenuScroll(menu, event); + return; + } + } + } +/* end fix scrolled menus */ + + if (XFindContext(dpy, event->xcrossing.window, wWinContext, (XPointer *)&desc)!=XCNOENT) { if(desc->handle_enternotify) @@ -1120,7 +1130,7 @@ handleShapeNotify(XEvent *event) XEvent ev; #ifdef DEBUG - puts("got shape notify"); + dputs("got shape notify"); #endif while (XCheckTypedWindowEvent(dpy, shev->window, event->type, &ev)) { @@ -1274,6 +1284,7 @@ windowUnderPointer(WScreen *scr) return NULL; } + #ifdef WEENDOZE_CYCLE static WWindow* @@ -1335,6 +1346,8 @@ nextToFocusBefore(WWindow *wwin) return wwin; } + + static void doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) { @@ -1349,7 +1362,7 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) if (!wwin) return; -/* puts("IN");*/ +/* dputs("IN");*/ keymap = XGetModifierMapping(dpy); @@ -1385,7 +1398,7 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) WMHandleEvent(&ev); continue; } -/*puts("EV");*/ +/*dputs("EV");*/ /* ignore CapsLock */ modifiers = ev.xkey.state & ValidModMask; @@ -1426,7 +1439,7 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) } } } -/*puts("OUT");*/ +/*dputs("OUT");*/ XFree(keymap); XUngrabKeyboard(dpy, CurrentTime); @@ -1449,7 +1462,7 @@ handleKeyPress(XEvent *event) WWindow *wwin = scr->focused_window; int i; int modifiers; - int command=-1; + int command=-1, index; #ifdef KEEP_XKB_LOCK_STATUS XkbStateRec staterec; #endif /*KEEP_XKB_LOCK_STATUS*/ @@ -1684,36 +1697,44 @@ handleKeyPress(XEvent *event) case WKBD_WINDOW9: case WKBD_WINDOW10: #endif - if ( scr->shortcutSelectedWindows[command-WKBD_WINDOW1]) { - LinkedList *list = scr->shortcutSelectedWindows[command-WKBD_WINDOW1]; + +#define INITBAG(bag) if (bag) WMEmptyBag(bag); else bag = WMCreateBag(4) + + index = command-WKBD_WINDOW1; + + if (scr->shortcutSelectedWindows[index]) { + WMBag *list = scr->shortcutSelectedWindows[index]; int cw; + int i; wUnselectWindows(scr); - if (scr->shortcutWindow[command-WKBD_WINDOW1]) - wMakeWindowVisible(scr->shortcutWindow[command-WKBD_WINDOW1]); + if (scr->shortcutWindow[index]) + wMakeWindowVisible(scr->shortcutWindow[index]); cw = scr->current_workspace; - while (list) { - wWindowChangeWorkspace(list->head, cw); - wMakeWindowVisible(list->head); - wSelectWindow(list->head, True); - list = list->tail; + for (i = 0; i < WMGetBagItemCount(list); i++) { + WWindow *wwin = WMGetFromBag(list, i); + wWindowChangeWorkspace(wwin, cw); + wMakeWindowVisible(wwin); + wSelectWindow(wwin, True); } - } else if (scr->shortcutWindow[command-WKBD_WINDOW1]){ + } else if (scr->shortcutWindow[index]){ - wMakeWindowVisible(scr->shortcutWindow[command-WKBD_WINDOW1]); + wMakeWindowVisible(scr->shortcutWindow[index]); } else if (wwin && ISMAPPED(wwin) && ISFOCUSED(wwin)) { - scr->shortcutWindow[command-WKBD_WINDOW1] = wwin; - if (wwin->flags.selected /* && scr->selected_windows */ ) { - LinkedList *sl; + scr->shortcutWindow[index] = wwin; + if (wwin->flags.selected && scr->selected_windows) { + WMBag *bag; + int i; - sl = scr->selected_windows; - list_free(scr->shortcutSelectedWindows[command-WKBD_WINDOW1]); + bag = scr->selected_windows; + INITBAG(scr->shortcutSelectedWindows[index]); - while (sl) { - scr->shortcutSelectedWindows[command-WKBD_WINDOW1] = list_cons(sl->head,scr->shortcutSelectedWindows[command-WKBD_WINDOW1]); - sl = sl->tail; + for (i = 0; i < WMGetBagItemCount(bag); i++) { + WWindow *tmp = WMGetFromBag(bag, i); + + WMPutInBag(scr->shortcutSelectedWindows[index], tmp); } } wSelectWindow(wwin, !wwin->flags.selected); @@ -1722,20 +1743,23 @@ handleKeyPress(XEvent *event) wSelectWindow(wwin, !wwin->flags.selected); XFlush(dpy); - } else if (scr->selected_windows) { + } else if (WMGetBagItemCount(scr->selected_windows)) { + + if (wwin->flags.selected && scr->selected_windows) { + WMBag *bag; + int i; - if (wwin->flags.selected /* && scr->selected_windows */ ) { - LinkedList *sl; + bag = scr->selected_windows; + INITBAG(scr->shortcutSelectedWindows[index]); - sl = scr->selected_windows; - list_free(scr->shortcutSelectedWindows[command-WKBD_WINDOW1]); + for (i = 0; i < WMGetBagItemCount(bag); i++) { + WWindow *tmp = WMGetFromBag(bag, i); - while (sl) { - scr->shortcutSelectedWindows[command-WKBD_WINDOW1] = list_cons(sl->head,scr->shortcutSelectedWindows[command-WKBD_WINDOW1]); - sl = sl->tail; + WMPutInBag(scr->shortcutSelectedWindows[index], tmp); } } } +#undef INITBAG break; case WKBD_NEXTWSLAYER: @@ -1805,7 +1829,7 @@ handleMotionNotify(XEvent *event) event->xmotion.y_root >= (scr->scr_height - 2)) { #ifdef DEBUG - puts("pointer at screen edge"); + dputs("pointer at screen edge"); #endif menu = wMenuUnderPointer(scr); diff --git a/src/funcs.h b/src/funcs.h index 6784fe15..d4312299 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -158,4 +158,12 @@ void ExecExitScript(); Bool wFetchName(Display *dpy, Window win, char **winname); Bool wGetIconName(Display *dpy, Window win, char **iconname); + + +/* debugging stuff */ + +void dprintf(char *, ...); +void dputs(char *); + + #endif diff --git a/src/list.c b/src/list.c deleted file mode 100644 index 745ae141..00000000 --- a/src/list.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Generic single linked list to keep various information - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - - -Author: Kresten Krab Thorup - -Many modifications by Alfredo K. Kojima -Some fixes and additions by Dan Pascu - - -This file is part of GNU CC. - -GNU CC 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, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include -#include "list.h" -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#include - -#define xrealloc(ptr, size) wrealloc(ptr, size) - -/* Return a cons cell produced from (head . tail) */ - -INLINE LinkedList* -list_cons(void* head, LinkedList* tail) -{ - LinkedList* cell; - - cell = (LinkedList*)wmalloc(sizeof(LinkedList)); - cell->head = head; - cell->tail = tail; - return cell; -} - -/* Inserts "item" in list using "compare" function to make a sorted list */ - -INLINE void -list_insert_sorted(void* item, LinkedList** list, int (*compare)(void*, void*)) -{ - LinkedList *tmp, *cell; - - cell = (LinkedList*)wmalloc(sizeof(LinkedList)); - cell->head = item; - if ((*list == NULL) || ((*compare)((*list)->head, item) >= 0)) { - cell->tail = *list; - *list = cell; - } else { - tmp = *list; - while (tmp->tail) { - if ((*compare)(tmp->tail->head, item) >= 0) - break; - tmp = tmp->tail; - } - cell->tail = tmp->tail; - tmp->tail = cell; - } -} - -/* Return the length of a list, list_length(NULL) returns zero */ - -INLINE int -list_length(LinkedList* list) -{ - int i = 0; - while(list) - { - i += 1; - list = list->tail; - } - return i; -} - -/* Return the Nth element of LIST, where N count from zero. If N - larger than the list length, NULL is returned */ - -INLINE void* -list_nth(int index, LinkedList* list) -{ - while(index-- != 0) - { - if(list->tail) - list = list->tail; - else - return 0; - } - return list->head; -} - -/* Remove the element at the head by replacing it by its successor */ - -#if 0 -INLINE void -list_remove_head(LinkedList** list) -{ - if (!*list) return; - if ((*list)->tail) - { - LinkedList* tail = (*list)->tail; /* fetch next */ - *(*list) = *tail; /* copy next to list head */ - free(tail); /* free next */ - } - else /* only one element in list */ - { - free(*list); - (*list) = 0; - } -} - -/* Alfredo, is there any reason for the function to be as above, - * instead of the more simple version below? - * The difference is that above function do a copying of the structure - * unlike the below that only changes where list points. - * This makes the above function twice slower, because it copies the - * whole structure, which contains 2 pointers. -Dan. - * - * I don't know. I just copied this file from the gcc distribution - * (I liked the API). One could think that the above function would - * keep the pointer to the list unchanged, while the below would change - * it, but since the list is passed by reference that doesn't make any - * sense. -Alfredo - */ - -#else -INLINE void -list_remove_head(LinkedList** list) -{ - if (!*list) return; - - { - LinkedList* next = (*list)->tail; /* fetch next */ - free(*list); /* free head */ - *list = next; /* update list pointer */ - } -} -#endif - - -/* Remove the element with `car' set to ELEMENT */ -/* -INLINE void -list_remove_elem(LinkedList** list, void* elem) -{ - while (*list) - { - if ((*list)->head == elem) - list_remove_head(list); - *list = (*list ? (*list)->tail : NULL); - } -}*/ - -INLINE LinkedList * -list_remove_elem(LinkedList* list, void* elem) -{ - LinkedList *tmp; - - if (list) { - if (list->head == elem) { - tmp = list->tail; - free(list); - return tmp; - } - list->tail = list_remove_elem(list->tail, elem); - return list; - } - return NULL; -} - - -/* Return element that has ELEM as car */ - -INLINE LinkedList* -list_find(LinkedList* list, void* elem) -{ - while(list) - { - if (list->head == elem) - return list; - list = list->tail; - } - return NULL; -} - -/* Free list (backwards recursive) */ - -INLINE void -list_free(LinkedList* list) -{ - if(list) - { - list_free(list->tail); - free(list); - } -} - -/* Map FUNCTION over all elements in LIST */ - -INLINE void -list_mapcar(LinkedList* list, void(*function)(void*)) -{ - while(list) - { - (*function)(list->head); - list = list->tail; - } -} diff --git a/src/list.h b/src/list.h deleted file mode 100644 index 8335222d..00000000 --- a/src/list.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Generic single linked list to keep various information - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -Author: Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC 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, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#ifndef __LIST_H_ -#define __LIST_H_ - -#include "config.h" -#include "wconfig.h" - - -typedef struct LinkedList { - void *head; - struct LinkedList *tail; -} LinkedList; - -INLINE LinkedList* list_cons(void* head, LinkedList* tail); - -INLINE void list_insert_sorted(void* item, LinkedList** list, - int (*compare)(void*, void*)); - -INLINE int list_length(LinkedList* list); - -INLINE void* list_nth(int index, LinkedList* list); - -INLINE void list_remove_head(LinkedList** list); - -INLINE LinkedList *list_remove_elem(LinkedList* list, void* elem); - -INLINE void list_mapcar(LinkedList* list, void(*function)(void*)); - -INLINE LinkedList*list_find(LinkedList* list, void* elem); - -INLINE void list_free(LinkedList* list); - -#endif diff --git a/src/main.c b/src/main.c index b58e8557..8f6ce605 100644 --- a/src/main.c +++ b/src/main.c @@ -262,9 +262,9 @@ print_help() #endif puts(_(" --no-dock do not open the application Dock")); puts(_(" --no-clip do not open the workspace Clip")); - /* + puts(_(" --locale locale locale to use")); - */ + puts(_(" --visual-id visualid visual id of visual to use")); puts(_(" --static do not update or save configurations")); #ifdef DEBUG @@ -342,7 +342,43 @@ ExecExitScript() } } +#if 0 +char* +getFullPath(char *path) +{ + char buffer[1024]; + char *tmp; + char *basep = (char*)buffer; + + if (*path != '/' && getcwd(buffer, 1023)) { + + for (;;) { + if (strncmp(path, "../", 3)==0) { + path += 3; + basep = strchr(basep, '/'); + if (!basep || *path==0) + break; + } + } + if (*path == '/' || strncmp(path, "./",2)==0) { + tmp = + } + + /* + * path + * ./path + * ../path + * ../../path + */ + + } else { + return wstrappend(path); + } + + return tmp; +} +#endif int main(int argc, char **argv) @@ -358,8 +394,14 @@ main(int argc, char **argv) wsetabort(wAbort); /* for telling WPrefs what's the name of the wmaker binary being ran */ - str = wstrappend("WMAKER_BIN_NAME=", argv[0]); - putenv(str); + { +/* char *tmp; + + tmp = getFullPath(argv[0]);*/ + str = wstrappend("WMAKER_BIN_NAME=", argv[0]); +/* free(tmp);*/ + putenv(str); + } ArgCount = argc; Arguments = argv; @@ -397,7 +439,7 @@ main(int argc, char **argv) printf("Window Maker %s\n", VERSION); exit(0); } else if (strcmp(argv[i], "--global_defaults_path")==0) { - puts(SYSCONFDIR); + printf("%s/WindowMaker\n", SYSCONFDIR); exit(0); #ifdef DEBUG } else if (strcmp(argv[i], "--synchronous")==0) { diff --git a/src/menu.c b/src/menu.c index bd0b1051..20bb572d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -102,35 +102,32 @@ appearanceObserver(void *self, WMNotification *notif) int flags = (int)WMGetNotificationClientData(notif); if (!menu->flags.realized) - return; - + return; + if (WMGetNotificationName(notif) == WNMenuAppearanceSettingsChanged) { - if (flags & WFontSettings) { - menu->flags.realized = 0; - wMenuRealize(menu); - } - if (flags & WTextureSettings) { - if (!menu->flags.brother) - updateTexture(menu); - } - if (flags & (WTextureSettings|WColorSettings)) { - wMenuPaint(menu); - } + if (flags & WFontSettings) { + menu->flags.realized = 0; + wMenuRealize(menu); + } + if (flags & WTextureSettings) { + if (!menu->flags.brother) + updateTexture(menu); + } + if (flags & (WTextureSettings|WColorSettings)) { + wMenuPaint(menu); + } } else if (menu->flags.titled) { - if (flags & WFontSettings) { - menu->flags.realized = 0; - wMenuRealize(menu); - } - if (flags & WTextureSettings) { - menu->frame->flags.need_texture_remake = 1; - } - if (flags & (WColorSettings|WTextureSettings)) { -#ifdef DRAWSTRING_PLUGIN - XClearWindow(dpy, menu->frame->titlebar->window); -#endif - wFrameWindowPaint(menu->frame); - } + if (flags & WFontSettings) { + menu->flags.realized = 0; + wMenuRealize(menu); + } + if (flags & WTextureSettings) { + menu->frame->flags.need_texture_remake = 1; + } + if (flags & (WColorSettings|WTextureSettings)) { + wFrameWindowPaint(menu->frame); + } } } @@ -174,13 +171,13 @@ wMenuCreate(WScreen *screen, char *title, int main_menu) menu->frame = wFrameWindowCreate(screen, tmp, 8, 2, 1, 1, flags, screen->menu_title_texture, NULL, - screen->menu_title_pixel, + screen->menu_title_pixel, #ifdef DRAWSTRING_PLUGIN - W_STRING_MTITLE, + W_STRING_MTITLE, #endif - &screen->menu_title_gc, - &screen->menu_title_font); - + &screen->menu_title_gc, + &screen->menu_title_font); + menu->frame->core->descriptor.parent = menu; menu->frame->core->descriptor.parent_type = WCLASS_MENU; menu->frame->core->descriptor.handle_mousedown = menuMouseDown; @@ -289,7 +286,7 @@ wMenuInsertCallback(WMenu *menu, int index, char *text, #ifdef DEBUG if (!menu) { - printf("Passed NULL as menu parameter to wMenuAddCallback() \n"); + dprintf("Passed NULL as menu parameter to wMenuAddCallback() \n"); return NULL; } #endif @@ -302,7 +299,7 @@ wMenuInsertCallback(WMenu *menu, int index, char *text, if (menu->entry_no >= menu->alloced_entries) { void *tmp; #ifdef DEBUG - puts("doing wrealloc()"); + dputs("doing wrealloc()"); #endif tmp = wrealloc(menu->entries, sizeof(WMenuEntry)*(menu->alloced_entries+5)); @@ -1782,7 +1779,7 @@ wMenuScroll(WMenu *menu, XEvent *event) XEvent ev; #ifdef DEBUG - puts("Entering menu Scroll"); + dputs("Entering menu Scroll"); #endif if (omenu->jump_back) @@ -1808,7 +1805,12 @@ wMenuScroll(WMenu *menu, XEvent *event) WMNextEvent(dpy, &ev); switch (ev.type) { case EnterNotify: +/* + this um causes a nasty crash ugly ugh i dont see *why* we do this, + everything seems fine without it. ( swivel ) WMHandleEvent(&ev); +*/ + break; case MotionNotify: x = (ev.type==MotionNotify) ? ev.xmotion.x_root : ev.xcrossing.x_root; y = (ev.type==MotionNotify) ? ev.xmotion.y_root : ev.xcrossing.y_root; @@ -1888,7 +1890,7 @@ wMenuScroll(WMenu *menu, XEvent *event) #ifdef DEBUG - puts("Leaving menu Scroll"); + dputs("Leaving menu Scroll"); #endif } @@ -2233,14 +2235,15 @@ wMenuMove(WMenu *menu, int x, int y, int submenus) if (i>=0 && menu->cascades) { submenu = menu->cascades[i]; - if (submenu->flags.mapped && !submenu->flags.buttoned) - if (wPreferences.align_menus) { - wMenuMove(submenu, x + MENUW(menu), y, submenus); - } else { - wMenuMove(submenu, x+ MENUW(menu), - y + submenu->entry_height*menu->selected_entry, - submenus); - } + if (submenu->flags.mapped && !submenu->flags.buttoned) { + if (wPreferences.align_menus) { + wMenuMove(submenu, x + MENUW(menu), y, submenus); + } else { + wMenuMove(submenu, x+ MENUW(menu), + y + submenu->entry_height*menu->selected_entry, + submenus); + } + } } } if (submenus<0 && menu->parent!=NULL && menu->parent->flags.mapped && @@ -2311,7 +2314,7 @@ menuTitleMouseDown(WCoreWindow *sender, void *data, XEvent *event) Bool started; #ifdef DEBUG - printf("Moving menu\n"); + dprintf("Moving menu\n"); #endif /* can't touch the menu copy */ @@ -2398,7 +2401,7 @@ menuTitleMouseDown(WCoreWindow *sender, void *data, XEvent *event) if (ev.xbutton.button != event->xbutton.button) break; #ifdef DEBUG - printf("End menu move\n"); + dprintf("End menu move\n"); #endif XUngrabPointer(dpy, CurrentTime); return; diff --git a/src/misc.c b/src/misc.c index 6f3f79b4..682533bd 100644 --- a/src/misc.c +++ b/src/misc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,6 @@ #include "xutil.h" #include "xmodifier.h" -#include "list.h" /**** global variables *****/ @@ -682,26 +682,26 @@ next_token(char *word, char **next) void ParseCommand(char *command, char ***argv, int *argc) { - LinkedList *list = NULL; + WMBag *bag = WMCreateBag(4); char *token, *line; - int count, i; + int count, j; line = command; do { token = next_token(line, &line); - if (token) { - list = list_cons(token, list); + if (token) { + WMPutInBag(bag, token); } } while (token!=NULL && line!=NULL); - count = list_length(list); + count = WMGetBagItemCount(bag); *argv = wmalloc(sizeof(char*)*count); - i = count; - while (list!=NULL) { - (*argv)[--i] = list->head; - list_remove_head(&list); + for (j = 0; j < count; j++) { + (*argv)[j] = WMGetFromBag(bag, j); } *argc = count; + + WMFreeBag(bag); } #if 0 @@ -1387,6 +1387,34 @@ SendHelperMessage(WScreen *scr, char type, int workspace, char *msg) } + +typedef struct { + WScreen *scr; + char *command; +} _tuple; + + +static void +shellCommandHandler(pid_t pid, unsigned char status, _tuple *data) +{ + if (status == 127) { + char *buffer; + + buffer = wstrappend(_("Could not execute command: "), data->command); + + wMessageDialog(data->scr, _("Error"), buffer, _("OK"), NULL, NULL); + free(buffer); + } else if (status != 127) { + /* + printf("%s: %i\n", data->command, status); + */ + } + + free(data->command); + free(data); +} + + void ExecuteShellCommand(WScreen *scr, char *command) { @@ -1406,6 +1434,7 @@ ExecuteShellCommand(WScreen *scr, char *command) shell = "/bin/sh"; pid = fork(); + if (pid==0) { SetupEnvironment(scr); @@ -1418,5 +1447,35 @@ ExecuteShellCommand(WScreen *scr, char *command) Exit(-1); } else if (pid < 0) { wsyserror("cannot fork a new process"); + } else { + _tuple *data = wmalloc(sizeof(_tuple)); + + data->scr = scr; + data->command = wstrdup(command); + + wAddDeathHandler(pid, (WDeathHandler*)shellCommandHandler, data); } } + + + + + +void dprintf(char *format, ...) +{ + va_list args; + + va_start(args, format); + vprintf(format, args); + fflush(stdout); + va_end(args); +} + + + +void dputs(char *text) +{ + puts(text); + fflush(stdout); +} + diff --git a/src/moveres.c b/src/moveres.c index 3d872180..26b9baf2 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -40,7 +40,6 @@ #include "actions.h" #include "workspace.h" -#include "list.h" #ifdef KWM_HINTS #include "kwm.h" @@ -327,7 +326,7 @@ showGeometry(WWindow *wwin, int x1, int y1, int x2, int y2, int direction) /* Display the width. */ WMDrawString(scr->wmscreen, root, gc, scr->info_text_font, - mx - fw/2 + 1, y - s + fh/2 + 1, num, strlen(num)); + mx - fw/2 + 1, y - s - fh/2 + 1, num, strlen(num)); } else { XClearArea(dpy, scr->geometry_display, 1, 1, scr->geometry_display_width-2, scr->geometry_display_height-2, @@ -402,18 +401,19 @@ XUnmapWindow(dpy, (w)->screen_ptr->geometry_display); static void -doWindowMove(WWindow *wwin, LinkedList *list, int dx, int dy) +doWindowMove(WWindow *wwin, WMBag *bag, int dx, int dy) { WWindow *tmpw; int x, y; int scr_width = wwin->screen_ptr->scr_width; int scr_height = wwin->screen_ptr->scr_height; - if (!list) { + if (!bag || !WMGetBagItemCount(bag)) { wWindowMove(wwin, wwin->frame_x + dx, wwin->frame_y + dy); } else { - while (list) { - tmpw = list->head; + int i; + for (i = 0; i < WMGetBagItemCount(bag); i++) { + tmpw = WMGetFromBag(bag, i); x = tmpw->frame_x + dx; y = tmpw->frame_y + dy; @@ -430,7 +430,6 @@ doWindowMove(WWindow *wwin, LinkedList *list, int dx, int dy) y = scr_height - 20; wWindowMove(tmpw, x, y); - list = list->tail; } } } @@ -467,14 +466,14 @@ drawTransparentFrame(WWindow *wwin, int x, int y, int width, int height) static void -drawFrames(WWindow *wwin, LinkedList *list, int dx, int dy) +drawFrames(WWindow *wwin, WMBag *bag, int dx, int dy) { WWindow *tmpw; int scr_width = wwin->screen_ptr->scr_width; int scr_height = wwin->screen_ptr->scr_height; int x, y; - if (!list) { + if (!bag) { x = wwin->frame_x + dx; y = wwin->frame_y + dy; @@ -484,8 +483,9 @@ drawFrames(WWindow *wwin, LinkedList *list, int dx, int dy) wwin->frame->core->height); } else { - while (list) { - tmpw = list->head; + int i; + for (i = 0; i < WMGetBagItemCount(bag); i++) { + tmpw = WMGetFromBag(bag, i); x = tmpw->frame_x + dx; y = tmpw->frame_y + dy; @@ -503,8 +503,6 @@ drawFrames(WWindow *wwin, LinkedList *list, int dx, int dy) drawTransparentFrame(tmpw, x, y, tmpw->frame->core->width, tmpw->frame->core->height); - - list = list->tail; } } } @@ -957,14 +955,12 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, int t_edge, b_edge; int edge_t, edge_b; int resist; - WWindow *rwin; - WWindow *rrwin; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - attract = wPreferences.attract; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + attract = wPreferences.attract; /* horizontal movement: check horizontal edge resistances */ if (dx || dy) { - int i; + int i; /* window is the leftmost window: check against screen edge */ l_edge = scr->totalUsableArea.x1; r_edge = scr->totalUsableArea.x2 + resist; @@ -973,208 +969,210 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, /* 1 */ if ((data->rightIndex >= 0) && (data->rightIndex <= data->count)) { - WWindow *looprw; + WWindow *looprw; - for (i = data->rightIndex - 1; i >= 0; i--) { - looprw = data->rightList[i]; - if (!(data->realY > WBOTTOM(looprw) - || (data->realY + data->winHeight) < WTOP(looprw))) { - if (attract || (data->realX < (WRIGHT(looprw) + 2)) && dx < 0) { - l_edge = WRIGHT(looprw) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - break; - } - } - - if (attract) { - for (i = data->rightIndex; i < data->count; i++) { - looprw = data->rightList[i]; - if(!(data->realY > WBOTTOM(looprw) - || (data->realY + data->winHeight) < WTOP(looprw))) { - r_edge = WRIGHT(looprw) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - break; - } - } - } - } - + for (i = data->rightIndex - 1; i >= 0; i--) { + looprw = data->rightList[i]; + if (!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + if (attract + || ((data->realX < (WRIGHT(looprw) + 2)) && dx < 0)) { + l_edge = WRIGHT(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) { + for (i = data->rightIndex; i < data->count; i++) { + looprw = data->rightList[i]; + if(!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + r_edge = WRIGHT(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + } + if ((data->leftIndex >= 0) && (data->leftIndex <= data->count)) { - WWindow *looprw; + WWindow *looprw; - for (i = data->leftIndex - 1; i >= 0; i--) { - looprw = data->leftList[i]; - if (!(data->realY > WBOTTOM(looprw) - || (data->realY + data->winHeight) < WTOP(looprw))) { - if (attract || ((data->realX + data->winWidth) > (WLEFT(looprw) - 1)) && dx > 0) { - edge_r = WLEFT(looprw); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - break; - } - } - - if (attract) - for (i = data->leftIndex; i < data->count; i++) { - looprw = data->leftList[i]; - if(!(data->realY > WBOTTOM(looprw) - || (data->realY + data->winHeight) < WTOP(looprw))) { - edge_l = WLEFT(looprw); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - break; - } - } - } - - /* + for (i = data->leftIndex - 1; i >= 0; i--) { + looprw = data->leftList[i]; + if (!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + if (attract + || (((data->realX + data->winWidth) > (WLEFT(looprw) - 1)) && dx > 0)) { + edge_r = WLEFT(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) + for (i = data->leftIndex; i < data->count; i++) { + looprw = data->leftList[i]; + if(!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + edge_l = WLEFT(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + + /* printf("%d %d\n",winL,winR); printf("l_ %d r_ %d _l %d _r %d\n",l_edge,r_edge,edge_l,edge_r); */ - if ((winL - l_edge) < (r_edge - winL)) { - if (resist > 0) { - if ((attract && winL <= l_edge + resist && winL >= l_edge - resist) - || (dx < 0 && winL <= l_edge && winL >= l_edge - resist)) { - newX = l_edge; - hresist = True; - } - } - } - else { - if (resist > 0 && attract && winL >= r_edge - resist && winL <= r_edge + resist) { - newX = r_edge; - hresist = True; - } - } - - if ((winR - edge_l) < (edge_r - winR)) { - if (resist > 0 && attract && winR <= edge_l + resist && winR >= edge_l - resist) { - newX = edge_l - data->winWidth; - hresist = True; - } - } - else { - if (resist > 0) { - if ((attract && winR >= edge_r - resist && winR <= edge_r + resist) - || (dx > 0 && winR >= edge_r && winR <= edge_r + resist)) { - newX = edge_r - data->winWidth; - hresist = True; - } - } - } + if ((winL - l_edge) < (r_edge - winL)) { + if (resist > 0) { + if ((attract && winL <= l_edge + resist && winL >= l_edge - resist) + || (dx < 0 && winL <= l_edge && winL >= l_edge - resist)) { + newX = l_edge; + hresist = True; + } + } + } else { + if (resist > 0 && attract && winL >= r_edge - resist && winL <= r_edge + resist) { + newX = r_edge; + hresist = True; + } + } + + if ((winR - edge_l) < (edge_r - winR)) { + if (resist > 0 && attract && winR <= edge_l + resist && winR >= edge_l - resist) { + newX = edge_l - data->winWidth; + hresist = True; + } + } else { + if (resist > 0) { + if ((attract && winR >= edge_r - resist && winR <= edge_r + resist) + || (dx > 0 && winR >= edge_r && winR <= edge_r + resist)) { + newX = edge_r - data->winWidth; + hresist = True; + } + } + } - /* VeRT */ + /* VeRT */ t_edge = scr->totalUsableArea.y1; b_edge = scr->totalUsableArea.y2 + resist; edge_t = scr->totalUsableArea.y1 - resist; edge_b = scr->totalUsableArea.y2; if ((data->bottomIndex >= 0) && (data->bottomIndex <= data->count)) { - WWindow *looprw; - - for (i = data->bottomIndex - 1; i >= 0; i--) { - looprw = data->bottomList[i]; - if (!(data->realX > WRIGHT(looprw) - || (data->realX + data->winWidth) < WLEFT(looprw))) { - if (attract || (data->realY < (WBOTTOM(looprw) + 2)) && dy < 0) { - t_edge = WBOTTOM(looprw) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - break; - } - } - - if (attract) { - for (i = data->bottomIndex; i < data->count; i++) { - looprw = data->bottomList[i]; - if(!(data->realX > WRIGHT(looprw) - || (data->realX + data->winWidth) < WLEFT(looprw))) { - b_edge = WBOTTOM(looprw) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - break; - } - } - } - } - + WWindow *looprw; + + for (i = data->bottomIndex - 1; i >= 0; i--) { + looprw = data->bottomList[i]; + if (!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + if (attract + || ((data->realY < (WBOTTOM(looprw) + 2)) && dy < 0)) { + t_edge = WBOTTOM(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) { + for (i = data->bottomIndex; i < data->count; i++) { + looprw = data->bottomList[i]; + if(!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + b_edge = WBOTTOM(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + } + if ((data->topIndex >= 0) && (data->topIndex <= data->count)) { - WWindow *looprw; - - for (i = data->topIndex - 1; i >= 0; i--) { - looprw = data->topList[i]; - if (!(data->realX > WRIGHT(looprw) - || (data->realX + data->winWidth) < WLEFT(looprw))) { - if (attract || ((data->realY + data->winHeight) > (WTOP(looprw) - 1)) && dy > 0) { - edge_b = WTOP(looprw); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - break; - } - } - - if (attract) - for (i = data->topIndex; i < data->count; i++) { - looprw = data->topList[i]; - if(!(data->realX > WRIGHT(looprw) - || (data->realX + data->winWidth) < WLEFT(looprw))) { - edge_t = WTOP(looprw); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - break; - } - } - } - - if ((winT - t_edge) < (b_edge - winT)) { - if (resist > 0) { - if ((attract && winT <= t_edge + resist && winT >= t_edge - resist) - || (dy < 0 && winT <= t_edge && winT >= t_edge - resist)) { - newY = t_edge; - vresist = True; - } - } - } - else { - if (resist > 0 && attract && winT >= b_edge - resist && winT <= b_edge + resist) { - newY = b_edge; - vresist = True; - } - } - - if ((winB - edge_t) < (edge_b - winB)) { - if (resist > 0 && attract && winB <= edge_t + resist && winB >= edge_t - resist) { - newY = edge_t - data->winHeight; - vresist = True; - } - } - else { - if (resist > 0) { - if ((attract && winB >= edge_b - resist && winB <= edge_b + resist) - || (dy > 0 && winB >= edge_b && winB <= edge_b + resist)) { - newY = edge_b - data->winHeight; - vresist = True; - } - } - } + WWindow *looprw; + + for (i = data->topIndex - 1; i >= 0; i--) { + looprw = data->topList[i]; + if (!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + if (attract + || (((data->realY + data->winHeight) > (WTOP(looprw) - 1)) && dy > 0)) { + edge_b = WTOP(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) + for (i = data->topIndex; i < data->count; i++) { + looprw = data->topList[i]; + if(!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + edge_t = WTOP(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + + if ((winT - t_edge) < (b_edge - winT)) { + if (resist > 0) { + if ((attract && winT <= t_edge + resist && winT >= t_edge - resist) + || (dy < 0 && winT <= t_edge && winT >= t_edge - resist)) { + newY = t_edge; + vresist = True; + } + } + } + else { + if (resist > 0 && attract && winT >= b_edge - resist && winT <= b_edge + resist) { + newY = b_edge; + vresist = True; + } + } + + if ((winB - edge_t) < (edge_b - winB)) { + if (resist > 0 && attract && winB <= edge_t + resist && winB >= edge_t - resist) { + newY = edge_t - data->winHeight; + vresist = True; + } + } + else { + if (resist > 0) { + if ((attract && winB >= edge_b - resist && winB <= edge_b + resist) + || (dy > 0 && winB >= edge_b && winB <= edge_b + resist)) { + newY = edge_b - data->winHeight; + vresist = True; + } + } + } } - /* END VeRT */ - + /* END VeRT */ + } - + /* update window position */ data->calcX += dx; data->calcY += dy; - + if (((dx > 0 && data->calcX - data->realX > 0) || (dx < 0 && data->calcX - data->realX < 0)) && !hresist) newX = data->calcX; - + if (((dy > 0 && data->calcY - data->realY > 0) || (dy < 0 && data->calcY - data->realY < 0)) && !vresist) newY = data->calcY; - + if (data->realX != newX || data->realY != newY) { - + if (wPreferences.move_display == WDIS_NEW && !scr->selected_windows) { showPosition(wwin, data->realX, data->realY); @@ -1192,24 +1190,24 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, if (!scr->selected_windows && wPreferences.move_display == WDIS_FRAME_CENTER) { - + moveGeometryDisplayCentered(scr, newX + data->winWidth/2, newY + data->winHeight/2); } - + if (!opaqueMove) { /* draw frames */ drawFrames(wwin, scr->selected_windows, newX - wwin->frame_x, newY - wwin->frame_y); } - + if (!scr->selected_windows) { showPosition(wwin, newX, newY); } } - - + + /* recalc relative window position */ if (doResistance && (data->realX != newX || data->realY != newY)) { updateResistance(wwin, data, newX, newY); @@ -1482,16 +1480,16 @@ wKeyboardMoveResizeWindow(WWindow *wwin) if(done==2) { if (wwin->flags.shaded || scr->selected_windows) { - LinkedList *list; - list=scr->selected_windows; - if (!scr->selected_windows) { + WMBag *bag; + bag=scr->selected_windows; + if (!WMGetBagItemCount(scr->selected_windows)) { wWindowMove(wwin, src_x+off_x, src_y+off_y); wWindowSynthConfigureNotify(wwin); } else { + int i; doWindowMove(wwin,scr->selected_windows,off_x,off_y); - while (list) { - wWindowSynthConfigureNotify(list->head); - list = list->tail; + for (i = 0; i < WMGetBagItemCount(bag); i++) { + wWindowSynthConfigureNotify(WMGetFromBag(bag, i)); } } } else { @@ -2036,14 +2034,19 @@ void wUnselectWindows(WScreen *scr) { WWindow *wwin; + + if (!scr->selected_windows) + return; - while (scr->selected_windows) { - wwin = scr->selected_windows->head; + while (WMGetBagItemCount(scr->selected_windows)) { + wwin = WMGetFromBag(scr->selected_windows, 0); if (wwin->flags.miniaturized && wwin->icon && wwin->icon->selected) wIconSelect(wwin->icon); wSelectWindow(wwin, False); } + WMFreeBag(scr->selected_windows); + scr->selected_windows = NULL; } #ifndef LITE diff --git a/src/placement.c b/src/placement.c index 6f009ef2..7ebde181 100644 --- a/src/placement.c +++ b/src/placement.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "WindowMaker.h" #include "wcore.h" @@ -39,7 +40,6 @@ #include "appicon.h" #include "dock.h" -#include "list.h" extern WPreferences wPreferences; @@ -252,115 +252,163 @@ PlaceIcon(WScreen *scr, int *x_ret, int *y_ret) } -static Bool +/* + * This function calculates the length of the intersection of two + * line sections. (Hey, is that english?) + */ +static int +calcIntersectionLength(int p1, int l1, int p2, int l2) +{ + int isect; + int tmp; + + if (p1 > p2) { + tmp = p1; + p1 = p2; + p2 = tmp; + tmp = l1; + l1 = l2; + l2 = tmp; + } + + if (p1 + l1 < p2) + isect = 0; + else if (p2 + l2 < p1 + l1) + isect = l2; + else + isect = p1 + l1 - p2; + + return isect; +} + + +/* + * This function calculates the area of the intersection of two rectangles. + */ +static int +calcIntersectionArea(int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) +{ + return calcIntersectionLength(x1, w1, x2, w2) + * calcIntersectionLength(y1, h1, y2, h2); +} + + +static int +calcSumOfCoveredAreas(WWindow *wwin, int x, int y, int w, int h) +{ + int sum_isect = 0; + WWindow *test_window; + int tw,tx,ty,th; + + test_window = wwin->screen_ptr->focused_window; + for(;test_window != NULL && test_window->prev != NULL;) + test_window = test_window->prev; + + for(; test_window != NULL; test_window = test_window->next) { + if (test_window->frame->core->stacking->window_level + < WMNormalLevel) { + continue; + } + +#if 0 + tw = test_window->client.width; + if (test_window->flags.shaded) + th = test_window->frame->top_width; + else + th = test_window->client.height + extra_height; +#else + tw = test_window->frame->core->width; + th = test_window->frame->core->height; +#endif + tx = test_window->frame_x; + ty = test_window->frame_y; + + if (test_window->flags.mapped || + (test_window->flags.shaded && + !(test_window->flags.miniaturized || + test_window->flags.hidden))) { + sum_isect += calcIntersectionArea(tx, ty, tw, th, x, y, w, h); + } + } + + return sum_isect; +} + + +static void smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, - unsigned int width, unsigned int height, int tryCount) + unsigned int width, unsigned int height) { WScreen *scr = wwin->screen_ptr; int test_x = 0, test_y = Y_ORIGIN(scr); - int loc_ok = False, tw,tx,ty,th; - int swidth, sx; - WWindow *test_window; + int from_x, to_x, from_y, to_y; + int sx; + int min_isect, min_isect_x, min_isect_y; + int sum_isect; int extra_height; WArea usableArea = scr->totalUsableArea; - + if (wwin->frame) - extra_height = wwin->frame->top_width + wwin->frame->bottom_width + 2; + extra_height = wwin->frame->top_width + wwin->frame->bottom_width; else - extra_height = 24; /* random value */ + extra_height = 24; /* random value */ - swidth = usableArea.x2-usableArea.x1; sx = X_ORIGIN(scr); - /* this was based on fvwm2's smart placement */ - + min_isect = INT_MAX; + min_isect_x = sx; + min_isect_y = test_y; + height += extra_height; - while (((test_y + height) < (scr->scr_height)) && (!loc_ok)) { + while (((test_y + height) < usableArea.y2)) { test_x = sx; - while (((test_x + width) < swidth) && (!loc_ok)) { + while ((test_x + width) < usableArea.x2) { - loc_ok = True; - test_window = scr->focused_window; + sum_isect = calcSumOfCoveredAreas(wwin, test_x, test_y, + width, height); - while ((test_window != NULL) && (loc_ok == True)) { - - if (test_window->frame->core->stacking->window_level - < WMNormalLevel && tryCount > 0) { - test_window = test_window->next; - continue; - } -#if 0 - tw = test_window->client.width; - if (test_window->flags.shaded) - th = test_window->frame->top_width; - else - th = test_window->client.height + extra_height; -#else - tw = test_window->frame->core->width; - th = test_window->frame->core->height; -#endif - tx = test_window->frame_x; - ty = test_window->frame_y; - - if ((tx < (test_x + width)) && ((tx + tw) > test_x) && - (ty < (test_y + height)) && ((ty + th) > test_y) && - (test_window->flags.mapped || - (test_window->flags.shaded && - !(test_window->flags.miniaturized || - test_window->flags.hidden)))) { - - loc_ok = False; - } - test_window = test_window->next; - } - - test_window = scr->focused_window; - - while ((test_window != NULL) && (loc_ok == True)) { - - if (test_window->frame->core->stacking->window_level - < WMNormalLevel && tryCount > 0) { - test_window = test_window->prev; - continue; - } -#if 0 - tw = test_window->client.width; - if (test_window->flags.shaded) - th = test_window->frame->top_width; - else - th = test_window->client.height + extra_height; -#else - tw = test_window->frame->core->width; - th = test_window->frame->core->height; -#endif - tx = test_window->frame_x; - ty = test_window->frame_y; - - if ((tx < (test_x + width)) && ((tx + tw) > test_x) && - (ty < (test_y + height)) && ((ty + th) > test_y) && - (test_window->flags.mapped || - (test_window->flags.shaded && - !(test_window->flags.miniaturized || - test_window->flags.hidden)))) { - - loc_ok = False; - } - test_window = test_window->prev; - } - if (loc_ok == True) { - *x_ret = test_x; - *y_ret = test_y; - break; + if ( sum_isect < min_isect ) { + min_isect = sum_isect; + min_isect_x = test_x; + min_isect_y = test_y; } + test_x += PLACETEST_HSTEP; } test_y += PLACETEST_VSTEP; } - return loc_ok; + from_x = min_isect_x - PLACETEST_HSTEP + 1; + from_x = WMAX(from_x, X_ORIGIN(scr)); + to_x = min_isect_x + PLACETEST_HSTEP; + if (to_x + width > usableArea.x2) + to_x = usableArea.x2 - width; + + from_y = min_isect_y - PLACETEST_VSTEP + 1; + from_y = WMAX(from_y, Y_ORIGIN(scr)); + to_y = min_isect_y + PLACETEST_VSTEP; + if (to_y + height > usableArea.y2) + to_y = usableArea.y2 - height; + + for (test_x = from_x; test_x < to_x; test_x++) { + for (test_y = from_y; test_y < to_y; test_y++) { + sum_isect = calcSumOfCoveredAreas(wwin, test_x, test_y, + width, height); + + if ( sum_isect < min_isect ) { + min_isect = sum_isect; + min_isect_x = test_x; + min_isect_y = test_y; + } + } + } + + *x_ret = min_isect_x; + *y_ret = min_isect_y; } @@ -401,14 +449,8 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, break; case WPM_SMART: - if (smartPlaceWindow(wwin, x_ret, y_ret, width, height, 0)) { - break; - } else if (smartPlaceWindow(wwin, x_ret, y_ret, width, height, 1)) { - break; - } - /* there isn't a break here, because if we fail, it should fall - through to cascade placement, as people who want tiling want - automagicness aren't going to want to place their window */ + smartPlaceWindow(wwin, x_ret, y_ret, width, height); + break; case WPM_CASCADE: if (wPreferences.window_placement == WPM_SMART) diff --git a/src/plugin.c b/src/plugin.c index 0875b05d..ebd40dcd 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -26,6 +26,8 @@ #include "plugin.h" +#include +#include #include #ifdef TEXTURE_PLUGIN @@ -37,18 +39,20 @@ #include -void** wPluginPackInitData(int members, ...) { +void** +wPluginPackInitData(int members, ...) +{ void **p; va_list vp; int i; p = wmalloc(sizeof(void *) * (members + 1)); - bzero(p, sizeof(void *) * (members + 1)); + memset(p, 0, sizeof(void *) * (members + 1)); va_start(vp, members); for(i=0;i %d\n",i,p[i]); + printf(" %d > %d\n",i,(int)p[i]); } - printf(" s> %s\n",p[2]); + printf(" s> %s\n",(char*)p[2]); va_end(vp); return p; } @@ -56,12 +60,13 @@ void** wPluginPackInitData(int members, ...) { WFunction * wPluginCreateFunction(int type, char *library_name, char *init_proc_name, char *proc_name, char *free_data_proc_name, - proplist_t pl_arg, void *init_data) { + proplist_t pl_arg, void *init_data) +{ WFunction *function; _DL_InitDataProc *initProc; function = wmalloc(sizeof(WFunction)); - bzero(function, sizeof(WFunction)); + memset(function, 0, sizeof(WFunction)); function->handle = dlopen(library_name, RTLD_LAZY); if (!function->handle) { @@ -108,8 +113,11 @@ wPluginCreateFunction(int type, char *library_name, } void -wPluginDestroyFunction(WFunction *function) { - if (!function) return; +wPluginDestroyFunction(WFunction *function) +{ + if (!function) + return; + if (function->data) { if (function->freeData) { function->freeData(&function->data); diff --git a/src/rootmenu.c b/src/rootmenu.c index 0d04d4e7..2c9c8124 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -55,7 +55,6 @@ #include "xmodifier.h" #include -#include "list.h" extern char *Locale; @@ -603,7 +602,7 @@ static void separateCommand(char *line, char ***file, char **command) { char *token, *tmp = line; - LinkedList *list = NULL; + WMBag *bag = WMCreateBag(4); int count, i; *file = NULL; @@ -618,20 +617,21 @@ separateCommand(char *line, char ***file, char **command) wwarning(_("%s: missing command"), line); break; } - list = list_cons(token, list); + WMPutInBag(bag, token); } } while (token!=NULL && tmp!=NULL); - count = list_length(list); + count = WMGetBagItemCount(bag); if (count>0) { + int j; *file = wmalloc(sizeof(char*)*(count+1)); i = count; (*file)[count] = NULL; - while (list!=NULL) { - (*file)[--i] = list->head; - list_remove_head(&list); + for (j = 0; j < count; j++) { + (*file)[--i] = WMGetFromBag(bag, j); } } + WMFreeBag(bag); } @@ -1304,11 +1304,15 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) struct stat stat_buf; WMenu *menu=NULL; char *buffer; - LinkedList *dirs = NULL, *files = NULL; + WMBag *dirs = NULL, *files = NULL; int length, i, have_space=0; dir_data *data; int stripExtension = 0; + + dirs = WMCreateBag(16); + files = WMCreateBag(16); + i=0; while (path[i]!=NULL) { if (strcmp(path[i], "-noext")==0) { @@ -1361,7 +1365,7 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) data->name = wstrdup(dentry->d_name); data->index = i; - list_insert_sorted(data, &dirs, (int(*)())myCompare); + WMPutInBag(dirs, data); } } else if (S_ISREG(stat_buf.st_mode) || isFilePack) { /* Hack because access always returns X_OK success for user root */ @@ -1374,7 +1378,7 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) data->name = wstrdup(dentry->d_name); data->index = i; - list_insert_sorted(data, &files, (int(*)())myCompare); + WMPutInBag(files, data); } } } @@ -1384,17 +1388,23 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) closedir(dir); i++; } - - if (!dirs && !files) + + if (!WMGetBagItemCount(dirs) && !WMGetBagItemCount(files)) { + WMFreeBag(dirs); + WMFreeBag(files); return NULL; + } + + WMSortBag(dirs, myCompare); + WMSortBag(files, myCompare); menu = wMenuCreate(scr, title, False); menu->on_destroy = removeShortcutsForMenu; - - while (dirs != NULL) { + + for (i = 0; i < WMGetBagItemCount(dirs); i++) { /* New directory. Use same OPEN_MENU command that was used * for the current directory. */ - dir_data *d = (dir_data*)dirs->head; + dir_data *d = (dir_data*)WMGetFromBag(dirs, i); length = strlen(path[d->index])+strlen(d->name)+6; if (command) @@ -1427,17 +1437,14 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) addMenuEntry(menu, d->name, NULL, "OPEN_MENU", buffer, path[d->index]); free(buffer); - if (dirs->head) { - if (d->name) - free(d->name); - free(dirs->head); - } - list_remove_head(&dirs); + if (d->name) + free(d->name); + free(d); } - while (files != NULL) { + for (i = 0; i < WMGetBagItemCount(files); i++) { /* executable: add as entry */ - dir_data *f = (dir_data*) files->head;; + dir_data *f = (dir_data*)WMGetFromBag(files, i); length = strlen(path[f->index])+strlen(f->name)+6; if (command) @@ -1480,13 +1487,13 @@ readMenuDirectory(WScreen *scr, char *title, char **path, char *command) addMenuEntry(menu, f->name, NULL, "SHEXEC", buffer, path[f->index]); free(buffer); - if (files->head) { - if (f->name) - free(f->name); - free(files->head); - } - list_remove_head(&files); + if (f->name) + free(f->name); + free(f); } + + WMFreeBag(files); + WMFreeBag(dirs); return menu; } diff --git a/src/screen.c b/src/screen.c index bcb5973c..4e6d5dc3 100644 --- a/src/screen.c +++ b/src/screen.c @@ -681,7 +681,7 @@ wScreenInit(int screen_number) scr = wmalloc(sizeof(WScreen)); memset(scr, 0, sizeof(WScreen)); - + /* initialize globals */ scr->screen = screen_number; scr->root_win = RootWindow(dpy, screen_number); @@ -853,11 +853,6 @@ wScreenInit(int screen_number) wScreenUpdateUsableArea(scr); -#ifndef LITE - /* kluge to load menu configurations at startup */ - OpenRootMenu(scr, -10000, -10000, False); - wMenuUnmap(scr->root_menu); -#endif return scr; } @@ -990,6 +985,12 @@ wScreenRestoreState(WScreen *scr) proplist_t state; char *path; + +#ifndef LITE + OpenRootMenu(scr, -10000, -10000, False); + wMenuUnmap(scr->root_menu); +#endif + make_keys(); if (wScreenCount == 1) @@ -1068,7 +1069,7 @@ wScreenSaveState(WScreen *scr) /* save dock state to file */ if (!wPreferences.flags.nodock) { - wDockSaveState(scr); + wDockSaveState(scr, old_state); } else { if ((foo = PLGetDictionaryEntry(old_state, dDock))!=NULL) { PLInsertDictionaryEntry(scr->session_state, dDock, foo); diff --git a/src/screen.h b/src/screen.h index 003fdc78..78a27a6c 100644 --- a/src/screen.h +++ b/src/screen.h @@ -92,7 +92,7 @@ typedef struct _WScreen { * traverse the entire window list */ - struct LinkedList *selected_windows; + WMBag *selected_windows; struct WAppIcon *app_icon_list; /* list of all app-icons on screen */ @@ -282,7 +282,7 @@ typedef struct _WScreen { /* for window shortcuts */ struct WWindow *shortcutWindow[MAX_WINDOW_SHORTCUTS]; - struct LinkedList *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS]; + WMBag *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS]; #ifdef XDND char *xdestring; diff --git a/src/session.c b/src/session.c index 5339058b..d9903123 100644 --- a/src/session.c +++ b/src/session.c @@ -91,7 +91,6 @@ #include "dock.h" -#include "list.h" #include @@ -281,7 +280,7 @@ wSessionSaveState(WScreen *scr) WWindow *wwin = scr->focused_window; proplist_t win_info, wks; proplist_t list=NULL; - LinkedList *wapp_list=NULL; + WMBag *wapp_list=NULL; make_keys(); @@ -297,7 +296,7 @@ wSessionSaveState(WScreen *scr) while (wwin) { WApplication *wapp=wApplicationOf(wwin->main_window); - if (wwin->transient_for==None && list_find(wapp_list, wapp)==NULL + if (wwin->transient_for==None && WMGetFirstInBag(wapp_list, wapp)<0 && !WFLAGP(wwin, dont_save_session)) { /* A entry for this application was not yet saved. Save one. */ if ((win_info = makeWindowState(wwin, wapp))!=NULL) { @@ -308,7 +307,7 @@ wSessionSaveState(WScreen *scr) * application list, so no multiple entries for the same * application are saved. */ - wapp_list = list_cons(wapp, wapp_list); + WMPutInBag(wapp_list, wapp); } } wwin = wwin->prev; @@ -321,7 +320,7 @@ wSessionSaveState(WScreen *scr) PLInsertDictionaryEntry(scr->session_state, sWorkspace, wks); PLRelease(wks); - list_free(wapp_list); + WMFreeBag(wapp_list); } diff --git a/src/superfluous.c b/src/superfluous.c index c71759db..3fe1f133 100644 --- a/src/superfluous.c +++ b/src/superfluous.c @@ -455,6 +455,9 @@ DoWindowBirth(WWindow *wwin) + + + #ifdef SILLYNESS static WMPixmap *data[12]; @@ -582,6 +585,9 @@ InitGhostWindowMove(WWindow *wwin) { _GhostWindowData *gdata; WScreen *scr = wwin->screen_ptr; + unsigned short *ptr; + unsigned short mask; + int i; gdata = wmalloc(sizeof(_GhostWindowData)); @@ -594,31 +600,195 @@ InitGhostWindowMove(WWindow *wwin) gdata->boxX = wwin->frame_x; gdata->boxY = wwin->frame_y; - gdata->window = + gdata->window = XCreateSimpleWindow(dpy, scr->root_win, wwin->frame_x, wwin->frame_y, gdata->width, gdata->height, 0, 0, 0); - gdata->winImage = - RGetXImage(scr->rcontext, wwin->frame->core->window, 0, 0, - scr->frame->core->width, scr->frame->core->height); + gdata->winImage = RGetXImage(scr->rcontext, wwin->frame->core->window, + 0, 0, gdata->width, gdata->height); - gdata->backImage = - RCreateXImage(scr->rcontext, scr->w_depth, - scr->frame->core->width, scr->frame->core->height); + gdata->backImage = RCreateXImage(scr->rcontext, scr->w_depth, + gdata->width, gdata->height); memcpy(gdata->backImage->image->data, gdata->winImage->image->data, - gdata->winImage->image->bytes_per_line * scr->frame->core->height); + gdata->winImage->image->bytes_per_line * gdata->height); + + gdata->image = RCreateXImage(scr->rcontext, scr->w_depth, + gdata->width, gdata->height); + + ptr = (unsigned short*)gdata->winImage->image->data; + + mask = 0x7b00|0x3d0|0x1e; + + for (i = 0; + i < gdata->winImage->image->bytes_per_line * gdata->height; + i++, ptr++) { + + *ptr &= mask; + } return gdata; } +static void +mergeGhostWindow(_GhostWindowData *gdata) +{ + register unsigned short *ptrw, *ptrb, *ptr; + int count; + int i; + + ptr = (unsigned short*)gdata->image->image->data; + ptrw = (unsigned short*)gdata->winImage->image->data; + ptrb = (unsigned short*)gdata->backImage->image->data; + + count = gdata->winImage->image->bytes_per_line * gdata->height; + + while (count--) { + *ptr = (*ptrw + *ptrb) >> 1; + + ptr++; + ptrw++; + ptrb++; + } +} + + void UpdateGhostWindowMove(void *data, int x, int y) { _GhostWindowData *gdata = (_GhostWindowData*)data; + WScreen *scr = gdata->scr; - + /* no intersection of new background with current */ + if (x + gdata->width <= gdata->boxX + || x >= gdata->boxX + gdata->width + || y + gdata->height <= gdata->boxY + || y >= gdata->boxY + gdata->height) { + int i; + + RDestroyXImage(gdata->backImage); + + gdata->backImage = RGetXImage(scr->rcontext, scr->root_win, x, y, + gdata->width, gdata->height); + + ptr = (unsigned short*)gdata->backImage->image->data; + + mask = 0x7b00|0x3d0|0x1e; + + for (i = 0; + i < gdata->winImage->image->bytes_per_line * gdata->height; + i++, ptr++) { + + *ptr &= mask; + } + } else { + int hx, hw, hy, hh; + int vx, vw, vy, vh; + int i, j; + unsigned char *backP = gdata->backImage->image->data; + unsigned char *winP = gdata->winImage->image->data; + int backLineLen = gdata->backImage->image->bytes_per_line; + int winLineLen = gdata->winImage->image->bytes_per_line; + + /* 1st move the area of the current backImage that overlaps + * the new backImage to it's new position */ + + if (x < gdata->boxX) { + vx = x + gdata->width; + vw = gdata->width - vx; + } else if (x > gdata->boxX) { + vw = gdata->boxX + gdata->width - x; + vx = gdata->boxX - vw; + } else { + vx = 0; + vw = gdata->width; + } + + if (y < gdata->boxY) { + vy = y + gdata->height; + vh = gdata->height - vy; + } else if (y > gdata->boxY) { + vh = gdata->boxY + gdata->height - y; + vy = gdata->boxY - vh; + } else { + vy = 0; + vh = gdata->height; + } + + if (y < gdata->boxY) { + int dy = vy - gdata->boxY; + + if (x < gdata->boxX) { + for (i = vh - 1; i >= 0; i--) { + memmove(&backP[(i + dy) * backLineLen + 2 * vx], + &backP[i * backLineLen], 2 * vw); + } + } else /* if (x > gdata->boxX) */ { + for (i = vh - 1; i >= 0; i--) { + memmove(&backP[(i + dy) * backLineLen], + &backP[i * backLineLen + 2 * vx], 2 * vw); + } + } + } else /*if (y > gdata->boxY) */ { + int dy = gdata->boxY - vy; + + if (x < gdata->boxX) { + for (i = 0; i < vh - 1; i++) { + memmove(&backP[i * backLineLen + 2 * vx], + &backP[(i + dy) * backLineLen], 2 * vw); + } + } else /*if (x > gdata->boxX) */ { + for (i = 0; i < vh - 1; i++) { + memmove(&backP[i * backLineLen], + &backP[(i + dy) * backLineLen + 2 * vx], 2 * vw); + } + } + } + + /* 2nd grab the background image from the screen and copy to the + * buffer. also maskout the lsb of rgb in each pixel of grabbed data */ + + if (y < gdata->boxY) { + vy = y; + vh = gdata->boxY - vy; + + hy = y + vh; + hh = gdata->height - vh; + } else if (y > gdata->boxY) { + vy = gdata->boxY + gdata->height; + vh = vy - (y + gdata->height); + + hy = y; + hh = y - gdata->boxY; + } else { + vy = vh = 0; + + hy = y; + hh = gdata->height; + } + + if (x < gdata->boxX) { + hx = x; + hw = gdata->boxX - hx; + } else if (x > gdata->boxX) { + hx = gdata->boxX + gdata->width; + hw = hx - (x + gdata->width); + } else { + hx = hw = 0; + + vx = x; + vw = gdata->width; + } + + /* 1st the top/bottom part */ + + + + /* 2nd the left/right part */ + } + + mergeGhostWindow(gdata); } diff --git a/src/wconfig.h.in b/src/wconfig.h.in index 85683768..12586f00 100644 --- a/src/wconfig.h.in +++ b/src/wconfig.h.in @@ -134,12 +134,9 @@ /* - * define EXTEND_WINDOWSHORTCUT if you have a great memory and want 10 - * window shortcuts instead of 4. You will also need to define the - * same thing in WPrefs.app/WPrefs.h to get the corresponding entries - * in WPrefs. + * define EXTEND_WINDOWSHORTCUT if you want 10 window shortcuts instead of 4. */ -#undef EXTEND_WINDOWSHORTCUT +#define EXTEND_WINDOWSHORTCUT @@ -300,6 +297,7 @@ #define DEF_ICON_TITLE_FONT "\"-*-*-medium-r-normal--10-*\"" #define DEF_CLIP_TITLE_FONT "\"-*-*-medium-r-normal--10-*\"" #define DEF_INFO_TEXT_FONT "\"-*-*-medium-r-normal--14-*\"" +#define DEF_ADDITONAL_FONT "-*-*-medium-r-normal--12-*" #define DEF_WORKSPACE_NAME_FONT "\"-*-*-medium-r-normal--24-*\"" #else /* !I18N_MB */ diff --git a/src/wdefaults.c b/src/wdefaults.c index b6279b74..5f193b8b 100644 --- a/src/wdefaults.c +++ b/src/wdefaults.c @@ -197,12 +197,14 @@ wDefaultFillAttributes(WScreen *scr, char *instance, char *class, proplist_t value; proplist_t key1, key2, key3; proplist_t dw, dc, dn, da; - char buffer[256]; - if (class && instance) + if (class && instance) { + char *buffer = NULL; + buffer = wmalloc(strlen(class)+strlen(instance)+4); key1 = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class)); - else + free(buffer); + } else key1 = NULL; if (instance) @@ -326,17 +328,19 @@ get_generic_value(WScreen *scr, char *instance, char *class, proplist_t option, Bool noDefault) { proplist_t value, key, dict; - char buffer[256]; value = NULL; PLSetStringCmpHook(NULL); if (class && instance) { + char *buffer = NULL; + buffer = wmalloc(strlen(class)+strlen(instance)+4); key = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class)); - + dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key); PLRelease(key); + free(buffer); if (dict) { value = PLGetDictionaryEntry(dict, option); @@ -348,7 +352,6 @@ get_generic_value(WScreen *scr, char *instance, char *class, proplist_t option, dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key); PLRelease(key); - if (dict) { value = PLGetDictionaryEntry(dict, option); } @@ -481,7 +484,6 @@ wDefaultChangeIcon(WScreen *scr, char *instance, char* class, char *file) WDDomain *db = WDWindowAttributes; proplist_t icon_value=NULL, value, attr, key, def_win, def_icon=NULL; proplist_t dict = db->dictionary; - char *buffer; int same = 0; if (!dict) { @@ -499,6 +501,7 @@ wDefaultChangeIcon(WScreen *scr, char *instance, char* class, char *file) PLSetStringCmpHook(NULL); if (instance && class) { + char *buffer; buffer = wmalloc(strlen(instance) + strlen(class) + 2); strcat(strcat(strcpy(buffer, instance), "."), class); key = PLMakeString(buffer); diff --git a/src/window.c b/src/window.c index 1f61703c..d0b08539 100644 --- a/src/window.c +++ b/src/window.c @@ -51,7 +51,7 @@ #include "stacking.h" #include "defaults.h" #include "workspace.h" -#include "list.h" + #ifdef MWM_HINTS # include "motif.h" @@ -212,15 +212,14 @@ wWindowDestroy(WWindow *wwin) wwin->flags.destroyed = 1; for (i = 0; i < MAX_WINDOW_SHORTCUTS; i++) { - wwin->screen_ptr->shortcutSelectedWindows[i] = list_remove_elem(wwin->screen_ptr->shortcutSelectedWindows[i], wwin); - if (wwin->screen_ptr->shortcutWindow[i] == wwin) { - if (wwin->screen_ptr->shortcutSelectedWindows[i]) { - LinkedList *list = wwin->screen_ptr->shortcutSelectedWindows[i]; - wwin->screen_ptr->shortcutWindow[i] = - list->head; - } - else wwin->screen_ptr->shortcutWindow[i] = NULL; - } + if (wwin->screen_ptr->shortcutSelectedWindows[i]) { + WMRemoveFromBag(wwin->screen_ptr->shortcutSelectedWindows[i], wwin); + + if (!WMGetBagItemCount(wwin->screen_ptr->shortcutSelectedWindows[i])) { + WMFreeBag(wwin->screen_ptr->shortcutSelectedWindows[i]); + wwin->screen_ptr->shortcutSelectedWindows[i] = NULL; + } + } } if (wwin->normal_hints) @@ -1469,28 +1468,40 @@ wUnmanageWindow(WWindow *wwin, Bool restore, Bool destroyed) scr->focused_window->next = NULL; } - /* if in click to focus mode and the window - * was a transient, focus the owner window - */ - tmp = NULL; if (wPreferences.focus_mode==WKF_CLICK) { - tmp = wWindowFor(wwin->transient_for); - if (tmp && (!tmp->flags.mapped || WFLAGP(tmp, no_focusable))) { - tmp = NULL; - } - } - /* otherwise, focus the next one in the focus list */ - if (!tmp) { - tmp = scr->focused_window; - while (tmp) { - if (!WFLAGP(tmp, no_focusable) - && (tmp->flags.mapped || tmp->flags.shaded)) - break; - tmp = tmp->prev; - } - } - if (wPreferences.focus_mode==WKF_CLICK) { - newFocusedWindow = tmp; + + /* if in click to focus mode and the window + * was a transient, focus the owner window + */ + tmp = NULL; + if (wPreferences.focus_mode==WKF_CLICK) { + tmp = wWindowFor(wwin->transient_for); + if (tmp && (!tmp->flags.mapped || WFLAGP(tmp, no_focusable))) { + tmp = NULL; + } + } + /* otherwise, focus the next one in the focus list */ + if (!tmp) { + tmp = scr->focused_window; + while (tmp) { /* look for one in the window list first */ + if (!WFLAGP(tmp, no_focusable) && !WFLAGP(tmp, skip_window_list) + && (tmp->flags.mapped || tmp->flags.shaded)) + break; + tmp = tmp->prev; + } + if (!tmp) { /* if unsuccessful, choose any focusable window */ + tmp = scr->focused_window; + while (tmp) { + if (!WFLAGP(tmp, no_focusable) + && (tmp->flags.mapped || tmp->flags.shaded)) + break; + tmp = tmp->prev; + } + } + } + + newFocusedWindow = tmp; + } else if (wPreferences.focus_mode==WKF_SLOPPY || wPreferences.focus_mode==WKF_POINTER) { unsigned int mask; @@ -1794,8 +1805,10 @@ wWindowChangeWorkspace(WWindow *wwin, int workspace) wapp->last_workspace = workspace; } if (wwin->flags.miniaturized) { - XUnmapWindow(dpy, wwin->icon->core->window); - wwin->icon->mapped = 0; + if (wwin->icon) { + XUnmapWindow(dpy, wwin->icon->core->window); + wwin->icon->mapped = 0; + } } else { unmap = 1; wSetFocusTo(scr, NULL); @@ -1804,8 +1817,10 @@ wWindowChangeWorkspace(WWindow *wwin, int workspace) } else { /* brought to current workspace. Map window */ if (wwin->flags.miniaturized && !wPreferences.sticky_icons) { - XMapWindow(dpy, wwin->icon->core->window); - wwin->icon->mapped = 1; + if (wwin->icon) { + XMapWindow(dpy, wwin->icon->core->window); + wwin->icon->mapped = 1; + } } else if (!wwin->flags.mapped && !(wwin->flags.miniaturized || wwin->flags.hidden)) { wWindowMap(wwin); @@ -1990,37 +2005,36 @@ int req_x, req_y; /* new position of the frame */ #endif } - -void +void wWindowUpdateButtonImages(WWindow *wwin) { WScreen *scr = wwin->screen_ptr; Pixmap pixmap, mask; WFrameWindow *fwin = wwin->frame; - + if (WFLAGP(wwin, no_titlebar)) return; /* miniaturize button */ - + if (!WFLAGP(wwin, no_miniaturize_button)) { if (wwin->wm_gnustep_attr && wwin->wm_gnustep_attr->flags & GSMiniaturizePixmapAttr) { pixmap = wwin->wm_gnustep_attr->miniaturize_pixmap; - + if (wwin->wm_gnustep_attr->flags&GSMiniaturizeMaskAttr) { mask = wwin->wm_gnustep_attr->miniaturize_mask; } else { mask = None; } - if (fwin->lbutton_image + if (fwin->lbutton_image && (fwin->lbutton_image->image != pixmap || fwin->lbutton_image->mask != mask)) { wPixmapDestroy(fwin->lbutton_image); fwin->lbutton_image = NULL; } - + if (!fwin->lbutton_image) { fwin->lbutton_image = wPixmapCreate(scr, pixmap, mask); fwin->lbutton_image->client_owned = 1; @@ -2033,55 +2047,64 @@ wWindowUpdateButtonImages(WWindow *wwin) fwin->lbutton_image = scr->b_pixmaps[WBUT_ICONIFY]; } } - + #ifdef XKB_BUTTON_HINT if (!WFLAGP(wwin, no_language_button)) { - if (fwin->languagebutton_image && !fwin->languagebutton_image->shared) { + if (fwin->languagebutton_image && + !fwin->languagebutton_image->shared) { wPixmapDestroy(fwin->languagebutton_image); } - fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode]; + fwin->languagebutton_image = + scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode]; } #endif - + /* close button */ +/* redefine WFLAGP to MGFLAGP to allow broken close operation */ +#define MGFLAGP(wwin, FLAG) (wwin)->client_flags.FLAG + if (!WFLAGP(wwin, no_close_button)) { - if (wwin->wm_gnustep_attr - && wwin->wm_gnustep_attr->flags&GSClosePixmapAttr) { - pixmap = wwin->wm_gnustep_attr->close_pixmap; - - if (wwin->wm_gnustep_attr->flags&GSCloseMaskAttr) { - mask = wwin->wm_gnustep_attr->close_mask; - } else { - mask = None; - } + if (wwin->wm_gnustep_attr + && wwin->wm_gnustep_attr->flags & GSClosePixmapAttr) { + pixmap = wwin->wm_gnustep_attr->close_pixmap; + + if (wwin->wm_gnustep_attr->flags&GSCloseMaskAttr) + mask = wwin->wm_gnustep_attr->close_mask; + else + mask = None; + + if (fwin->rbutton_image && (fwin->rbutton_image->image != pixmap + || fwin->rbutton_image->mask != mask)) { + wPixmapDestroy(fwin->rbutton_image); + fwin->rbutton_image = NULL; + } + + if (!fwin->rbutton_image) { + fwin->rbutton_image = wPixmapCreate(scr, pixmap, mask); + fwin->rbutton_image->client_owned = 1; + fwin->rbutton_image->client_owned_mask = 1; + } - if (fwin->rbutton_image - && (fwin->rbutton_image->image != pixmap - || fwin->rbutton_image->mask != mask)) { - wPixmapDestroy(fwin->rbutton_image); - fwin->rbutton_image = NULL; - } - - if (!fwin->rbutton_image) { - fwin->rbutton_image = wPixmapCreate(scr, pixmap, mask); - fwin->rbutton_image->client_owned = 1; - fwin->rbutton_image->client_owned_mask = 1; - } } else if (WFLAGP(wwin, kill_close)) { - if (fwin->rbutton_image && !fwin->rbutton_image->shared) { + + if (fwin->rbutton_image && !fwin->rbutton_image->shared) wPixmapDestroy(fwin->rbutton_image); - } + fwin->rbutton_image = scr->b_pixmaps[WBUT_KILL]; - } else if (WFLAGP(wwin, broken_close)) { - if (fwin->rbutton_image && !fwin->rbutton_image->shared) { + + } else if (MGFLAGP(wwin, broken_close)) { + + if (fwin->rbutton_image && !fwin->rbutton_image->shared) wPixmapDestroy(fwin->rbutton_image); - } + fwin->rbutton_image = scr->b_pixmaps[WBUT_BROKENCLOSE]; + } else { - if (fwin->rbutton_image && !fwin->rbutton_image->shared) { + + if (fwin->rbutton_image && !fwin->rbutton_image->shared) wPixmapDestroy(fwin->rbutton_image); - } + fwin->rbutton_image = scr->b_pixmaps[WBUT_CLOSE]; } } @@ -2422,17 +2445,13 @@ wWindowResetMouseGrabs(WWindow *wwin) void wWindowUpdateGNUstepAttr(WWindow *wwin, GNUstepWMAttributes *attr) { - - if (attr->flags & GSExtraFlagsAttr) { - if (WFLAGP(wwin, broken_close) != - (attr->extra_flags & GSDocumentEditedFlag)) { - - wwin->client_flags.broken_close = !WFLAGP(wwin, broken_close); - - wWindowUpdateButtonImages(wwin); - } - } - + if (attr->flags & GSExtraFlagsAttr) { + if (MGFLAGP(wwin, broken_close) != + (attr->extra_flags & GSDocumentEditedFlag)) { + wwin->client_flags.broken_close = !MGFLAGP(wwin, broken_close); + wWindowUpdateButtonImages(wwin); + } + } } diff --git a/src/winmenu.c b/src/winmenu.c index 0d065803..9f967104 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -44,7 +44,7 @@ #include "dialog.h" #include "stacking.h" #include "icon.h" -#include "list.h" + #define MC_MAXIMIZE 0 #define MC_MINIATURIZE 1 @@ -199,16 +199,23 @@ makeShortcutCommand(WMenu *menu, WMenuEntry *entry) WScreen *scr = wwin->screen_ptr; scr->shortcutWindow[entry->order-WO_ENTRIES] = wwin; - list_free(scr->shortcutSelectedWindows[entry->order-WO_ENTRIES]); - scr->shortcutSelectedWindows[entry->order-WO_ENTRIES] = NULL; - if (wwin->flags.selected /* && scr->selected_windows */ ) { - LinkedList *sl; - sl = scr->selected_windows; + if (scr->shortcutSelectedWindows[entry->order-WO_ENTRIES]) + WMFreeBag(scr->shortcutSelectedWindows[entry->order-WO_ENTRIES]); + + if (wwin->flags.selected && scr->selected_windows) { + WMBag *bag; + int i; + + scr->shortcutSelectedWindows[entry->order-WO_ENTRIES] = WMCreateBag(4); - while (sl) { - scr->shortcutSelectedWindows[entry->order-WO_ENTRIES] = list_cons(sl->head,scr->shortcutSelectedWindows[entry->order-WO_ENTRIES]); - sl = sl->tail; + bag = scr->selected_windows; + + for (i = 0; i < WMGetBagItemCount(bag); i++) { + WWindow *tmp = WMGetFromBag(bag, i); + + WMPutInBag(scr->shortcutSelectedWindows[entry->order-WO_ENTRIES], + tmp); } } else { @@ -273,16 +280,17 @@ updateMakeShortcutMenu(WMenu *menu, WWindow *wwin) int shortcutNo = i-WO_ENTRIES; WWindow *twin = wwin->screen_ptr->shortcutWindow[shortcutNo]; WMenuEntry *entry = smenu->entries[i]; + WMBag *shortSelWindows = wwin->screen_ptr->shortcutSelectedWindows[shortcutNo]; sprintf(buffer, "%s %i", _("Set Shortcut"), shortcutNo+1); - if (!twin && !wwin->screen_ptr->shortcutSelectedWindows[shortcutNo]) { + if (!twin && !shortSelWindows) { entry->flags.indicator_on = 0; } else { entry->flags.indicator_on = 1; if (twin == wwin) entry->flags.indicator_type = MI_DIAMOND; - else if (list_find(wwin->screen_ptr->shortcutSelectedWindows[shortcutNo], wwin)) + else if (shortSelWindows && WMCountInBag(shortSelWindows, wwin)) entry->flags.indicator_type = MI_HIDDEN; else entry->flags.indicator_type = MI_CHECK; diff --git a/src/winspector.c b/src/winspector.c index a3ce7b5f..5109e629 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -371,12 +371,13 @@ getBool(proplist_t value) */ -static void +static int insertAttribute(proplist_t dict, proplist_t window, proplist_t attr, - proplist_t value, int *modified, int flags) + proplist_t value, int flags) { proplist_t def_win, def_value=NULL; int update = 0; + int modified = 0; if (!(flags & UPDATE_DEFAULTS) && dict) { if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) { @@ -398,8 +399,10 @@ insertAttribute(proplist_t dict, proplist_t window, proplist_t attr, if (update) { PLInsertDictionaryEntry(window, attr, value); - *modified = 1; + modified = 1; } + + return modified; } @@ -410,7 +413,7 @@ saveSettings(WMButton *button, InspectorPanel *panel) WDDomain *db = WDWindowAttributes; proplist_t dict = db->dictionary; proplist_t winDic, value, key; - char buffer[256], *icon_file; + char *icon_file; int flags = 0; int different = 0; @@ -422,14 +425,16 @@ saveSettings(WMButton *button, InspectorPanel *panel) else if (WMGetButtonSelected(panel->clsRb) != 0) key = PLMakeString(wwin->wm_class); else if (WMGetButtonSelected(panel->bothRb) != 0) { + char *buffer; + + buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+4); strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class); key = PLMakeString(buffer); - } - else if (WMGetButtonSelected(panel->defaultRb) != 0) { + free(buffer); + } else if (WMGetButtonSelected(panel->defaultRb) != 0) { key = PLRetain(AnyWindow); flags = UPDATE_DEFAULTS; - } - else + } else key = NULL; if (!key) @@ -462,7 +467,7 @@ saveSettings(WMButton *button, InspectorPanel *panel) if (icon_file) { if (icon_file[0] != 0) { value = PLMakeString(icon_file); - insertAttribute(dict, winDic, AIcon, value, &different, flags); + different |= insertAttribute(dict, winDic, AIcon, value, flags); PLRelease(value); } free(icon_file); @@ -475,7 +480,8 @@ saveSettings(WMButton *button, InspectorPanel *panel) if (i>=0 && i < panel->frame->screen_ptr->workspace_count) { value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name); - insertAttribute(dict, winDic, AStartWorkspace, value, &different, flags); + different |= insertAttribute(dict, winDic, AStartWorkspace, value, + flags); PLRelease(value); } } @@ -483,66 +489,66 @@ saveSettings(WMButton *button, InspectorPanel *panel) flags |= IS_BOOLEAN; value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No; - insertAttribute(dict, winDic, AAlwaysUserIcon, value, &different, flags); + different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags); value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoTitlebar, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags); value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoResizebar, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoResizebar, value, flags); value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoCloseButton, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags); value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoMiniaturizeButton, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags); value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No; - insertAttribute(dict, winDic, AKeepOnTop, value, &different, flags); + different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags); value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No; - insertAttribute(dict, winDic, AKeepOnBottom, value, &different, flags); + different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags); value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No; - insertAttribute(dict, winDic, AOmnipresent, value, &different, flags); + different |= insertAttribute(dict, winDic, AOmnipresent, value, flags); value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No; - insertAttribute(dict, winDic, AStartMiniaturized, value, &different, flags); + different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags); value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No; - insertAttribute(dict, winDic, AStartMaximized, value, &different, flags); + different |= insertAttribute(dict, winDic, AStartMaximized, value, flags); value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No; - insertAttribute(dict, winDic, ASkipWindowList, value, &different, flags); + different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags); value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoHideOthers, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags); value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoKeyBindings, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags); value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoMouseBindings, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags); value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No; - insertAttribute(dict, winDic, AKeepInsideScreen, value, &different, flags); + different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags); value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No; - insertAttribute(dict, winDic, AUnfocusable, value, &different, flags); + different |= insertAttribute(dict, winDic, AUnfocusable, value, flags); value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No; - insertAttribute(dict, winDic, ADontSaveSession, value, &different, flags); + different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags); value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No; - insertAttribute(dict, winDic, AEmulateAppIcon, value, &different, flags); + different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags); value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No; - insertAttribute(dict, winDic, AFullMaximize, value, &different, flags); + different |= insertAttribute(dict, winDic, AFullMaximize, value, flags); #ifdef XKB_BUTTON_HINT value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoLanguageButton, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags); #endif /* application wide settings for when */ @@ -550,10 +556,10 @@ saveSettings(WMButton *button, InspectorPanel *panel) if (panel->inspected->main_window == panel->inspected->client_win) { value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No; - insertAttribute(dict, winDic, AStartHidden, value, &different, flags); + different |= insertAttribute(dict, winDic, AStartHidden, value, flags); value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No; - insertAttribute(dict, winDic, ANoAppIcon, value, &different, flags); + different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags); } PLRemoveDictionaryEntry(dict, key); @@ -575,15 +581,19 @@ saveSettings(WMButton *button, InspectorPanel *panel) wapp = wApplicationOf(panel->inspected->main_window); if (wapp) { char *iconFile; + char *buffer; appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL); assert(wapp->main_window_desc->wm_instance!=NULL); assert(wapp->main_window_desc->wm_class!=NULL); + buffer = wmalloc(strlen(wapp->main_window_desc->wm_instance) + +strlen(wwin->wm_class)+4); strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), "."); strcat(buffer, wwin->wm_class); key = PLMakeString(buffer); + free(buffer); iconFile = wDefaultGetIconFile(wwin->screen_ptr, wapp->main_window_desc->wm_instance, @@ -592,16 +602,18 @@ saveSettings(WMButton *button, InspectorPanel *panel) if (iconFile && iconFile[0]!=0) { value = PLMakeString(iconFile); - insertAttribute(dict, appDic, AIcon, value, &different, - flags&~IS_BOOLEAN); + different |= insertAttribute(dict, appDic, AIcon, value, + flags&~IS_BOOLEAN); PLRelease(value); } value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No; - insertAttribute(dict, appDic, AStartHidden, value, &different, flags); + different |= insertAttribute(dict, appDic, AStartHidden, value, + flags); value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No; - insertAttribute(dict, appDic, ANoAppIcon, value, &different, flags); + different |= insertAttribute(dict, appDic, ANoAppIcon, value, + flags); PLRemoveDictionaryEntry(dict, key); if (different) { @@ -1099,6 +1111,7 @@ createInspectorForWindow(WWindow *wwin) tmp = wstrappend(wwin->wm_instance, "."); str = wstrappend(tmp, wwin->wm_class); + panel->bothRb = WMCreateRadioButton(panel->specFrm); WMMoveWidget(panel->bothRb, 10, 18); WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20); @@ -1507,6 +1520,8 @@ createInspectorForWindow(WWindow *wwin) if (!selectedBtn) selectedBtn = panel->defaultRb; + WMSetButtonSelected(selectedBtn, True); + selectSpecification(selectedBtn, panel); /* kluge to know who should get the key events */ diff --git a/src/workspace.c b/src/workspace.c index 88bc441b..486aa41f 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -498,11 +498,14 @@ wWorkspaceForceChange(WScreen *scr, int workspace) wWorkspaceMenuUpdate(scr, scr->clip_ws_menu); if ((tmp = scr->focused_window)!= NULL) { - if (IS_OMNIPRESENT(tmp) || tmp->flags.changing_workspace) + if ((IS_OMNIPRESENT(tmp) && !WFLAGP(tmp, skip_window_list)) + || tmp->flags.changing_workspace) { foc = tmp; - /* foc2 = tmp; will fix annoyance with gnome panel - * but will create annoyance for every other application - */ + } + + /* foc2 = tmp; will fix annoyance with gnome panel + * but will create annoyance for every other application + */ while (tmp) { if (tmp->frame->workspace!=workspace && !tmp->flags.selected) { @@ -552,7 +555,7 @@ wWorkspaceForceChange(WScreen *scr, int workspace) if (!(tmp->flags.mapped || tmp->flags.miniaturized)) { /* remap windows that are on this workspace */ wWindowMap(tmp); - if (!foc) + if (!foc && !WFLAGP(tmp, skip_window_list)) foc = tmp; } /* Also map miniwindow if not omnipresent */ @@ -880,7 +883,7 @@ wWorkspaceRestoreState(WScreen *scr) return; wscount = scr->workspace_count; - for (i=0; i < PLGetNumberOfElements(parr); i++) { + for (i=0; i < WMIN(PLGetNumberOfElements(parr), MAX_WORKSPACES); i++) { wks_state = PLGetArrayElement(parr, i); if (PLIsDictionary(wks_state)) pstr = PLGetDictionaryEntry(wks_state, dName); -- 2.11.4.GIT