Compare commits

..
16 Commits
Author SHA1 Message Date
BrunoCooper17 42cd641add MoveStack patch
This plugin allows you to move clients around in the stack and swap them
with the master. It emulates the behavior off mod+shift+j and mod+shift+k
in Xmonad. movestack(+1) will swap the client with the current focus with
the next client. movestack(-1) will swap the client with the current focus
with the previous client.
2026-01-22 09:30:17 +01:00
lupan 879aa682e8 apply patch dwm-winview-gaplessgrid-gridall-6.5.diff 2026-01-22 09:30:17 +01:00
explosion-mental 7aeb4c5156 shift-tools - shifttag, moves the current selected client to the adjacent tag - shifttagclients, moves the current selected client to the adjacent tag that has at least one client else acts as shifttag - shiftview, view adjacent tag - shiftviewclients, view the closes tag that has a client. If none acts as shiftview - shiftboth, shifttag and shiftview. Basically moves the window to the next/prev tag and follows it. - shiftswaptags, its a shift implementation on the swaptags function (see https://github.com/moizifty/DWM-Build/blob/65379c62640788881486401a0d8c79333751b02f/config.h#L48 for more details), which in short 'swaps tags' (swaps all clients with the clients on the adjacent tag). A pretty useful example of this is chosing a tag empty and sending all your clients to that tag. - swapfunction is the 'helper' function for the shiftswaptags. remember that these functions **shift**, which means you can go from tag 1 to 9 or 9 to 1. Also remember that the default argument is 1 and you can change it. 2026-01-20 21:05:18 +01:00
lupan 6e62aa05e3 agree: dwm-goback with dwm-warp 2026-01-20 21:05:18 +01:00
Max Schillinger 2b9fb819c9 add patch/function 'goback' 2026-01-20 21:05:18 +01:00
lupan 2577fc5da2 agree: dwm-autodarkmode with dwm-awesomebar 2026-01-20 21:05:18 +01:00
dimarogiv 2a169de7d8 With this patch you can focus on any of the currently open windows on the current tagset with just one key combination 2026-01-20 21:05:18 +01:00
Cyril Cressent 403292696a Port the uselessgap patch to 6.2 2026-01-20 21:05:18 +01:00
Jonas Dujava c797eece48 Warp patch
Warps the mouse cursor to the center of the currently focused
window or screen when the mouse cursor is
  (a) on a different screen, or
  (b) on top of a different window.

This version properly handles warping to windows that have not been
mapped yet (before it resulted in a change of the stack order).
See the discussion in (thanks goes to Bakkeby):
    https://github.com/bakkeby/patches/issues/60
2026-01-20 21:05:18 +01:00
lupan ab679e3203 apply dwm-xinerama-monitors-xorder-6.4.diff 2026-01-20 21:05:18 +01:00
lupan 1d83868c91 agree: change dwm-autodarkmode signal to USR1 and leave restarsig signal to HUP 2026-01-20 21:05:18 +01:00
lupan d55cfd204f apply patch dwm-autodarkmode-20250224-6.5.diff 2026-01-20 21:05:18 +01:00
lupan ca03ca3348 apply patch dwm-awesomebar-20230431-6.4.diff 2026-01-20 21:05:18 +01:00
lupan 79a8bed5b1 apply patch dwm-exitmenu-6.3.diff 2026-01-20 20:26:37 +01:00
Arda Atci bb014787b7 preserve clients on old tags when renewing dwm
By default, when dwm is recompiled-restarted all clients will
lose it's current tag and collapse to first tag. This patch preserves
clients on old tags, however note that layout order is not preserved.
2026-01-20 20:26:37 +01:00
Christopher Drelich 256cec2013 Modifies quit to handle restarts and adds SIGHUP and SIGTERM handlers.
Modified quit() to restart if it receives arg .i = 1
MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that.

Signal handlers were handled for SIGHUP and SIGTERM.
If dwm receives these signals it calls quit() with
arg .i = to 1 or 0, respectively.

To restart dwm:
MOD+CTRL+SHIFT+Q
or
kill -HUP dwmpid

To quit dwm cleanly:
MOD+SHIFT+Q
or
kill -TERM dwmpid
2026-01-20 20:26:37 +01:00
10 changed files with 126 additions and 781 deletions

No files matched your search

+80 -97
View File
@@ -2,8 +2,8 @@
#include "gaplessgrid.c"
/* appearance */
static const unsigned int borderpx = 2; /* border pixel of windows */
static const unsigned int gappx = 2; /* gaps between windows */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int gappx = 6; /* gaps between windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
@@ -14,23 +14,21 @@ static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
static const char col_border_focus_light[] = "#df8c20"; // hsl(34 75% 50%)
static const char col_border_focus_dark[] = "#b25e34"; // hsl(20 55% 45%)
static const char *colorsdark[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_border_focus_dark },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
[SchemeHid] = { col_cyan, col_gray1, col_cyan },
};
static const char *colorslight[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray1, col_gray3, col_gray2 },
[SchemeSel] = { col_cyan, col_gray4, col_border_focus_light },
[SchemeSel] = { col_cyan, col_gray4, col_cyan },
[SchemeHid] = { col_cyan, col_gray1, col_cyan },
};
/* tagging */
static const char *tags[] = { "q", "w", "e", "r", "t", "a", "s", "d", "f", "g", "z", "x", "c", "v", "b" };
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static const Rule rules[] = {
/* xprop(1):
@@ -58,104 +56,89 @@ static const Layout layouts[] = {
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
&((Keychord){1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }),
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static char dmenumon[8] = "0"; /* component of dmenu{dark,light}, manipulated in spawndmenu() */
static const char *dmenudark[] = { "dmenu_run", "-l", "10", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *dmenulight[] = { "dmenu_run", "-l", "10", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray3, "-nf", col_gray1, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "alacritty", NULL };
static const char *lockcmd[] = { "slock", NULL };
static const char *suspendcmd[] = { "systemctl", "suspend", NULL };
static const char *themecmd[] = { "lupan-set-theme", "toggle", NULL };
static char dmenumon[2] = "0"; /* component of dmenu{dark,light}, manipulated in spawndmenu() */
static const char *dmenudark[] = { "dmenu_run", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *dmenulight[] = { "dmenu_run", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray3, "-nf", col_gray1, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
#include "shift-tools.c"
#include "exitdwm.c"
#include "movestack.c"
static Keychord *keychords[] = {
/* Keys function argument */
&((Keychord){1, {{MODKEY, XK_p}}, spawndmenu, {0} }),
&((Keychord){1, {{MODKEY, XK_u}}, shiftview, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_u}}, shifttag, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_y}}, shifttag, { .i = -1 } }),
&((Keychord){1, {{MODKEY, XK_y}}, shiftview, { .i = -1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_b}}, togglebar, {0} }),
&((Keychord){1, {{MODKEY, XK_j}}, focusstackvis, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_k}}, focusstackvis, {.i = -1 } }),
&((Keychord){1, {{MODKEY|ControlMask, XK_j}}, focusstackhid, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ControlMask, XK_k}}, focusstackhid, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_d}}, incnmaster, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_h}}, shiftboth, {.i = -1} }),
&((Keychord){1, {{MODKEY|ControlMask, XK_h}}, shiftswaptags, {.i = -1} }),
&((Keychord){1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }),
&((Keychord){1, {{MODKEY|ControlMask, XK_l}}, shiftswaptags, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_l}}, shiftboth, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_j}}, movestack, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_k}}, movestack, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_Return}}, zoom, {0} }),
&((Keychord){1, {{MODKEY, XK_Tab}}, view, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_w}}, goback, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_c}}, killclient, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_t}}, setlayout, {.v = &layouts[0]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_f}}, setlayout, {.v = &layouts[1]} }),
&((Keychord){1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_g}}, setlayout, {.v = &layouts[3]} }),
&((Keychord){1, {{MODKEY, XK_space}}, setlayout, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} }),
&((Keychord){1, {{MODKEY, XK_0}}, view, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_s}}, show, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_s}}, showall, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ControlMask, XK_s}}, hide, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_q}}, quit, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ControlMask|ShiftMask, XK_q}}, quit, {1} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_e}}, exitdwm, {0} }),
&((Keychord){1, {{MODKEY, XK_o}}, winview, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_a}}, gridall, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_r}}, winviewmono, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {ControlMask|ShiftMask, XK_s}}, spawn, {.v = suspendcmd } }),
&((Keychord){1, {{MODKEY|ControlMask|ShiftMask, XK_l}}, spawn, {.v = lockcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {ControlMask|ShiftMask, XK_t}}, spawn, {.v = themecmd } }),
TAGKEYS( XK_q, 0)
TAGKEYS( XK_w, 1)
TAGKEYS( XK_e, 2)
TAGKEYS( XK_r, 3)
TAGKEYS( XK_t, 4)
TAGKEYS( XK_a, 5)
TAGKEYS( XK_s, 6)
TAGKEYS( XK_d, 7)
TAGKEYS( XK_f, 8)
TAGKEYS( XK_g, 9)
TAGKEYS( XK_z, 10)
TAGKEYS( XK_x, 11)
TAGKEYS( XK_c, 12)
TAGKEYS( XK_v, 13)
TAGKEYS( XK_b, 14)
&((Keychord){1, {{ ControlMask, XK_1}}, focusbynum, {.i = 0} }),
&((Keychord){1, {{ ControlMask, XK_2}}, focusbynum, {.i = 1} }),
&((Keychord){1, {{ ControlMask, XK_3}}, focusbynum, {.i = 2} }),
&((Keychord){1, {{ ControlMask, XK_4}}, focusbynum, {.i = 3} }),
&((Keychord){1, {{ ControlMask, XK_5}}, focusbynum, {.i = 4} }),
&((Keychord){1, {{ ControlMask, XK_6}}, focusbynum, {.i = 5} }),
&((Keychord){1, {{ ControlMask, XK_7}}, focusbynum, {.i = 6} }),
&((Keychord){1, {{ ControlMask, XK_8}}, focusbynum, {.i = 7} }),
&((Keychord){1, {{ ControlMask, XK_9}}, focusbynum, {.i = 8} }),
static const Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawndmenu, {0} },
{ MODKEY, XK_o, shiftviewclients, { .i = +1 } },
{ MODKEY|ShiftMask, XK_o, shiftview, { .i = +1 } },
{ MODKEY|ShiftMask, XK_i, shiftview, { .i = -1 } },
{ MODKEY, XK_i, shiftviewclients, { .i = -1 } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstackvis, {.i = +1 } },
{ MODKEY, XK_k, focusstackvis, {.i = -1 } },
{ MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } },
{ MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY|ShiftMask, XK_h, shiftboth, { .i = -1 } },
{ MODKEY|ControlMask, XK_h, shiftswaptags, { .i = -1 } },
{ MODKEY|ControlMask, XK_l, shiftswaptags, { .i = +1 } },
{ MODKEY|ShiftMask, XK_l, shiftboth, { .i = +1 } },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_g, goback, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
{ MODKEY, XK_s, show, {0} },
{ MODKEY|ShiftMask, XK_s, showall, {0} },
{ MODKEY, XK_h, hide, {0} },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_j, focusbynum, {.i = 0} },
{ MODKEY|ShiftMask, XK_k, focusbynum, {.i = 1} },
{ MODKEY|ShiftMask, XK_l, focusbynum, {.i = 2} },
{ MODKEY|ShiftMask, XK_colon, focusbynum, {.i = 3} },
{ MODKEY|ShiftMask, XK_f, focusbynum, {.i = 4} },
{ MODKEY|ShiftMask, XK_d, focusbynum, {.i = 5} },
{ MODKEY|ShiftMask, XK_s, focusbynum, {.i = 6} },
{ MODKEY|ShiftMask, XK_a, focusbynum, {.i = 7} },
{ MODKEY|ShiftMask, XK_q, quit, {0} },
{ MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
{ MODKEY|ShiftMask, XK_e, exitdwm, {0} },
{ MODKEY, XK_o, winview, {0} },
{ MODKEY, XK_g, gridall, {} },
{ MODKEY, XK_r, winviewmono, {} },
};
/* button definitions */
-178
View File
@@ -1,178 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include "gaplessgrid.c"
/* appearance */
static const unsigned int borderpx = 2; /* border pixel of windows */
static const unsigned int gappx = 2; /* gaps between windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
static const char col_border_focus_light[] = "#df8c20"; // hsl(34 75% 50%)
static const char col_border_focus_dark[] = "#b25e34"; // hsl(20 55% 45%)
static const char *colorsdark[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_border_focus_dark },
[SchemeHid] = { col_cyan, col_gray1, col_cyan },
};
static const char *colorslight[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray1, col_gray3, col_gray2 },
[SchemeSel] = { col_cyan, col_gray4, col_border_focus_light },
[SchemeHid] = { col_cyan, col_gray1, col_cyan },
};
/* tagging */
static const char *tags[] = { "q", "w", "e", "r", "t", "a", "s", "d", "f", "g", "z", "x", "c", "v", "b" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "HHH", gaplessgrid },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
&((Keychord){1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }),
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static char dmenumon[8] = "0"; /* component of dmenu{dark,light}, manipulated in spawndmenu() */
static const char *dmenudark[] = { "dmenu_run", "-l", "10", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *dmenulight[] = { "dmenu_run", "-l", "10", "-m", dmenumon, "-i", "-fn", dmenufont, "-nb", col_gray3, "-nf", col_gray1, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "alacritty", NULL };
static const char *lockcmd[] = { "slock", NULL };
static const char *suspendcmd[] = { "systemctl", "suspend", NULL };
static const char *themecmd[] = { "lupan-set-theme", "toggle", NULL };
#include "shift-tools.c"
#include "exitdwm.c"
#include "movestack.c"
static Keychord *keychords[] = {
/* Keys function argument */
&((Keychord){1, {{MODKEY, XK_p}}, spawndmenu, {0} }),
&((Keychord){1, {{MODKEY, XK_u}}, shiftview, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_u}}, shifttag, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_y}}, shifttag, { .i = -1 } }),
&((Keychord){1, {{MODKEY, XK_y}}, shiftview, { .i = -1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_b}}, togglebar, {0} }),
&((Keychord){1, {{MODKEY, XK_j}}, focusstackvis, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_k}}, focusstackvis, {.i = -1 } }),
&((Keychord){1, {{MODKEY|ControlMask, XK_j}}, focusstackhid, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ControlMask, XK_k}}, focusstackhid, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_d}}, incnmaster, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_h}}, shiftboth, {.i = -1} }),
&((Keychord){1, {{MODKEY|ControlMask, XK_h}}, shiftswaptags, {.i = -1} }),
&((Keychord){1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }),
&((Keychord){1, {{MODKEY|ControlMask, XK_l}}, shiftswaptags, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_l}}, shiftboth, { .i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_j}}, movestack, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_k}}, movestack, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_Return}}, zoom, {0} }),
&((Keychord){1, {{MODKEY, XK_Tab}}, view, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_w}}, goback, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_c}}, killclient, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_t}}, setlayout, {.v = &layouts[0]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_f}}, setlayout, {.v = &layouts[1]} }),
&((Keychord){1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_g}}, setlayout, {.v = &layouts[3]} }),
&((Keychord){1, {{MODKEY, XK_space}}, setlayout, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} }),
&((Keychord){1, {{MODKEY, XK_0}}, view, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_s}}, show, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_s}}, showall, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ControlMask, XK_s}}, hide, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_q}}, quit, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ControlMask|ShiftMask, XK_q}}, quit, {1} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_e}}, exitdwm, {0} }),
&((Keychord){1, {{MODKEY, XK_o}}, winview, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_a}}, gridall, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_r}}, winviewmono, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {ControlMask|ShiftMask, XK_s}}, spawn, {.v = suspendcmd } }),
&((Keychord){1, {{MODKEY|ControlMask|ShiftMask, XK_l}}, spawn, {.v = lockcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {ControlMask|ShiftMask, XK_t}}, spawn, {.v = themecmd } }),
TAGKEYS( XK_q, 0)
TAGKEYS( XK_w, 1)
TAGKEYS( XK_e, 2)
TAGKEYS( XK_r, 3)
TAGKEYS( XK_t, 4)
TAGKEYS( XK_a, 5)
TAGKEYS( XK_s, 6)
TAGKEYS( XK_d, 7)
TAGKEYS( XK_f, 8)
TAGKEYS( XK_g, 9)
TAGKEYS( XK_z, 10)
TAGKEYS( XK_x, 11)
TAGKEYS( XK_c, 12)
TAGKEYS( XK_v, 13)
TAGKEYS( XK_b, 14)
&((Keychord){1, {{ ControlMask, XK_1}}, focusbynum, {.i = 0} }),
&((Keychord){1, {{ ControlMask, XK_2}}, focusbynum, {.i = 1} }),
&((Keychord){1, {{ ControlMask, XK_3}}, focusbynum, {.i = 2} }),
&((Keychord){1, {{ ControlMask, XK_4}}, focusbynum, {.i = 3} }),
&((Keychord){1, {{ ControlMask, XK_5}}, focusbynum, {.i = 4} }),
&((Keychord){1, {{ ControlMask, XK_6}}, focusbynum, {.i = 5} }),
&((Keychord){1, {{ ControlMask, XK_7}}, focusbynum, {.i = 6} }),
&((Keychord){1, {{ ControlMask, XK_8}}, focusbynum, {.i = 7} }),
&((Keychord){1, {{ ControlMask, XK_9}}, focusbynum, {.i = 8} }),
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button1, togglewin, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
-124
View File
@@ -1,124 +0,0 @@
/* See LICENSE file for copyright and license details. */
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
/* tagging */
static const char *tags[] = { "q", "w", "e", "r", "t", "a", "s", "d", "f", "g", "z", "x", "c", "v", "b" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
&((Keychord){1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }), \
&((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }),
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static char dmenumon[8]; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "alacritty", NULL };
static Keychord *keychords[] = {
/* Keys function argument */
&((Keychord){1, {{MODKEY, XK_p}}, spawn, {.v = dmenucmd } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_e}}, spawn, {.v = termcmd } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_b}}, togglebar, {0} }),
&((Keychord){1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }),
&((Keychord){1, {{MODKEY, XK_u}}, incnmaster, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }),
&((Keychord){1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }),
&((Keychord){1, {{MODKEY, XK_Return}}, zoom, {0} }),
&((Keychord){1, {{MODKEY, XK_Tab}}, view, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_t}}, setlayout, {.v = &layouts[0]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_f}}, setlayout, {.v = &layouts[1]} }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {0, XK_m}}, setlayout, {.v = &layouts[2]} }),
&((Keychord){1, {{MODKEY, XK_space}}, setlayout, {0} }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} }),
&((Keychord){1, {{MODKEY, XK_y}}, view, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }),
&((Keychord){1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }),
&((Keychord){1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }),
&((Keychord){2, {{MODKEY, XK_semicolon}, {MODKEY|ShiftMask, XK_q}}, quit, {0} }),
TAGKEYS( XK_q, 0)
TAGKEYS( XK_w, 1)
TAGKEYS( XK_e, 2)
TAGKEYS( XK_r, 3)
TAGKEYS( XK_t, 4)
TAGKEYS( XK_a, 5)
TAGKEYS( XK_s, 6)
TAGKEYS( XK_d, 7)
TAGKEYS( XK_f, 8)
TAGKEYS( XK_g, 9)
TAGKEYS( XK_z, 10)
TAGKEYS( XK_x, 11)
TAGKEYS( XK_c, 12)
TAGKEYS( XK_v, 13)
TAGKEYS( XK_b, 14)
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
+1 -1
View File
@@ -1,5 +1,5 @@
# dwm version
VERSION = 6.8
VERSION = 6.7
# Customize below to fit your system
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-272
View File
@@ -1,272 +0,0 @@
From 9c020a20a2e1091e8b47edfea5e8795d8b451bc9 Mon Sep 17 00:00:00 2001
From: Lukasz Kasprzak <lukas@labunix.xyz>
Date: Fri, 17 Jul 2026 15:45:22 +0200
Subject: [PATCH] keychord: bind a sequence of keys, and dispatch events while
waiting
Original keychord patch by Hai Nguyen <hhai2105@gmail.com>, updated for
dwm 6.4+ grabkeys() by Aaron Zueger <contact@azureorange.xyz>. This
revision rebases onto dwm 6.8 and fixes an event-loss bug in the chord
wait loop.
The wait loop used to discard every event that was not a KeyPress:
while (running && !XNextEvent(dpy, &event) && !ran)
if(event.type == KeyPress)
break;
Two consequences, both reproduced on Xephyr:
1. Unrecoverable input freeze. grabbuttons() grabs unfocused clients
GrabModeSync/GrabModeSync, so clicking one freezes pointer AND
keyboard until the grabbing client calls XAllowEvents. dwm does that
in buttonpress() -- but if the ButtonPress is discarded here,
buttonpress() never runs. The grab stays frozen forever and the loop
can never exit, because a frozen keyboard cannot deliver the KeyPress
it is waiting for. Only killing dwm ends it; XSendEvent is discarded
by this same loop and XTEST queues behind the frozen device.
Repro: press a chord prefix, then click any unfocused client.
Observed: XGrabKeyboard -> GrabFrozen, XQueryPointer -> Button1 held.
2. Orphaned windows. A MapRequest arriving mid-chord is dropped, so a
window opening during a chord is never managed. DestroyNotify,
Expose and ConfigureRequest are lost the same way.
Dispatch through handler[] as run() does, breaking on KeyPress before
dispatch so keypress() cannot recurse. The `&& !ran` term is dropped:
ran is always 0 on entry and nothing in the body can set it.
---
config.def.h | 81 ++++++++++++++++++++++++++--------------------------
dwm.c | 79 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 106 insertions(+), 54 deletions(-)
diff --git a/config.def.h b/config.def.h
index 81c3fc0..7c7ec36 100644
--- a/config.def.h
+++ b/config.def.h
@@ -47,11 +47,11 @@ static const Layout layouts[] = {
/* key definitions */
#define MODKEY Mod1Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
+#define TAGKEYS(KEY,TAG) \
+ &((Keychord){1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }), \
+ &((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \
+ &((Keychord){1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }), \
+ &((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }),
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
@@ -61,41 +61,42 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
-static const Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_c, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
+static Keychord *keychords[] = {
+ /* Keys function argument */
+ &((Keychord){1, {{MODKEY, XK_p}}, spawn, {.v = dmenucmd } }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } }),
+ &((Keychord){2, {{MODKEY, XK_e}, {MODKEY, XK_e}}, spawn, {.v = termcmd } }),
+ &((Keychord){1, {{MODKEY, XK_b}}, togglebar, {0} }),
+ &((Keychord){1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } }),
+ &((Keychord){1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } }),
+ &((Keychord){1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }),
+ &((Keychord){1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } }),
+ &((Keychord){1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }),
+ &((Keychord){1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }),
+ &((Keychord){1, {{MODKEY, XK_Return}}, zoom, {0} }),
+ &((Keychord){1, {{MODKEY, XK_Tab}}, view, {0} }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} }),
+ &((Keychord){1, {{MODKEY, XK_t}}, setlayout, {.v = &layouts[0]} }),
+ &((Keychord){1, {{MODKEY, XK_f}}, setlayout, {.v = &layouts[1]} }),
+ &((Keychord){1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} }),
+ &((Keychord){1, {{MODKEY, XK_space}}, setlayout, {0} }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} }),
+ &((Keychord){1, {{MODKEY, XK_0}}, view, {.ui = ~0 } }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }),
+ &((Keychord){1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }),
+ &((Keychord){1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }),
+ &((Keychord){1, {{MODKEY|ShiftMask, XK_q}}, quit, {0} }),
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+ TAGKEYS( XK_4, 3)
+ TAGKEYS( XK_5, 4)
+ TAGKEYS( XK_6, 5)
+ TAGKEYS( XK_7, 6)
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
};
/* button definitions */
diff --git a/dwm.c b/dwm.c
index 53b393e..243b12c 100644
--- a/dwm.c
+++ b/dwm.c
@@ -101,9 +101,14 @@ struct Client {
typedef struct {
unsigned int mod;
KeySym keysym;
+} Key;
+
+typedef struct {
+ unsigned int n;
+ const Key keys[5];
void (*func)(const Arg *);
const Arg arg;
-} Key;
+} Keychord;
typedef struct {
const char *symbol;
@@ -266,6 +271,7 @@ static Display *dpy;
static Drw *drw;
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
+unsigned int currentkey = 0;
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -954,7 +960,8 @@ grabkeys(void)
{
updatenumlockmask();
{
- unsigned int i, j, k;
+ /* unsigned int i, j, k; */
+ unsigned int i, c, k;
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
int start, end, skip;
KeySym *syms;
@@ -964,15 +971,18 @@ grabkeys(void)
syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
if (!syms)
return;
+
for (k = start; k <= end; k++)
- for (i = 0; i < LENGTH(keys); i++)
+ for (i = 0; i < LENGTH(keychords); i++)
/* skip modifier codes, we do that ourselves */
- if (keys[i].keysym == syms[(k - start) * skip])
- for (j = 0; j < LENGTH(modifiers); j++)
+ if (keychords[i]->keys[currentkey].keysym == syms[(k - start) * skip])
+ for (c = 0; c < LENGTH(modifiers); c++)
XGrabKey(dpy, k,
- keys[i].mod | modifiers[j],
+ keychords[i]->keys[currentkey].mod | modifiers[c],
root, True,
GrabModeAsync, GrabModeAsync);
+ if(currentkey > 0)
+ XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Escape), AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
XFree(syms);
}
}
@@ -999,17 +1009,58 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
void
keypress(XEvent *e)
{
- unsigned int i;
+ /* unsigned int i; */
+ XEvent event = *e;
+ unsigned int ran = 0;
KeySym keysym;
XKeyEvent *ev;
- ev = &e->xkey;
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for (i = 0; i < LENGTH(keys); i++)
- if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keys[i].func)
- keys[i].func(&(keys[i].arg));
+ Keychord *arr1[sizeof(keychords) / sizeof(Keychord*)];
+ Keychord *arr2[sizeof(keychords) / sizeof(Keychord*)];
+ memcpy(arr1, keychords, sizeof(keychords));
+ Keychord **rpointer = arr1;
+ Keychord **wpointer = arr2;
+
+ size_t r = sizeof(keychords)/ sizeof(Keychord*);
+
+ while(1){
+ ev = &event.xkey;
+ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
+ size_t w = 0;
+ for (int i = 0; i < r; i++){
+ if(keysym == (*(rpointer + i))->keys[currentkey].keysym
+ && CLEANMASK((*(rpointer + i))->keys[currentkey].mod) == CLEANMASK(ev->state)
+ && (*(rpointer + i))->func){
+ if((*(rpointer + i))->n == currentkey +1){
+ (*(rpointer + i))->func(&((*(rpointer + i))->arg));
+ ran = 1;
+ }else{
+ *(wpointer + w) = *(rpointer + i);
+ w++;
+ }
+ }
+ }
+ currentkey++;
+ if(w == 0 || ran == 1)
+ break;
+ grabkeys();
+ /* Events arriving mid-chord must be dispatched, not dropped:
+ * discarding a ButtonPress that activated the GrabModeSync grab
+ * from grabbuttons() freezes pointer and keyboard permanently,
+ * since only buttonpress()'s XAllowEvents can release it. */
+ while (running && !XNextEvent(dpy, &event)) {
+ if (event.type == KeyPress)
+ break;
+ if (handler[event.type])
+ handler[event.type](&event); /* call handler */
+ }
+ r = w;
+ Keychord **holder = rpointer;
+ rpointer = wpointer;
+ wpointer = holder;
+ }
+ currentkey = 0;
+ grabkeys();
}
void
--
2.47.3
+45 -109
View File
@@ -102,14 +102,9 @@ struct Client {
typedef struct {
unsigned int mod;
KeySym keysym;
} Key;
typedef struct {
unsigned int n;
const Key keys[5];
void (*func)(const Arg *);
const Arg arg;
} Keychord;
} Key;
typedef struct {
const char *symbol;
@@ -299,7 +294,6 @@ static Monitor *mons, *selmon, *prevmon;
static Window root, wmcheckwin;
static const char **dmenucmd;
static int colormodechanged;
unsigned int currentkey = 0;
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -429,8 +423,7 @@ arrange(Monitor *m)
void
arrangemon(Monitor *m)
{
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof(m->ltsymbol) - 1);
m->ltsymbol[sizeof(m->ltsymbol) - 1] = '\0';
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
if (m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
}
@@ -619,9 +612,6 @@ configurenotify(XEvent *e)
/* TODO: updategeom handling sucks, needs to be simplified */
if (ev->window == root) {
if (ev->width <= 0 || ev->height <= 0)
return;
dirty = (sw != ev->width || sh != ev->height);
sw = ev->width;
sh = ev->height;
@@ -705,8 +695,7 @@ createmon(void)
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof(m->ltsymbol) - 1);
m->ltsymbol[sizeof(m->ltsymbol) - 1] = '\0';
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
return m;
}
@@ -986,15 +975,15 @@ focusstack(int inc, int hid)
Atom
getatomprop(Client *c, Atom prop)
{
int format;
int di;
unsigned long nitems, dl;
unsigned char *p = NULL;
Atom da, atom = None;
if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
&da, &format, &nitems, &dl, &p) == Success && p) {
if (nitems > 0 && format == 32)
atom = *(long *)p;
&da, &di, &nitems, &dl, &p) == Success && p) {
if (nitems > 0)
atom = *(Atom *)p;
XFree(p);
}
return atom;
@@ -1020,10 +1009,10 @@ getstate(Window w)
Atom real;
if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
&real, &format, &n, &extra, &p) != Success)
&real, &format, &n, &extra, (unsigned char **)&p) != Success)
return -1;
if (n != 0 && format == 32)
result = *(long *)p;
if (n != 0)
result = *p;
XFree(p);
return result;
}
@@ -1042,9 +1031,8 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
return 0;
if (name.encoding == XA_STRING) {
strncpy(text, (char *)name.value, size - 1);
} else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success) {
if (n > 0 && *list)
strncpy(text, *list, size - 1);
} else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
strncpy(text, *list, size - 1);
XFreeStringList(list);
}
text[size - 1] = '\0';
@@ -1094,8 +1082,7 @@ grabkeys(void)
{
updatenumlockmask();
{
/* unsigned int i, j, k; */
unsigned int i, c, k;
unsigned int i, j, k;
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
int start, end, skip;
KeySym *syms;
@@ -1105,18 +1092,15 @@ grabkeys(void)
syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
if (!syms)
return;
for (k = start; k <= end; k++)
for (i = 0; i < LENGTH(keychords); i++)
for (i = 0; i < LENGTH(keys); i++)
/* skip modifier codes, we do that ourselves */
if (keychords[i]->keys[currentkey].keysym == syms[(k - start) * skip])
for (c = 0; c < LENGTH(modifiers); c++)
if (keys[i].keysym == syms[(k - start) * skip])
for (j = 0; j < LENGTH(modifiers); j++)
XGrabKey(dpy, k,
keychords[i]->keys[currentkey].mod | modifiers[c],
keys[i].mod | modifiers[j],
root, True,
GrabModeAsync, GrabModeAsync);
if(currentkey > 0)
XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Escape), AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
XFree(syms);
}
}
@@ -1173,58 +1157,17 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
void
keypress(XEvent *e)
{
/* unsigned int i; */
XEvent event = *e;
unsigned int ran = 0;
unsigned int i;
KeySym keysym;
XKeyEvent *ev;
Keychord *arr1[sizeof(keychords) / sizeof(Keychord*)];
Keychord *arr2[sizeof(keychords) / sizeof(Keychord*)];
memcpy(arr1, keychords, sizeof(keychords));
Keychord **rpointer = arr1;
Keychord **wpointer = arr2;
size_t r = sizeof(keychords)/ sizeof(Keychord*);
while(1){
ev = &event.xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
size_t w = 0;
for (int i = 0; i < r; i++){
if(keysym == (*(rpointer + i))->keys[currentkey].keysym
&& CLEANMASK((*(rpointer + i))->keys[currentkey].mod) == CLEANMASK(ev->state)
&& (*(rpointer + i))->func){
if((*(rpointer + i))->n == currentkey +1){
(*(rpointer + i))->func(&((*(rpointer + i))->arg));
ran = 1;
}else{
*(wpointer + w) = *(rpointer + i);
w++;
}
}
}
currentkey++;
if(w == 0 || ran == 1)
break;
grabkeys();
/* Events arriving mid-chord must be dispatched, not dropped:
* discarding a ButtonPress that activated the GrabModeSync grab
* from grabbuttons() freezes pointer and keyboard permanently,
* since only buttonpress()'s XAllowEvents can release it. */
while (running && !XNextEvent(dpy, &event)) {
if (event.type == KeyPress)
break;
if (handler[event.type])
handler[event.type](&event); /* call handler */
}
r = w;
Keychord **holder = rpointer;
rpointer = wpointer;
wpointer = holder;
}
currentkey = 0;
grabkeys();
ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for (i = 0; i < LENGTH(keys); i++)
if (keysym == keys[i].keysym
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
&& keys[i].func)
keys[i].func(&(keys[i].arg));
}
void
@@ -1779,10 +1722,12 @@ sendevent(Client *c, Atom proto)
void
setfocus(Client *c)
{
if (!c->neverfocus)
if (!c->neverfocus) {
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
XChangeProperty(dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32,
PropModeReplace, (unsigned char *)&c->win, 1);
XChangeProperty(dpy, root, netatom[NetActiveWindow],
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1);
}
sendevent(c, wmatom[WMTakeFocus]);
}
@@ -2027,16 +1972,8 @@ void
spawn(const Arg *arg)
{
struct sigaction sa;
pid_t pid;
if (arg->v == dmenucmd)
snprintf(dmenumon, sizeof(dmenumon), "%d", selmon->num);
if ((pid = fork()) == -1) {
fprintf(stderr, "dwm: fork failed: %s\n", strerror(errno));
return;
}
if (pid == 0) {
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
@@ -2396,8 +2333,7 @@ updatenumlockmask(void)
XModifierKeymap *modmap;
numlockmask = 0;
if (!(modmap = XGetModifierMapping(dpy)))
return;
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++)
for (j = 0; j < modmap->max_keypermod; j++)
if (modmap->modifiermap[i * modmap->max_keypermod + j]
@@ -2416,32 +2352,32 @@ updatesizehints(Client *c)
/* size is uninitialized, ensure that size.flags aren't used */
size.flags = PSize;
if (size.flags & PBaseSize) {
c->basew = MAX(0, size.base_width);
c->baseh = MAX(0, size.base_height);
c->basew = size.base_width;
c->baseh = size.base_height;
} else if (size.flags & PMinSize) {
c->basew = MAX(0, size.min_width);
c->baseh = MAX(0, size.min_height);
c->basew = size.min_width;
c->baseh = size.min_height;
} else
c->basew = c->baseh = 0;
if (size.flags & PResizeInc) {
c->incw = MAX(0, size.width_inc);
c->inch = MAX(0, size.height_inc);
c->incw = size.width_inc;
c->inch = size.height_inc;
} else
c->incw = c->inch = 0;
if (size.flags & PMaxSize) {
c->maxw = MAX(0, size.max_width);
c->maxh = MAX(0, size.max_height);
c->maxw = size.max_width;
c->maxh = size.max_height;
} else
c->maxw = c->maxh = 0;
if (size.flags & PMinSize) {
c->minw = MAX(0, size.min_width);
c->minh = MAX(0, size.min_height);
c->minw = size.min_width;
c->minh = size.min_height;
} else if (size.flags & PBaseSize) {
c->minw = MAX(0, size.base_width);
c->minh = MAX(0, size.base_height);
c->minw = size.base_width;
c->minh = size.base_height;
} else
c->minw = c->minh = 0;
if ((size.flags & PAspect) && size.min_aspect.x > 0 && size.max_aspect.y > 0) {
if (size.flags & PAspect) {
c->mina = (float)size.min_aspect.y / size.min_aspect.x;
c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
} else
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.