X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=16cb8b397f01c4284230ed27a87d59acb23e2b1c;hb=5d85c472a1bbb33bfa6e4760a201f2c3a2ec4355;hp=1522296d6037c10ac039b935b03b216cf1164b28;hpb=fc4fba85135f7d758fd3019917a0490791033933;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 1522296..16cb8b3 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -387,7 +387,7 @@ char *bar_fonts; XftColor bar_font_color; struct passwd *pwd; char *startup_exception; -unsigned int nr_exceptions = 0; +unsigned int nr_exceptions = 0; /* layout manager data */ struct swm_geometry { @@ -1055,8 +1055,8 @@ pid_t window_get_pid(xcb_window_t); void wkill(struct swm_region *, union arg *); void workaround(void); void xft_init(struct swm_region *); -void _add_startup_exception(const char *, va_list); -void add_startup_exception(const char *, ...); +void _add_startup_exception(const char *, va_list); +void add_startup_exception(const char *, ...); RB_PROTOTYPE(key_tree, key, entry, key_cmp); RB_GENERATE(key_tree, key, entry, key_cmp); @@ -2539,7 +2539,8 @@ bar_setup(struct swm_region *r) r->bar->id = xcb_generate_id(conn); wa[0] = r->s->c[SWM_S_COLOR_BAR].pixel; wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER_UNFOCUS].pixel; - wa[2] = XCB_EVENT_MASK_EXPOSURE; + wa[2] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION | + XCB_EVENT_MASK_POINTER_MOTION_HINT; xcb_create_window(conn, XCB_COPY_FROM_PARENT, r->bar->id, r->s->root, X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar), @@ -4723,7 +4724,7 @@ get_win_name(xcb_window_t win) free(r); /* Use WM_NAME instead; no UTF-8. */ c = xcb_get_property(conn, 0, win, XCB_ATOM_WM_NAME, - XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); + XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); r = xcb_get_property_reply(conn, c, NULL); if (!r) @@ -4735,7 +4736,7 @@ get_win_name(xcb_window_t win) } if (r->length > 0) name = strndup(xcb_get_property_value(r), - xcb_get_property_value_length(r)); + xcb_get_property_value_length(r)); free(r); } @@ -6018,15 +6019,25 @@ setspawn(const char *name, const char *args) int setconfspawn(char *selector, char *value, int flags) { - char *args; - - /* suppress unused warning since var is needed */ - (void)flags; + char *args; + char which[PATH_MAX]; + size_t i; args = expand_tilde(value); DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args); + /* verify we have the goods */ + snprintf(which, sizeof which, "which %s", value); + for (i = strlen("which "); i < strlen(which); i++) + if (which[i] == ' ') { + which[i] = '\0'; + break; + } + if (flags == 0 && system(which) != 0) + add_startup_exception("could not find %s", + &which[strlen("which ")]); + setspawn(selector, args); free(args); @@ -6039,10 +6050,6 @@ setup_spawn(void) { setconfspawn("term", "xterm", 0); setconfspawn("spawn_term", "xterm", 0); - setconfspawn("screenshot_all", "screenshot.sh full", 0); - setconfspawn("screenshot_wind", "screenshot.sh window", 0); - setconfspawn("lock", "xlock", 0); - setconfspawn("initscr", "initscreen.sh", 0); setconfspawn("menu", "dmenu_run" " -fn $bar_font" " -nb $bar_color" @@ -6064,9 +6071,11 @@ setup_spawn(void) " -sb $bar_border" " -sf $bar_color", 0); - /* only test dmenu for now, really should expand this */ - if (system("dmenu -v") != 0) - add_startup_exception("you must install dmenu"); + /* these are not verified for existence */ + setconfspawn("lock", "xlock", 1); + setconfspawn("screenshot_all", "screenshot.sh full", 1); + setconfspawn("screenshot_wind", "screenshot.sh window", 1); + setconfspawn("initscr", "initscreen.sh", 1); } /* key bindings */ @@ -7307,6 +7316,12 @@ conf_load(const char *filename, int keymapping) cp += strspn(cp, "= \t\n"); /* eat trailing */ /* get RHS value */ optval = strdup(cp); + if (strlen(optval) == 0) { + add_startup_exception("%s: line %zd: must supply value " + "to %s", filename, lineno, + configopt[optidx].optname); + goto invalid; + } /* call function to deal with it all */ if (configopt[optidx].func(optsub, optval, configopt[optidx].funcflags) != 0) { @@ -8728,6 +8743,7 @@ scan_xrandr(int i) int ncrtc = 0; #endif /* SWM_XRR_HAS_CRTC */ struct swm_region *r; + struct ws_win *win; int num_screens; xcb_randr_get_screen_resources_current_cookie_t src; xcb_randr_get_screen_resources_current_reply_t *srr; @@ -8752,9 +8768,6 @@ scan_xrandr(int i) xcb_destroy_window(conn, r->id); TAILQ_REMOVE(&screens[i].rl, r, entry); TAILQ_INSERT_TAIL(&screens[i].orl, r, entry); - - if (r->s->r_focus == r) - r->s->r_focus = NULL; } outputs = 0; @@ -8804,6 +8817,16 @@ scan_xrandr(int i) screen->height_in_pixels); out: + /* Cleanup unused previously visible workspaces. */ + TAILQ_FOREACH(r, &screens[i].orl, entry) { + TAILQ_FOREACH(win, &r->ws->winlist, entry) + unmap_window(win); + + /* The screen shouldn't focus on an unused region. */ + if (screens[i].r_focus == r) + screens[i].r_focus = NULL; + } + DNPRINTF(SWM_D_MISC, "scan_xrandr: done.\n"); } @@ -8833,16 +8856,19 @@ screenchange(xcb_randr_screen_change_notify_event_t *e) for (i = 0; i < num_screens; i++) { TAILQ_FOREACH(r, &screens[i].rl, entry) bar_setup(r); + } - if (screens[0].r_focus == NULL) { - /* Focus on first region. */ - r = TAILQ_FIRST(&screens[0].rl); - if (r) + stack(); + + /* Make sure a region has focus on each screen. */ + for (i = 0; i < num_screens; i++) { + if (screens[i].r_focus == NULL) { + r = TAILQ_FIRST(&screens[i].rl); + if (r != NULL) focus_region(r); } } - stack(); bar_draw(); focus_flush(); }