X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=b96e6f47d5cc43f8be28d27b5c36e0925adfe671;hb=e126add24b56470c8dc0cd7d0ee0dd71de22fb9a;hp=602cbc24ac95b2aaa4f33767d65b3bdc00081f01;hpb=ccf8f495c4098874f74cfc2814d0902e7869d4de;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 602cbc2..b96e6f4 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -51,7 +51,8 @@ * DEALINGS IN THE SOFTWARE. */ -static const char *cvstag = "$scrotwm$"; +static const char *cvstag = + "$scrotwm$"; #define SWM_VERSION "0.9.30" @@ -310,6 +311,7 @@ struct layout { void (*l_stack)(struct workspace *, struct swm_geometry *); void (*l_config)(struct workspace *, int); u_int32_t flags; +#define SWM_L_FOCUSPREV (1<<0) #define SWM_L_MAPONFOCUS (1<<1) char *name; } layouts[] = { @@ -317,8 +319,8 @@ struct layout { { vertical_stack, vertical_config, 0, "[|]" }, { horizontal_stack, horizontal_config, 0, "[-]" }, { max_stack, NULL, - SWM_L_MAPONFOCUS, "[ ]"}, - { NULL, NULL, 0, NULL }, + SWM_L_MAPONFOCUS | SWM_L_FOCUSPREV, "[ ]" }, + { NULL, NULL, 0, NULL }, }; /* position of max_stack mode in the layouts array */ @@ -415,6 +417,7 @@ struct quirk { #define SWM_Q_ANYWHERE (1<<2) /* don't position this window */ #define SWM_Q_XTERM_FONTADJ (1<<3) /* adjust xterm fonts when resizing */ #define SWM_Q_FULLSCREEN (1<<4) /* remove border */ +#define SWM_Q_FOCUSPREV (1<<5) /* focus on caller */ }; int quirks_size = 0, quirks_length = 0; struct quirk *quirks = NULL; @@ -554,7 +557,8 @@ setup_ewmh(void) /* Report supported atoms */ XDeleteProperty(display, screens[i].root, sup_list); for (j = 0; j < LENGTH(ewmh); j++) - XChangeProperty(display, screens[i].root, sup_list, XA_ATOM, 32, + XChangeProperty(display, screens[i].root, + sup_list, XA_ATOM, 32, PropModeAppend, (unsigned char *)&ewmh[j].atom,1); } } @@ -740,7 +744,8 @@ ewmh_update_win_state(struct ws_win *win, long state, long action) win->manual = (win->ewmh_flags & SWM_F_MANUAL) != 0; if (state == ewmh[_NET_WM_STATE_FULLSCREEN].atom) if (changed) - if (!ewmh_set_win_fullscreen(win, win->ewmh_flags & EWMH_F_FULLSCREEN)) + if (!ewmh_set_win_fullscreen(win, + win->ewmh_flags & EWMH_F_FULLSCREEN)) win->ewmh_flags = orig_flags; /* revert */ XDeleteProperty(display, win->id, ewmh[_NET_WM_STATE].atom); @@ -783,8 +788,8 @@ ewmh_get_win_state(struct ws_win *win) if (win->manual) win->ewmh_flags |= SWM_F_MANUAL; - success = get_property(win->id, ewmh[_NET_WM_STATE].atom, (~0L), XA_ATOM, - &n, (unsigned char **)&states); + success = get_property(win->id, ewmh[_NET_WM_STATE].atom, + (~0L), XA_ATOM, &n, (unsigned char **)&states); if (!success) return; @@ -1107,7 +1112,8 @@ custom_region(char *val) y < 0 || y > DisplayHeight(display, sidx) || w + x > DisplayWidth(display, sidx) || h + y > DisplayHeight(display, sidx)) { - fprintf(stderr, "ignoring region %ux%u+%u+%u - not within screen boundaries " + fprintf(stderr, "ignoring region %ux%u+%u+%u " + "- not within screen boundaries " "(%ux%u)\n", w, h, x, y, DisplayWidth(display, sidx), DisplayHeight(display, sidx)); return; @@ -1360,12 +1366,14 @@ bar_setup(struct swm_region *r) if (bar_fs == NULL) errx(1, "couldn't create font structure"); - bar_height = bar_fs->ascent + bar_fs->descent + 1 + 2 * bar_border_width; + bar_height = bar_fs->ascent + bar_fs->descent + 1 + + 2 * bar_border_width; x = X(r); y = bar_at_bottom ? (Y(r) + HEIGHT(r) - bar_height) : Y(r); r->bar_window = XCreateSimpleWindow(display, - r->s->root, x, y, WIDTH(r) - 2 * bar_border_width, bar_height - 2 * bar_border_width, + r->s->root, x, y, WIDTH(r) - 2 * bar_border_width, + bar_height - 2 * bar_border_width, bar_border_width, r->s->c[SWM_S_COLOR_BAR_BORDER].color, r->s->c[SWM_S_COLOR_BAR].color); bar_gc = XCreateGC(display, r->bar_window, 0, &bar_gcv); @@ -1460,7 +1468,8 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) return; if (ev == NULL) { - DNPRINTF(SWM_D_MISC, "config_win: win %lu x %d y %d w %d h %d\n", + DNPRINTF(SWM_D_MISC, + "config_win: win %lu x %d y %d w %d h %d\n", win->id, win->g.x, win->g.y, win->g.w, win->g.h); ce.type = ConfigureNotify; @@ -1475,7 +1484,8 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.above = None; ce.override_redirect = False; } else { - DNPRINTF(SWM_D_MISC, "config_win: ev win %lu x %d y %d w %d h %d\n", + DNPRINTF(SWM_D_MISC, + "config_win: ev win %lu x %d y %d w %d h %d\n", ev->window, ev->x, ev->y, ev->width, ev->height); ce.type = ConfigureNotify; ce.display = ev->display; @@ -1773,7 +1783,7 @@ validate_win(struct ws_win *testwin) int i, x, foundit = 0; if (testwin == NULL) - return(0); + return (0); for (i = 0, foundit = 0; i < ScreenCount(display); i++) TAILQ_FOREACH(r, &screens[i].rl, entry) @@ -1901,6 +1911,13 @@ focus_win(struct ws_win *win) XGetInputFocus(display, &cur_focus, &rr); if ((cfw = find_window(cur_focus)) != NULL) unfocus_win(cfw); + else { + /* use larger hammer since the window was killed somehow */ + TAILQ_FOREACH(cfw, &win->ws->winlist, entry) + if (cfw->ws && cfw->ws->r && cfw->ws->r->s) + XSetWindowBorder(display, cfw->id, + cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color); + } win->ws->focus = win; @@ -1968,6 +1985,9 @@ switchws(struct swm_region *r, union arg *args) this_r->ws = new_ws; new_ws->r = this_r; + /* this is needed so that we can click on a window after a restart */ + unfocus_all(); + stack(); a.id = SWM_ARG_ID_FOCUSCUR; focus(new_ws->r, &a); @@ -2157,7 +2177,7 @@ swapwin(struct swm_region *r, union arg *args) source = source->ws->focus_prev; else return; - } + } if (target == NULL || source == NULL) return; source->ws->focus_prev = target; @@ -2215,17 +2235,25 @@ focus_prev(struct ws_win *win) goto done; } - /* try to focus on previously focused app */ - if (cur_focus != ws->focus_prev) - winfocus = ws->focus_prev; - else if (cur_focus != ws->focus) - winfocus = ws->focus; - else { - winfocus = TAILQ_PREV(win, ws_win_list, entry); - if (winfocus == NULL) - winfocus = TAILQ_LAST(wl, ws_win_list); + /* if in max_stack try harder */ + if ((win->quirks & SWM_Q_FOCUSPREV) || + (ws->cur_layout->flags & SWM_L_FOCUSPREV)) { + if (cur_focus != ws->focus_prev) + winfocus = ws->focus_prev; + else if (cur_focus != ws->focus) + winfocus = ws->focus; + else + winfocus = TAILQ_PREV(win, ws_win_list, entry); + if (winfocus) + 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); done: if (winfocus == winlostfocus || winfocus == NULL) return; @@ -2453,8 +2481,10 @@ stack_floater(struct ws_win *win, struct swm_region *r) * floaters and transients are auto-centred unless moved * or resized */ - win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2 - wc.border_width; - win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2 - wc.border_width; + win->g.x = r->g.x + (WIDTH(r) - win->g.w) / + 2 - wc.border_width; + win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / + 2 - wc.border_width; } /* win can be outside r if new r smaller than old r */ @@ -2544,7 +2574,8 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) return; TAILQ_FOREACH(win, &ws->winlist, entry) - if (win->transient == 0 && win->floating == 0 && win->iconic == 0) + if (win->transient == 0 && win->floating == 0 + && win->iconic == 0) break; if (win == NULL) @@ -2593,7 +2624,8 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) } else { msize = -2; colno = split = winno / stacks; - win_g.w = ((r_g.w - (stacks * 2 * border_width) + 2 * border_width) / stacks); + win_g.w = ((r_g.w - (stacks * 2 * border_width) + + 2 * border_width) / stacks); } hrh = r_g.h / colno; extra = r_g.h - (colno * hrh); @@ -2623,10 +2655,11 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) win_g.x = r_g.x; else win_g.x += win_g.w + 2 * border_width; - win_g.w = (r_g.w - msize - (stacks * 2 * border_width)) / stacks; + win_g.w = (r_g.w - msize - + (stacks * 2 * border_width)) / stacks; if (s == 1) - win_g.w += (r_g.w - msize - (stacks * 2 * border_width)) % - stacks; + win_g.w += (r_g.w - msize - + (stacks * 2 * border_width)) % stacks; s--; j = 0; } @@ -3194,7 +3227,6 @@ resize(struct ws_win *win, union arg *args) Time time = 0; struct swm_region *r = win->ws->r; int relx, rely; - union arg a; DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %lu\n", @@ -3210,9 +3242,7 @@ resize(struct ws_win *win, union arg *args) win->manual = 1; ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom, _NET_WM_STATE_ADD); - /* raise the window = move to last in window list */ - a.id = SWM_ARG_ID_MOVELAST; - swapwin(r, &a); + stack(); if (focus_mode == SWM_FOCUS_DEFAULT) drain_enter_notify(); @@ -3236,7 +3266,7 @@ resize(struct ws_win *win, union arg *args) do { XMaskEvent(display, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); - switch(ev.type) { + switch (ev.type) { case ConfigureRequest: case Expose: case MapRequest: @@ -3306,7 +3336,6 @@ move(struct ws_win *win, union arg *args) XEvent ev; Time time = 0; struct swm_region *r = win->ws->r; - union arg a; DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %lu\n", win->id, win->floating, win->transient); @@ -3317,16 +3346,12 @@ move(struct ws_win *win, union arg *args) win->manual = 1; if (win->floating == 0 && !win->transient) { - win->floating = 1; ewmh_update_win_state(win, ewmh[_NET_WM_STATE_ABOVE].atom, _NET_WM_STATE_ADD); } ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom, _NET_WM_STATE_ADD); - /* raise the window = move to last in window list */ - a.id = SWM_ARG_ID_MOVELAST; - swapwin(r, &a); stack(); if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync, @@ -3336,7 +3361,7 @@ move(struct ws_win *win, union arg *args) do { XMaskEvent(display, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); - switch(ev.type) { + switch (ev.type) { case ConfigureRequest: case Expose: case MapRequest: @@ -3910,7 +3935,8 @@ strdupsafe(char *str) } void -setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name) +setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid, + char *spawn_name) { int i, j; DNPRINTF(SWM_D_KEY, "setkeybinding: enter %s [%s]\n", @@ -4113,7 +4139,7 @@ updatenumlockmask(void) for (i = 0; i < 8; i++) for (j = 0; j < modmap->max_keypermod; j++) if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(display, XK_Num_Lock)) + == XKeysymToKeycode(display, XK_Num_Lock)) numlockmask = (1 << i); XFreeModifiermap(modmap); @@ -4175,6 +4201,7 @@ const char *quirkname[] = { "ANYWHERE", "XTERM_FONTADJ", "FULLSCREEN", + "FOCUSPREV", }; /* SWM_Q_WS: retain '|' for back compat for now (2009-08-11) */ @@ -4195,7 +4222,8 @@ parsequirks(char *qstr, unsigned long *quirk) cp += (long)strspn(cp, SWM_Q_WS); for (i = 0; i < LENGTH(quirkname); i++) { if (!strncasecmp(name, quirkname[i], SWM_QUIRK_LEN)) { - DNPRINTF(SWM_D_QUIRK, "parsequirks: %s\n", name); + DNPRINTF(SWM_D_QUIRK, + "parsequirks: %s\n", name); if (i == 0) { *quirk = 0; return (0); @@ -4266,7 +4294,8 @@ setquirk(const char *class, const char *name, const int quirk) } else if (quirks_length == quirks_size) { quirks_size *= 2; DNPRINTF(SWM_D_QUIRK, "setquirk: grow list %d\n", quirks_size); - quirks = realloc(quirks, (size_t)quirks_size * sizeof(struct quirk)); + quirks = realloc(quirks, + (size_t)quirks_size * sizeof(struct quirk)); if (!quirks) { fprintf(stderr, "setquirk: realloc failed\n"); perror(" failed"); @@ -4309,7 +4338,7 @@ setconfquirk(char *selector, char *value, int flags) void setup_quirks(void) { - setquirk("MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN); + setquirk("MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV); setquirk("OpenOffice.org 3.2", "VCLSalFrame", SWM_Q_FLOAT); setquirk("Firefox-bin", "firefox-bin", SWM_Q_TRANSSZ); setquirk("Firefox", "Dialog", SWM_Q_FLOAT); @@ -4327,13 +4356,14 @@ setup_quirks(void) /* conf file stuff */ #define SWM_CONF_FILE "scrotwm.conf" -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_SS_ENABLED, SWM_S_TERM_WIDTH, - SWM_S_TITLE_CLASS_ENABLED, SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_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 +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_SS_ENABLED, + SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED, + SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_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 }; int @@ -4952,8 +4982,8 @@ keypress(XEvent *e) keysym = XKeycodeToKeysym(display, (KeyCode)ev->keycode, 0); for (i = 0; i < keys_length; i++) if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keyfuncs[keys[i].funcid].func) { + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keyfuncs[keys[i].funcid].func) { if (keys[i].funcid == kf_spawn_custom) spawn_custom( root_to_region(ev->root), @@ -5397,7 +5427,8 @@ clientmessage(XEvent *e) XKillClient(display, win->id); } if (ev->message_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) { - DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_MOVERESIZE_WINDOW \n"); + DNPRINTF(SWM_D_EVENT, + "clientmessage: _NET_MOVERESIZE_WINDOW \n"); if (win->floating) { if (ev->data.l[0] & (1<<8)) /* x */ win->g.x = ev->data.l[1]; @@ -5417,7 +5448,8 @@ clientmessage(XEvent *e) DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_WM_STATE \n"); ewmh_update_win_state(win, ev->data.l[1], ev->data.l[0]); if (ev->data.l[2]) - ewmh_update_win_state(win, ev->data.l[2], ev->data.l[0]); + ewmh_update_win_state(win, ev->data.l[2], + ev->data.l[0]); stack(); }