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:
M | README | | | 5 | +++-- |
M | shod.1 | | | 56 | ++++++++++++++++++++++++++++++-------------------------- |
M | shod.c | | | 7 | +++++-- |
M | shodc.c | | | 20 | +++++--------------- |
M | xevents.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 *) = {