X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=7a13f559acdbe2e361c0ff6405b92703c55d9ba0;hb=8ad832c092d5d3523831284139674813362b8ea3;hp=d7ddbfc1dca46a80bd8f0ff4e5c6ef7ef351facf;hpb=c721268c34bb2267e073558e7c6523cc97ba089e;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index d7ddbfc..7a13f55 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -101,6 +101,7 @@ u_int32_t swm_debug = 0 #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) char **start_argv; +Atom astate; int (*xerrorxlib)(Display *, XErrorEvent *); int other_wm; int screen; @@ -435,9 +436,9 @@ spawn(union arg *args) * The double-fork construct avoids zombie processes and keeps the code * clean from stupid signal handlers. */ - if(fork() == 0) { - if(fork() == 0) { - if(display) + if (fork() == 0) { + if (fork() == 0) { + if (display) close(ConnectionNumber(display)); setsid(); execvp(args->argv[0], args->argv); @@ -1086,9 +1087,9 @@ grabkeys(void) updatenumlockmask(); XUngrabKey(display, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) { - if((code = XKeysymToKeycode(display, keys[i].keysym))) - for(j = 0; j < LENGTH(modifiers); j++) + for (i = 0; i < LENGTH(keys); i++) { + if ((code = XKeysymToKeycode(display, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(display, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); @@ -1110,8 +1111,8 @@ keypress(XEvent *e) DNPRINTF(SWM_D_EVENT, "keypress: window: %lu\n", ev->window); keysym = XKeycodeToKeysym(display, (KeyCode)ev->keycode, 0); - for(i = 0; i < LENGTH(keys); i++) - if(keysym == keys[i].keysym + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) keys[i].func(&(keys[i].args)); @@ -1148,6 +1149,17 @@ buttonpress(XEvent *e) #endif } +void +set_win_state(struct ws_win *win, long state) +{ + long data[] = {state, None}; + + DNPRINTF(SWM_D_EVENT, "set_win_state: window: %lu\n", win->id); + + XChangeProperty(display, win->id, astate, astate, 32, PropModeReplace, + (unsigned char *)data, 2); +} + struct ws_win * manage_window(Window id) { @@ -1178,20 +1190,22 @@ manage_window(Window id) /* XXX */ bzero(&ch, sizeof ch); - if(XGetClassHint(display, win->id, &ch)) { + if (XGetClassHint(display, win->id, &ch)) { /*fprintf(stderr, "class: %s name: %s\n", ch.res_class, ch.res_name); */ if (!strcmp(ch.res_class, "MPlayer") && !strcmp(ch.res_name, "xv")) { win->floating = 1; } - if(ch.res_class) + if (ch.res_class) XFree(ch.res_class); - if(ch.res_name) + if (ch.res_name) XFree(ch.res_name); } XSelectInput(display, id, ButtonPressMask | EnterWindowMask | FocusChangeMask | ExposureMask); + set_win_state(win, NormalState); + return (win); } @@ -1256,6 +1270,7 @@ destroynotify(XEvent *e) ws[current_ws].focus = NULL; TAILQ_REMOVE(&ws[current_ws].winlist, win, entry); + set_win_state(win, WithdrawnState); free(win); break; } @@ -1272,7 +1287,7 @@ enternotify(XEvent *e) DNPRINTF(SWM_D_EVENT, "enternotify: window: %lu\n", ev->window); - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; if (ignore_enter) { @@ -1316,7 +1331,7 @@ mappingnotify(XEvent *e) DNPRINTF(SWM_D_EVENT, "mappingnotify: window: %lu\n", ev->window); XRefreshKeyboardMapping(ev); - if(ev->request == MappingKeyboard) + if (ev->request == MappingKeyboard) grabkeys(); } @@ -1329,9 +1344,9 @@ maprequest(XEvent *e) DNPRINTF(SWM_D_EVENT, "maprequest: window: %lu\n", e->xmaprequest.window); - if(!XGetWindowAttributes(display, ev->window, &wa)) + if (!XGetWindowAttributes(display, ev->window, &wa)) return; - if(wa.override_redirect) + if (wa.override_redirect) return; manage_window(e->xmaprequest.window); stack(); @@ -1386,8 +1401,7 @@ xerror_start(Display *d, XErrorEvent *ee) int xerror(Display *d, XErrorEvent *ee) { - fprintf(stderr, "error: %p %p\n", display, ee); - + /* fprintf(stderr, "error: %p %p\n", display, ee); */ return (-1); } @@ -1401,7 +1415,7 @@ active_wm(void) XSelectInput(display, DefaultRootWindow(display), SubstructureRedirectMask); XSync(display, False); - if(other_wm) + if (other_wm) return (1); XSetErrorHandler(xerror); @@ -1409,6 +1423,26 @@ active_wm(void) return (0); } +long +getstate(Window w) +{ + int format, status; + long result = -1; + unsigned char *p = NULL; + unsigned long n, extra; + Atom real; + + astate = XInternAtom(display, "WM_STATE", False); + status = XGetWindowProperty(display, w, astate, 0L, 2L, False, astate, + &real, &format, &n, &extra, (unsigned char **)&p); + if (status != Success) + return (-1); + if (n != 0) + result = *p; + XFree(p); + return (result); +} + int main(int argc, char *argv[]) { @@ -1422,10 +1456,10 @@ main(int argc, char *argv[]) start_argv = argv; fprintf(stderr, "Welcome to scrotwm V%s\n", SWM_VERSION); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) warnx("no locale support"); - if(!(display = XOpenDisplay(0))) + if (!(display = XOpenDisplay(0))) errx(1, "can not open display"); if (active_wm()) @@ -1433,6 +1467,7 @@ main(int argc, char *argv[]) screen = DefaultScreen(display); root = RootWindow(display, screen); + astate = XInternAtom(display, "WM_STATE", False); /* look for local and global conf file */ pwd = getpwuid(getuid()); @@ -1475,15 +1510,25 @@ main(int argc, char *argv[]) /* grab existing windows */ if (XQueryTree(display, root, &d1, &d2, &wins, &num)) { + /* normal windows */ + for (i = 0; i < num; i++) { + XGetWindowAttributes(display, wins[i], &wa); + if (!XGetWindowAttributes(display, wins[i], &wa) || + wa.override_redirect || XGetTransientForHint(display, wins[i], &d1)) + continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == NormalState) + manage_window(wins[i]); + } + /* transient windows */ for (i = 0; i < num; i++) { - if (!XGetWindowAttributes(display, wins[i], &wa) - || wa.override_redirect - || wa.map_state != IsViewable || - XGetTransientForHint(display, wins[i], &d1)) + if (!XGetWindowAttributes(display, wins[i], &wa)) continue; - manage_window(wins[i]); + if (XGetTransientForHint(display, wins[i], &d1) && + (wa.map_state == IsViewable || getstate(wins[i]) == + NormalState)) + manage_window(wins[i]); } - if(wins) + if (wins) XFree(wins); } ws[0].focus = TAILQ_FIRST(&ws[0].winlist);