Hi, On 2009-12-08 00:26, Carlos R. Mafra wrote: > I never noticed this, could you share your test program just in case?
Sure, it's attached. The program will just open and close windows as fast as possible. You should start in from a terminal to be able to abort the program. > Sounds reasonable, and if it works for you than it is all fine I guess. I attached another patch implementing my proposal. It works for me and a default value is still set for the first screen so it should also work in the environment mentioned in the commit e4800. Best Regards, Ralf Hoffmann -- Ralf Hoffmann <[email protected]> Homepage: http://www.boomerangsworld.de
lost-window-test.tar.gz
Description: application/gzip
>From e5f41894a3fdc6438af590ff203be35c92931178 Mon Sep 17 00:00:00 2001 From: Ralf Hoffmann <[email protected]> Date: Thu, 10 Dec 2009 19:57:23 +0100 Subject: [PATCH] fixed problem with default visual ID for multi-screen setups by using multiple IDs for each screen Since a single default visual ID cannot be used for multiple screens, thus Window Maker refused to start. There is now a global function for getting the default visual ID. The command line argument --visual-id can be a comma separated list of visual IDs for each screen. A default value is only set for the first screen. --- src/funcs.h | 2 + src/main.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/screen.c | 5 +-- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/funcs.h b/src/funcs.h index f49536e..8dfcc5c 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -148,4 +148,6 @@ char* GetProgramNameForWindow(Window win); Bool GetCommandForPid(int pid, char ***argv, int *argc); +int getWVisualID(int screen); + #endif diff --git a/src/main.c b/src/main.c index 2ad68f8..cb5c74b 100644 --- a/src/main.c +++ b/src/main.c @@ -145,9 +145,6 @@ char WProgramSigState = 0; char WProgramState = WSTATE_NORMAL; char WDelayedActionSet = 0; -/* temporary stuff */ -int wVisualID = -1; - /* notifications */ const char *WMNManaged = "WMNManaged"; const char *WMNUnmanaged = "WMNUnmanaged"; @@ -178,8 +175,95 @@ extern int MonitorLoop(int argc, char **argv); static Bool multiHead = True; +static int *wVisualID = NULL; +static int wVisualID_len = 0; + static int real_main(int argc, char **argv); +int getWVisualID(int screen) +{ + if (wVisualID == NULL) return -1; + if (screen < 0 || screen >= wVisualID_len) return -1; + return wVisualID[screen]; +} + +static void setWVisualID(int screen, int val) +{ + int i; + + if (screen < 0) return; + + if (wVisualID == NULL) { + /* no array at all, alloc space for screen + 1 entries + and init with default value */ + wVisualID_len = screen + 1; + wVisualID = (int*)malloc(wVisualID_len * sizeof(int)); + for (i = 0; i < wVisualID_len; i++) { + wVisualID[i] = -1; + } + } else if (screen >= wVisualID_len) { + /* larger screen number than previously allocated + so enlarge array */ + int oldlen = wVisualID_len; + + wVisualID_len = screen + 1; + wVisualID = (int*)realloc(wVisualID, + wVisualID_len * sizeof(int)); + for (i = oldlen; i < wVisualID_len; i++) { + wVisualID[i] = -1; + } + } + + wVisualID[screen] = val; +} + +/* + * this function splits a given string at the comma into tokens + * and set the wVisualID variable to each parsed number + */ +static int initWVisualID(const char *user_str) +{ + char *mystr = strdup(user_str); + int cur_in_pos = 0; + int cur_out_pos = 0; + int cur_screen = 0; + int error_found = 0; + + for (;;) { + /* check for delimiter */ + if (user_str[cur_in_pos] == '\0' || + user_str[cur_in_pos] == ',') { + int v; + + mystr[cur_out_pos] = '\0'; + + if (sscanf(mystr, "%i", &v) != 1) { + error_found = 1; + break; + } + + setWVisualID(cur_screen, v); + + cur_screen++; + cur_out_pos = 0; + } + + /* break in case last char has been consumed */ + if (user_str[cur_in_pos] == '\0') break; + + /* if the current char is no delimiter put it into mystr */ + if (user_str[cur_in_pos] != ',') { + mystr[cur_out_pos++] = user_str[cur_in_pos]; + } + cur_in_pos++; + } + + free(mystr); + + if (cur_screen == 0||error_found != 0) return 1; + return 0; +} + void Exit(int status) { #ifdef XSMP_ENABLED @@ -640,7 +724,7 @@ static int real_main(int argc, char **argv) wwarning(_("too few arguments for %s"), argv[i - 1]); exit(0); } - if (sscanf(argv[i], "%i", &wVisualID) != 1) { + if (initWVisualID(argv[i]) != 0) { wwarning(_("bad value for visualid: \"%s\""), argv[i]); exit(0); } @@ -722,7 +806,8 @@ static int real_main(int argc, char **argv) exit(1); } - if (wVisualID < 0) + + if (getWVisualID(0) < 0) { /* * If unspecified, use default visual instead of waiting * for wrlib/context.c:bestContext() that may end up choosing @@ -730,7 +815,8 @@ static int real_main(int argc, char **argv) * This is required to avoid all sort of corruptions when * composite is enabled, and at a depth other than 24. */ - wVisualID = (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid; + setWVisualID(0, (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid); + } /* check if the user specified a complete display name (with screen). * If so, only manage the specified screen */ diff --git a/src/screen.c b/src/screen.c index 58649f9..6dd30ba 100644 --- a/src/screen.c +++ b/src/screen.c @@ -538,7 +538,6 @@ WScreen *wScreenInit(int screen_number) WScreen *scr; XIconSize icon_size[1]; RContextAttributes rattr; - extern int wVisualID; long event_mask; XErrorHandler oldHandler; int i; @@ -625,9 +624,9 @@ WScreen *wScreenInit(int screen_number) rattr.standard_colormap_mode = RUseStdColormap; } - if (wVisualID >= 0) { + if (getWVisualID(screen_number) >= 0) { rattr.flags |= RC_VisualID; - rattr.visualid = wVisualID; + rattr.visualid = getWVisualID(screen_number); } scr->rcontext = RCreateContext(dpy, screen_number, &rattr); -- 1.6.5.1
