X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=796153b47edfa3db573b016ad62abfcf9b179884;hb=3ce4ba02b4120821833b08ca9f7829c6b723c3e4;hp=1002ee6cf1b6233c4148f54fb26d39fa6fa21c43;hpb=325fce8801030f2d1a729e0310d801a42b310f8b;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 1002ee6..796153b 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -241,8 +241,7 @@ struct search_window { Window indicator; }; TAILQ_HEAD(search_winlist, search_window); - -struct search_winlist search_wl; +struct search_winlist search_wl; /* search actions */ enum { @@ -253,6 +252,11 @@ enum { SWM_SEARCH_SEARCH_WINDOW }; +#define SWM_STACK_TOP (0) +#define SWM_STACK_BOTTOM (1) +#define SWM_STACK_ABOVE (2) +#define SWM_STACK_BELOW (3) + /* dialog windows */ double dialog_ratio = 0.6; /* status bar */ @@ -264,7 +268,8 @@ double dialog_ratio = 0.6; #define SWM_BAR_FONTS "-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*," \ "-*-profont-*-*-*-*-*-*-*-*-*-*-*-*," \ "-*-times-medium-r-*-*-*-*-*-*-*-*-*-*," \ - "-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*" + "-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*," \ + "-*-*-*-r-*--*-*-*-*-*-*-*-*" #ifdef X_HAVE_UTF8_STRING #define DRAWSTRING(x...) Xutf8DrawString(x) @@ -295,6 +300,10 @@ int title_name_enabled = 0; int title_class_enabled = 0; int window_name_enabled = 0; int focus_mode = SWM_FOCUS_DEFAULT; +int focus_close = SWM_STACK_BELOW; +int focus_close_wrap = 1; +int focus_default = SWM_STACK_TOP; +int spawn_position = SWM_STACK_TOP; int disable_border = 0; int border_width = 1; int verbose_layout = 0; @@ -466,7 +475,6 @@ struct swm_screen { GC bar_gc; }; struct swm_screen *screens; -int num_screens; /* args to functions */ union arg { @@ -598,11 +606,11 @@ get_property(Window id, Atom atom, long count, Atom type, unsigned long *nitems, &real, &format, nitems_ret, nbytes_ret, data); if (status != Success) - return False; + return (False); if (real != type) - return False; + return (False); - return True; + return (True); } void @@ -670,7 +678,7 @@ setup_ewmh(void) for (j = 0; j < LENGTH(ewmh); j++) XChangeProperty(display, screens[i].root, sup_list, XA_ATOM, 32, - PropModeAppend, (unsigned char *)&ewmh[j].atom,1); + PropModeAppend, (unsigned char *)&ewmh[j].atom, 1); } } @@ -753,10 +761,10 @@ ewmh_set_win_fullscreen(struct ws_win *win, int fs) struct swm_geometry rg; if (!win->ws->r) - return 0; + return (0); if (!win->floating) - return 0; + return (0); DNPRINTF(SWM_D_MISC, "ewmh_set_win_fullscreen: window: 0x%lx, " "fullscreen %s\n", win->id, YESNO(fs)); @@ -777,7 +785,7 @@ ewmh_set_win_fullscreen(struct ws_win *win, int fs) } } - return 1; + return (1); } void @@ -1018,7 +1026,7 @@ geteventname(XEvent *e) name = "Unknown"; } - return name; + return (name); } char * @@ -1034,7 +1042,7 @@ xrandr_geteventname(XEvent *e) name = "Unknown"; } - return name; + return (name); } void @@ -1345,32 +1353,24 @@ void bar_class_name(char *s, ssize_t sz, struct ws_win *cur_focus) { int do_class, do_name; - Status status; - XClassHint *xch = NULL; + XClassHint *ch; - if ((title_name_enabled == 1 || title_class_enabled == 1) && - cur_focus != NULL) { - if ((xch = XAllocClassHint()) == NULL) - goto out; - status = XGetClassHint(display, cur_focus->id, xch); - if (status == BadWindow || status == BadAlloc) - goto out; - do_class = (title_class_enabled && xch->res_class != NULL); - do_name = (title_name_enabled && xch->res_name != NULL); - if (do_class) - strlcat(s, xch->res_class, sz); - if (do_class && do_name) - strlcat(s, ":", sz); - if (do_name) - strlcat(s, xch->res_name, sz); - strlcat(s, " ", sz); - } -out: - if (xch) { - XFree(xch->res_name); - XFree(xch->res_class); - XFree(xch); - } + if (title_name_enabled == 0 && title_class_enabled == 0) + return; + if (cur_focus == NULL) + return; + + ch = &cur_focus->ch; + do_class = (title_class_enabled && ch->res_class != NULL); + do_name = (title_name_enabled && ch->res_name != NULL); + + if (do_class) + strlcat(s, ch->res_class, sz); + if (do_class && do_name) + strlcat(s, ":", sz); + if (do_name) + strlcat(s, ch->res_name, sz); + strlcat(s, " ", sz); } void @@ -1488,7 +1488,7 @@ bar_update(void) if (stack_enabled) stack = r->ws->stacker; - snprintf(loc, sizeof loc, + snprintf(loc, sizeof loc, "%d:%d %s %s %s%s %s %s", x++, r->ws->idx + 1, stack, ws, s, cn, bar_ext, bar_vertext); @@ -2158,7 +2158,7 @@ unfocus_win(struct ws_win *win) XChangeProperty(display, win->s->root, ewmh[_NET_ACTIVE_WINDOW].atom, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&none,1); + PropModeReplace, (unsigned char *)&none, 1); } void @@ -2234,7 +2234,7 @@ focus_win(struct ws_win *win) XChangeProperty(display, win->s->root, ewmh[_NET_ACTIVE_WINDOW].atom, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win->id,1); + PropModeReplace, (unsigned char *)&win->id, 1); } bar_check_opts(); @@ -2475,7 +2475,6 @@ swapwin(struct swm_region *r, union arg *args) if (target == source) { if (source->ws->focus_prev != NULL && source->ws->focus_prev != target) - source = source->ws->focus_prev; else return; @@ -2510,8 +2509,6 @@ focus_prev(struct ws_win *win) struct ws_win_list *wl = NULL; struct workspace *ws = NULL; - DNPRINTF(SWM_D_FOCUS, "focus_prev: window: 0x%lx\n", WINID(win)); - if (!(win && win->ws)) return; @@ -2519,14 +2516,15 @@ focus_prev(struct ws_win *win) wl = &ws->winlist; cur_focus = ws->focus; + DNPRINTF(SWM_D_FOCUS, "focus_prev: window: 0x%lx, cur_focus: 0x%lx\n", + WINID(win), WINID(cur_focus)); + /* pickle, just focus on whatever */ if (cur_focus == NULL) { /* use prev_focus if valid */ if (ws->focus_prev && ws->focus_prev != cur_focus && find_window(WINID(ws->focus_prev))) winfocus = ws->focus_prev; - if (winfocus == NULL) - winfocus = TAILQ_FIRST(wl); goto done; } @@ -2547,14 +2545,44 @@ focus_prev(struct ws_win *win) goto done; } - if (cur_focus == win) - winfocus = TAILQ_PREV(win, ws_win_list, entry); - if (winfocus == NULL) - winfocus = TAILQ_LAST(wl, ws_win_list); - if (winfocus == NULL || winfocus == win) - winfocus = TAILQ_NEXT(cur_focus, entry); + DNPRINTF(SWM_D_FOCUS, "focus_prev: focus_close: %d\n", focus_close); + if (winfocus == NULL || winfocus == win) { + switch (focus_close) { + case SWM_STACK_BOTTOM: + winfocus = TAILQ_FIRST(wl); + break; + case SWM_STACK_TOP: + winfocus = TAILQ_LAST(wl, ws_win_list); + break; + case SWM_STACK_ABOVE: + if ((winfocus = TAILQ_NEXT(cur_focus, entry)) == NULL) { + if (focus_close_wrap) + winfocus = TAILQ_FIRST(wl); + else + winfocus = TAILQ_PREV(cur_focus, + ws_win_list, entry); + } + break; + case SWM_STACK_BELOW: + if ((winfocus = TAILQ_PREV(cur_focus, ws_win_list, + entry)) == NULL) { + if (focus_close_wrap) + winfocus = TAILQ_LAST(wl, ws_win_list); + else + winfocus = TAILQ_NEXT(cur_focus, entry); + } + break; + } + } done: + if (winfocus == NULL) { + if (focus_default == SWM_STACK_TOP) + winfocus = TAILQ_LAST(wl, ws_win_list); + else + winfocus = TAILQ_FIRST(wl); + } + focus_magic(winfocus); } @@ -3738,16 +3766,16 @@ floating_toggle_win(struct ws_win *win) struct swm_region *r; if (win == NULL) - return 0; + return (0); if (!win->ws->r) - return 0; + return (0); r = win->ws->r; /* reject floating toggles in max stack mode */ if (win->ws->cur_layout == &layouts[SWM_MAX_STACK]) - return 0; + return (0); if (win->floating) { if (!win->floatmaxed) { @@ -3768,7 +3796,7 @@ floating_toggle_win(struct ws_win *win) ewmh_update_actions(win); - return 1; + return (1); } void @@ -5280,11 +5308,12 @@ enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_BAR_BORDER_WIDTH, SWM_S_STACK_ENABLED, SWM_S_CLOCK_ENABLED, SWM_S_CLOCK_FORMAT, SWM_S_CYCLE_EMPTY, SWM_S_CYCLE_VISIBLE, SWM_S_WORKSPACE_LIMIT, SWM_S_SS_ENABLED, SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED, - SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED, SWM_S_URGENT_ENABLED, - SWM_S_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, - SWM_S_BAR_FONT, SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, - SWM_S_SS_APP, SWM_S_DIALOG_RATIO, SWM_S_BAR_AT_BOTTOM, - SWM_S_VERBOSE_LAYOUT, SWM_S_BAR_JUSTIFY + SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED, + SWM_S_URGENT_ENABLED, SWM_S_FOCUS_MODE, SWM_S_FOCUS_CLOSE, + SWM_S_FOCUS_CLOSE_WRAP, SWM_S_FOCUS_DEFAULT, SWM_S_SPAWN_ORDER, + SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, SWM_S_BAR_FONT, + SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_SS_APP, SWM_S_DIALOG_RATIO, + SWM_S_BAR_AT_BOTTOM, SWM_S_VERBOSE_LAYOUT, SWM_S_BAR_JUSTIFY }; int @@ -5370,6 +5399,41 @@ setconfvalue(char *selector, char *value, int flags) else errx(1, "focus_mode"); break; + case SWM_S_FOCUS_CLOSE: + if (!strcmp(value, "first")) + focus_close = SWM_STACK_BOTTOM; + else if (!strcmp(value, "last")) + focus_close = SWM_STACK_TOP; + else if (!strcmp(value, "next")) + focus_close = SWM_STACK_ABOVE; + else if (!strcmp(value, "previous")) + focus_close = SWM_STACK_BELOW; + else + errx(1, "focus_close"); + break; + case SWM_S_FOCUS_CLOSE_WRAP: + focus_close_wrap = atoi(value); + break; + case SWM_S_FOCUS_DEFAULT: + if (!strcmp(value, "last")) + focus_default = SWM_STACK_TOP; + else if (!strcmp(value, "first")) + focus_default = SWM_STACK_BOTTOM; + else + errx(1, "focus_default"); + break; + case SWM_S_SPAWN_ORDER: + if (!strcmp(value, "first")) + spawn_position = SWM_STACK_BOTTOM; + else if (!strcmp(value, "last")) + spawn_position = SWM_STACK_TOP; + else if (!strcmp(value, "next")) + spawn_position = SWM_STACK_ABOVE; + else if (!strcmp(value, "previous")) + spawn_position = SWM_STACK_BELOW; + else + errx(1, "spawn_position"); + break; case SWM_S_DISABLE_BORDER: disable_border = atoi(value); break; @@ -5619,6 +5683,10 @@ struct config_option configopt[] = { { "title_class_enabled", setconfvalue, SWM_S_TITLE_CLASS_ENABLED }, { "title_name_enabled", setconfvalue, SWM_S_TITLE_NAME_ENABLED }, { "focus_mode", setconfvalue, SWM_S_FOCUS_MODE }, + { "focus_close", setconfvalue, SWM_S_FOCUS_CLOSE }, + { "focus_close_wrap", setconfvalue, SWM_S_FOCUS_CLOSE_WRAP }, + { "focus_default", setconfvalue, SWM_S_FOCUS_DEFAULT }, + { "spawn_position", setconfvalue, SWM_S_SPAWN_ORDER }, { "disable_border", setconfvalue, SWM_S_DISABLE_BORDER }, { "border_width", setconfvalue, SWM_S_BORDER_WIDTH }, { "autorun", setautorun, 0 }, @@ -5858,12 +5926,27 @@ manage_window(Window id) DNPRINTF(SWM_D_MISC, "manage_window: previously unmanaged " "window: 0x%lx\n", win->id); TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry); - if (win->transient) { + if (win->transient) set_child_transient(win, &trans); - } if (trans && (ww = find_window(trans))) + + if (trans && (ww = find_window(trans))) TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry); - else + else if ((ww = win->ws->focus) && + spawn_position == SWM_STACK_ABOVE) + TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); + else if (ww && spawn_position == SWM_STACK_BELOW) + TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); + else switch (spawn_position) { + default: + case SWM_STACK_TOP: + case SWM_STACK_ABOVE: TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry); + break; + case SWM_STACK_BOTTOM: + case SWM_STACK_BELOW: + TAILQ_INSERT_HEAD(&win->ws->winlist, win, entry); + } + ewmh_update_actions(win); return (win); } @@ -5950,6 +6033,8 @@ manage_window(Window id) win->s = r->s; /* this never changes */ if (trans && (ww = find_window(trans))) TAILQ_INSERT_AFTER(&ws->winlist, ww, win, entry); + else if (spawn_position == SWM_STACK_ABOVE && win->ws->focus) + TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); else TAILQ_INSERT_TAIL(&ws->winlist, win, entry); @@ -6214,9 +6299,8 @@ configurerequest(XEvent *e) wc.sibling = ev->above; wc.stack_mode = ev->detail; XConfigureWindow(display, ev->window, ev->value_mask, &wc); - } else { + } else config_win(win, ev); - } } void @@ -6438,6 +6522,13 @@ mapnotify(XEvent *e) win = manage_window(ev->window); if (win) set_win_state(win, NormalState); + + /* + * focus_win can only set input focus on a mapped window. + * make sure the window really has focus since it is just being mapped. + */ + if (win->ws->focus == win) + focus_win(win); } void @@ -6985,9 +7076,9 @@ workaround(void) screens[i].c[SWM_S_COLOR_UNFOCUS].color); XChangeProperty(display, root, netwmcheck, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win,1); + PropModeReplace, (unsigned char *)&win, 1); XChangeProperty(display, win, netwmcheck, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win,1); + PropModeReplace, (unsigned char *)&win, 1); XChangeProperty(display, win, netwmname, utf8_string, 8, PropModeReplace, (unsigned char*)"LG3D", strlen("LG3D")); }