shod

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 6c85883fdcc4ef9eed0b48bc488b5afdcb4df319
parent 4dad8bf8094aa16cd09ede1bc0eb932cbe00d9a6
Author: Lucas de Sena <lucas@seninha.org>
Date:   Fri, 20 Jan 2023 18:40:34 -0300

Bind alt-tab again

Diffstat:
MREADME | 5+++--
Mshod.1 | 56++++++++++++++++++++++++++++++--------------------------
Mshod.c | 7+++++--
Mshodc.c | 20+++++---------------
Mxevents.c | 19+++++++++++++++----
5 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/README b/README @@ -22,8 +22,9 @@ on the screen. shod works via mouse, possibly with a given modifier (Alt by default), and by responding to client messages sent by the shodc utility (shod's -remote controller). Shod does no keybinding by itself and relies on -other applications (such as sxhkd) for that. +remote controller). With the exception of the alt-tab combination for +cycling windows, shod does no keybinding by itself and relies on other +applications (such as sxhkd) for that. shod has no default bar. However shod has a dock where dockapps (small windows commonly used on other window managers like Window Maker) can diff --git a/shod.1 b/shod.1 @@ -7,7 +7,7 @@ .Nd mouse-focused window manager .Sh SYNOPSIS .Nm shod -.Op Fl cdhs +.Op Fl cdhst .Op Fl m Ar keysym .Op Ar file .Pp @@ -17,8 +17,6 @@ .Nm shodc .Cm cycle .Op Fl s -.Op Fl a Ar altkey -.Op Fl t Ar tabkey .Nm shodc .Cm desk .Nm shodc @@ -124,6 +122,9 @@ or on most systems). .It Fl s Use sloppy focus rather than click-to-focus. +.It Fl t +Disable container cycling (aka +.Dq "alt-tab" No ). .El .Pp .Nm shodc @@ -145,30 +146,12 @@ If no argument is provided, close the active window. .Ss Cycle containers The .Cm cycle -operation cycles through the open containers on the current desktop. +operation initiates the cycling through the open containers on the current desktop. This cycling is generally called -.Qq "Alt-Tab" -and is initiated by pressing a key (usually -.Qq "Tab" ) -while a modifier key (usually -.Qq "Alt_L" ) -is pressed. -If the -.Qq "Shift" -modifier is also pressed, the cycling is performed in the opposite direction. -.Pp The options are as follows. -.Bl -tag -width Ds -.It Fl a Ar altkey -Use the key -.Ar altkey -as Alt. -.It Fl s -Initiate the cycling in the opposite direction. -.It Fl t Ar tabkey -Use the key -.Ar tabkey -as Tab. -.El +.Qq "alt-tab" . +Cycling is performed as +.Qq "Tab" +is pressed, and terminates when the modifier key is released. .Ss List desktops The .Cm desks @@ -520,6 +503,27 @@ or undoes this state. Each title bar has a right button. Clicking on the right title-bar button with the first mouse button closes the focused client or its top dialog. +.Pp +Containers can be cycled using the key provided by the +.Fl m +option +.No ( Cm Alt_L +by default) followed by the +.Cm Tab +key. +The +.Cm Tab +key can be further modified by +.Cm Shift +to cycle in the oposite direction. +This mechanism is usually called +.Dq "alt-tab" +because of the key combination that usually triggers it. +This mechanism can be turned off by invoking +.Nm shod +with the +.Fl t +command-line option. .Ss Dialog Windows that are transient for another managed windows (called its leader) are mapped in the center of the leader. diff --git a/shod.c b/shod.c @@ -35,7 +35,7 @@ struct Dock dock; static void usage(void) { - (void)fprintf(stderr, "usage: shod [-cdhs] [-m modifier] [file]\n"); + (void)fprintf(stderr, "usage: shod [-cdhst] [-m modifier] [file]\n"); exit(1); } @@ -119,7 +119,7 @@ getoptions(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "cdhm:s")) != -1) { + while ((c = getopt(argc, argv, "cdhm:st")) != -1) { switch (c) { case 'c': config.honorconfig = 1; @@ -137,6 +137,9 @@ getoptions(int argc, char *argv[]) case 's': config.sloppyfocus = 1; break; + case 't': + config.disablealttab = 1; + break; default: usage(); break; diff --git a/shodc.c b/shodc.c @@ -53,6 +53,7 @@ static void usage(void) { (void)fprintf(stderr, "usage: shodc close [WIN_ID]\n"); + (void)fprintf(stderr, " shodc cycle [-s]\n"); (void)fprintf(stderr, " shodc desks\n"); (void)fprintf(stderr, " shodc focus [-clrtbpnLRTBPN] [WIN_ID]\n"); (void)fprintf(stderr, " shodc geom [-X|-x N] [-Y|-y N] [-W|-w N] [-H|-h N] [WIN_ID]\n"); @@ -593,31 +594,20 @@ state(int argc, char *argv[]) static void cycle(int argc, char *argv[]) { - KeyCode alt, tab; - KeySym ksym; int c, shift; - alt = XKeysymToKeycode(dpy, XK_Alt_L); - tab = XKeysymToKeycode(dpy, XK_Tab); shift = 0; - while ((c = getopt(argc, argv, "a:st:")) != -1) { + while ((c = getopt(argc, argv, "s")) != -1) { switch (c) { - case 'a': - if ((ksym = XStringToKeysym(optarg)) == NoSymbol) - errx(1, "%s: unknown key", optarg); - alt = XKeysymToKeycode(dpy, ksym); - break; case 's': shift = 1; break; - case 't': - if ((ksym = XStringToKeysym(optarg)) == NoSymbol) - errx(1, "%s: unknown key", optarg); - tab = XKeysymToKeycode(dpy, ksym); + default: + usage(); break; } } - clientmsg(None, atoms[_SHOD_CYCLE], alt, tab, shift, 0, 0); + clientmsg(None, atoms[_SHOD_CYCLE], shift, 0, 0, 0, 0); } /* shodc: remote controller for shod */ diff --git a/xevents.c b/xevents.c @@ -699,7 +699,7 @@ manage(Window win, XRectangle rect, int ignoreunmap) /* perform container switching (aka alt-tab) */ static void -alttab(KeyCode alt, KeyCode tab, int shift) +alttab(int shift) { struct Container *c, *prevfocused; XEvent ev; @@ -720,13 +720,13 @@ alttab(KeyCode alt, KeyCode tab, int shift) copypixmap(ev.xexpose.window); break; case KeyPress: - if (ev.xkey.keycode == tab) { + if (ev.xkey.keycode == config.tabkeycode && isvalidstate(ev.xkey.state)) { containerbacktoplace(c, 1); c = containerraisetemp(c, isshiftstate(ev.xkey.state)); } break; case KeyRelease: - if (ev.xkey.keycode == config.altkeycode || ev.xkey.keycode == alt) + if (ev.xkey.keycode == config.altkeycode) goto done; break; } @@ -1390,7 +1390,7 @@ xeventclientmessage(XEvent *e) if (ev->message_type == atoms[_NET_CURRENT_DESKTOP]) { deskfocus(wm.selmon, ev->data.l[0]); } else if (ev->message_type == atoms[_SHOD_CYCLE]) { - alttab(ev->data.l[0], ev->data.l[1], ev->data.l[2]); + alttab(ev->data.l[0]); } else if (ev->message_type == atoms[_NET_SHOWING_DESKTOP]) { if (ev->data.l[0]) { deskshow(1); @@ -1659,6 +1659,9 @@ xeventkeypress(XEvent *e) XKeyPressedEvent *ev; ev = &e->xkey; + if (!config.disablealttab && ev->keycode == config.tabkeycode) { + alttab(ev->state & ShiftMask); + } if (ev->window == wm.wmcheckwin) { e->xkey.window = root; XSendEvent(dpy, root, False, KeyPressMask, e); @@ -1825,10 +1828,18 @@ setmod(void) warnx("could not get keycode from keysym"); return; } + if ((config.tabkeycode = XKeysymToKeycode(dpy, config.tabkeysym)) == 0) { + warnx("could not get keycode from keysym"); + return; + } if ((config.modifier = XkbKeysymToModifiers(dpy, config.altkeysym)) == 0) { warnx("could not get modifier from keysym"); return; } + if (config.disablealttab) + return; + XUngrabKey(dpy, config.tabkeycode, config.modifier, root); + XGrabKey(dpy, config.tabkeycode, config.modifier, root, False, GrabModeAsync, GrabModeAsync); } void (*xevents[LASTEvent])(XEvent *) = {