X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=37cdf4810e5edef8489cb5037410a4dd79af86fc;hb=b4f18a38d0b1cf8c0ee85e0366ab4caa4cc00560;hp=718c5d5e22627e68eb98334661770d31f26c9b24;hpb=bf9901fca703621db2c07b2ee7f7169c6b4b1129;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 718c5d5..37cdf48 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -1159,16 +1159,16 @@ setscreencolor(char *val, int i, int c) screens[i - 1].c[c].color = name_to_color(val); free(screens[i - 1].c[c].name); if ((screens[i - 1].c[c].name = strdup(val)) == NULL) - errx(1, "strdup"); + err(1, "strdup"); } else if (i == -1) { for (i = 0; i < ScreenCount(display); i++) { screens[i].c[c].color = name_to_color(val); free(screens[i].c[c].name); if ((screens[i].c[c].name = strdup(val)) == NULL) - errx(1, "strdup"); + err(1, "strdup"); } } else - errx(1, "invalid screen index: %d out of bounds (maximum %d)\n", + errx(1, "invalid screen index: %d out of bounds (maximum %d)", i, ScreenCount(display)); } @@ -1201,14 +1201,14 @@ custom_region(char *val) if (sscanf(val, "screen[%u]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5) errx(1, "invalid custom region, " - "should be 'screen[]:x++\n"); + "should be 'screen[]:x++"); if (sidx < 1 || sidx > ScreenCount(display)) - errx(1, "invalid screen index: %d out of bounds (maximum %d)\n", + errx(1, "invalid screen index: %d out of bounds (maximum %d)", sidx, ScreenCount(display)); sidx--; if (w < 1 || h < 1) - errx(1, "region %ux%u+%u+%u too small\n", w, h, x, y); + errx(1, "region %ux%u+%u+%u too small", w, h, x, y); if (x > DisplayWidth(display, sidx) || y > DisplayHeight(display, sidx) || @@ -1475,9 +1475,9 @@ bar_refresh(void) socket_setnonblock(bar_pipe[0]); socket_setnonblock(bar_pipe[1]); /* XXX hmmm, really? */ if (dup2(bar_pipe[0], 0) == -1) - errx(1, "dup2"); + err(1, "dup2"); if (dup2(bar_pipe[1], 1) == -1) - errx(1, "dup2"); + err(1, "dup2"); if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) err(1, "could not disable SIGPIPE"); switch (bar_pid = fork()) { @@ -1526,7 +1526,7 @@ bar_setup(struct swm_region *r) } } if (bar_fonts[i] == NULL) - errx(1, "couldn't load font"); + errx(1, "couldn't load font"); if (bar_fs == NULL) errx(1, "couldn't create font structure"); @@ -1762,7 +1762,7 @@ restart(struct swm_region *r, union arg *args) /* disable alarm because the following code may not be interrupted */ alarm(0); if (signal(SIGALRM, SIG_IGN) == SIG_ERR) - errx(1, "can't disable alarm"); + err(1, "can't disable alarm"); bar_extra_stop(); bar_extra = 1; @@ -1945,12 +1945,12 @@ validate_win(struct ws_win *testwin) struct ws_win *win; struct workspace *ws; struct swm_region *r; - int i, x, foundit = 0; + int i, x; if (testwin == NULL) return (0); - for (i = 0, foundit = 0; i < ScreenCount(display); i++) + for (i = 0; i < ScreenCount(display); i++) TAILQ_FOREACH(r, &screens[i].rl, entry) for (x = 0; x < SWM_WS_MAX; x++) { ws = &r->s->ws[x]; @@ -1966,10 +1966,10 @@ validate_ws(struct workspace *testws) { struct swm_region *r; struct workspace *ws; - int foundit, i, x; + int i, x; /* validate all ws */ - for (i = 0, foundit = 0; i < ScreenCount(display); i++) + for (i = 0; i < ScreenCount(display); i++) TAILQ_FOREACH(r, &screens[i].rl, entry) for (x = 0; x < SWM_WS_MAX; x++) { ws = &r->s->ws[x]; @@ -2428,8 +2428,13 @@ focus_prev(struct ws_win *win) if (winfocus == NULL || winfocus == win) winfocus = TAILQ_NEXT(cur_focus, entry); done: - if (winfocus == winlostfocus || winfocus == NULL) + if (winfocus == winlostfocus || winfocus == NULL) { + /* update the bar so that title/class/name will be cleared. */ + if (window_name_enabled || title_name_enabled || title_class_enabled) + bar_update(); + return; + } focus_magic(winfocus); } @@ -2441,6 +2446,7 @@ focus(struct swm_region *r, union arg *args) struct ws_win *cur_focus = NULL; struct ws_win_list *wl = NULL; struct workspace *ws = NULL; + int all_iconics; if (!(r && r->ws)) return; @@ -2466,6 +2472,17 @@ focus(struct swm_region *r, union arg *args) return; ws = r->ws; wl = &ws->winlist; + if (TAILQ_EMPTY(wl)) + return; + /* make sure there is at least one uniconified window */ + all_iconics = 1; + TAILQ_FOREACH(winfocus, wl, entry) + if (winfocus->iconic == 0) { + all_iconics = 0; + break; + } + if (all_iconics) + return; winlostfocus = cur_focus; @@ -2484,9 +2501,13 @@ focus(struct swm_region *r, union arg *args) /* skip iconics */ if (winfocus && winfocus->iconic) { - TAILQ_FOREACH_REVERSE(winfocus, wl, ws_win_list, entry) + while (winfocus != cur_focus) { + if (winfocus == NULL) + winfocus = TAILQ_LAST(wl, ws_win_list); if (winfocus->iconic == 0) break; + winfocus = TAILQ_PREV(winfocus, ws_win_list, entry); + } } break; @@ -2498,9 +2519,13 @@ focus(struct swm_region *r, union arg *args) /* skip iconics */ if (winfocus && winfocus->iconic) { - TAILQ_FOREACH(winfocus, wl, entry) + while (winfocus != cur_focus) { + if (winfocus == NULL) + winfocus = TAILQ_FIRST(wl); if (winfocus->iconic == 0) break; + winfocus = TAILQ_NEXT(winfocus, entry); + } } break; @@ -2513,8 +2538,13 @@ focus(struct swm_region *r, union arg *args) default: return; } - if (winfocus == winlostfocus || winfocus == NULL) + if (winfocus == winlostfocus || winfocus == NULL) { + /* update the bar so that title/class/name will be cleared. */ + if (window_name_enabled || title_name_enabled || title_class_enabled) + bar_update(); + return; + } focus_magic(winfocus); } @@ -2523,13 +2553,10 @@ void cycle_layout(struct swm_region *r, union arg *args) { struct workspace *ws = r->ws; - struct ws_win *winfocus; union arg a; DNPRINTF(SWM_D_EVENT, "cycle_layout: workspace: %d\n", ws->idx); - winfocus = ws->focus; - ws->cur_layout++; if (ws->cur_layout->l_stack == NULL) ws->cur_layout = &layouts[0]; @@ -3103,7 +3130,7 @@ send_to_ws(struct swm_region *r, union arg *args) unsigned char ws_idx_str[SWM_PROPLEN]; union arg a; - if (r && r->ws) + if (r && r->ws && r->ws->focus) win = r->ws->focus; else return; @@ -3131,6 +3158,8 @@ send_to_ws(struct swm_region *r, union arg *args) unmap_window(win); TAILQ_REMOVE(&ws->winlist, win, entry); TAILQ_INSERT_TAIL(&nws->winlist, win, entry); + if (TAILQ_EMPTY(&ws->winlist)) + r->ws->focus = NULL; win->ws = nws; /* Try to update the window's workspace property */ @@ -3266,14 +3295,11 @@ uniconify(struct swm_region *r, union arg *args) void name_workspace(struct swm_region *r, union arg *args) { - struct workspace *ws; FILE *lfile; DNPRINTF(SWM_D_MISC, "name_workspace\n"); - if (r && r->ws) - ws = r->ws; - else + if (r == NULL) return; search_r = r; @@ -3452,7 +3478,6 @@ search_resp_name_workspace(char *resp, unsigned long len) strerror(errno)); return; } - ws->name[len - 1] = '\0'; } } @@ -3472,7 +3497,6 @@ search_resp_search_workspace(char *resp, unsigned long len) strerror(errno)); return; } - q[len - 1] = '\0'; p = strchr(q, ':'); if (p != NULL) *p = '\0'; @@ -3504,7 +3528,7 @@ search_resp_search_window(char *resp, unsigned long len) strerror(errno)); return; } - s[len - 1] = '\0'; + idx = strtonum(s, 1, INT_MAX, &errstr); if (errstr) { DNPRINTF(SWM_D_MISC, "window idx is %s: %s", @@ -3546,6 +3570,12 @@ search_do_resp(void) goto done; } resp[rbytes] = '\0'; + + /* XXX: + * Older versions of dmenu (Atleast pre 4.4.1) do not send a + * newline, so work around that by sanitizing the resp now. + */ + resp[strcspn(resp, "\n")] = '\0'; len = strlen(resp); switch (search_resp_action) { @@ -3816,9 +3846,7 @@ move_window(struct ws_win *win) { unsigned int mask; XWindowChanges wc; - struct swm_region *r; - r = root_to_region(win->wa.root); bzero(&wc, sizeof wc); mask = CWX | CWY; wc.x = win->g.x; @@ -4292,9 +4320,9 @@ spawn_select(struct swm_region *r, union arg *args, char *spawn_name, int *pid) break; case 0: /* child */ if (dup2(select_list_pipe[0], 0) == -1) - errx(1, "dup2"); + err(1, "dup2"); if (dup2(select_resp_pipe[1], 1) == -1) - errx(1, "dup2"); + err(1, "dup2"); close(select_list_pipe[1]); close(select_resp_pipe[0]); spawn(r->ws->idx, &a, 0); @@ -4727,7 +4755,7 @@ setup_keys(void) setkeybinding(MODKEY|ShiftMask, XK_bracketright,kf_move_down, NULL); setkeybinding(MODKEY|ShiftMask, XK_slash, kf_name_workspace,NULL); setkeybinding(MODKEY, XK_slash, kf_search_workspace,NULL); - setkeybinding(MODKEY, XK_s, kf_search_win, NULL); + setkeybinding(MODKEY, XK_f, kf_search_win, NULL); #ifdef SWM_DEBUG setkeybinding(MODKEY|ShiftMask, XK_d, kf_dumpwins, NULL); #endif @@ -5077,7 +5105,7 @@ setconfvalue(char *selector, char *value, int flags) else if (!strcmp(value, "synergy")) focus_mode = SWM_FOCUS_SYNERGY; else - err(1, "focus_mode"); + errx(1, "focus_mode"); break; case SWM_S_DISABLE_BORDER: disable_border = atoi(value); @@ -5168,10 +5196,10 @@ setautorun(char *selector, char *value, int flags) bzero(s, sizeof s); if (sscanf(value, "ws[%d]:%1023c", &ws_id, s) != 2) - errx(1, "invalid autorun entry, should be 'ws[]:command'\n"); + errx(1, "invalid autorun entry, should be 'ws[]:command'"); ws_id--; if (ws_id < 0 || ws_id >= SWM_WS_MAX) - errx(1, "autorun: invalid workspace %d\n", ws_id + 1); + errx(1, "autorun: invalid workspace %d", ws_id + 1); /* * This is a little intricate @@ -5233,10 +5261,10 @@ setlayout(char *selector, char *value, int flags) &ws_id, &mg, &ma, &si, &raise, s) != 6) errx(1, "invalid layout entry, should be 'ws[]:" "::::" - "'\n"); + "'"); ws_id--; if (ws_id < 0 || ws_id >= SWM_WS_MAX) - errx(1, "layout: invalid workspace %d\n", ws_id + 1); + errx(1, "layout: invalid workspace %d", ws_id + 1); if (!strcasecmp(s, "vertical")) st = SWM_V_STACK; @@ -5247,7 +5275,7 @@ setlayout(char *selector, char *value, int flags) else errx(1, "invalid layout entry, should be 'ws[]:" "::::" - "'\n"); + "'"); for (i = 0; i < ScreenCount(display); i++) { ws = (struct workspace *)&screens[i].ws; @@ -5563,7 +5591,7 @@ manage_window(Window id) } if ((win = calloc(1, sizeof(struct ws_win))) == NULL) - errx(1, "calloc: failed to allocate memory for new window"); + err(1, "calloc: failed to allocate memory for new window"); win->id = id; @@ -6188,8 +6216,8 @@ propertynotify(XEvent *e) } switch (ev->atom) { - case XA_WM_NORMAL_HINTS: #if 0 + case XA_WM_NORMAL_HINTS: long mask; XGetWMNormalHints(display, win->id, &win->sh, &mask); fprintf(stderr, "normal hints: flag 0x%x\n", win->sh.flags); @@ -6201,6 +6229,11 @@ propertynotify(XEvent *e) XMoveResizeWindow(display, win->id, win->g.x, win->g.y, win->g.w, win->g.h); #endif + case XA_WM_CLASS: + if (title_name_enabled || title_class_enabled) + bar_update(); + break; + case XA_WM_NAME: if (window_name_enabled) bar_update(); break; @@ -6395,7 +6428,7 @@ new_region(struct swm_screen *s, int x, int y, int w, int h) ws = r->ws; } else if ((r = calloc(1, sizeof(struct swm_region))) == NULL) - errx(1, "calloc: failed to allocate memory for screen"); + err(1, "calloc: failed to allocate memory for screen"); /* if we don't have a workspace already, find one */ if (ws == NULL) { @@ -6407,7 +6440,7 @@ new_region(struct swm_screen *s, int x, int y, int w, int h) } if (ws == NULL) - errx(1, "no free workspaces\n"); + errx(1, "no free workspaces"); X(r) = x; Y(r) = y; @@ -6496,7 +6529,7 @@ screenchange(XEvent *e) { if (screens[i].root == xe->root) break; if (i >= ScreenCount(display)) - errx(1, "screenchange: screen not found\n"); + errx(1, "screenchange: screen not found"); /* brute force for now, just re-enumerate the regions */ scan_xrandr(i); @@ -6564,7 +6597,7 @@ setup_screens(void) if ((screens = calloc(ScreenCount(display), sizeof(struct swm_screen))) == NULL) - errx(1, "calloc: screens"); + err(1, "calloc: screens"); /* initial Xrandr setup */ xrandr_support = XRRQueryExtension(display, @@ -6635,7 +6668,7 @@ setup_globals(void) if ((spawn_term[0] = strdup("xterm")) == NULL) err(1, "setup_globals: strdup"); if ((clock_format = strdup("%a %b %d %R %Z %Y")) == NULL) - errx(1, "strdup"); + err(1, "strdup"); } void