~ruther/dwl

84dd2bbcd50cad935798ec6d94071035ad596fb9 — Rutherther 11 months ago 162ffed + da27c65
Merge branch 'v0.6-a/keycodes-modes' into v0.6-a/patched-keycodes
8 files changed, 1888 insertions(+), 71 deletions(-)

M config.def.h
M dwl.c
A generate-keys.c
A keycodes-diff.patch
A keycodes.patch
A keys.h
A modes-diff.patch
A modes.patch
M config.def.h => config.def.h +63 -51
@@ 14,6 14,13 @@ static const float urgentcolor[]           = COLOR(0xff0000ff);
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */

enum {
	BROWSER,
};
const char *modes_labels[] = {
	"browser",
};

/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)



@@ 106,13 113,13 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
#define MODKEY WLR_MODIFIER_ALT

#define TAGKEYS(KEY,SKEY,TAG) \
#define TAGKEYS(KEY,TAG) \
	{ MODKEY,                    KEY,            view,            {.ui = 1 << TAG} }, \
	{ MODKEY|WLR_MODIFIER_CTRL,  KEY,            toggleview,      {.ui = 1 << TAG} }, \
	{ MODKEY|WLR_MODIFIER_SHIFT, SKEY,           tag,             {.ui = 1 << TAG} }, \
	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }, \
	{ MODKEY|WLR_MODIFIER_SHIFT, KEY,           tag,             {.ui = 1 << TAG} }, \
	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,KEY,toggletag, {.ui = 1 << TAG} }, \
	{ WLR_MODIFIER_ALT,          KEY,            focusnthmon,     {.ui = TAG} }, \
	{ WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, SKEY, tagnthmon,       {.ui = TAG} }
	{ WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, KEY, tagnthmon,       {.ui = TAG} }

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }


@@ 124,60 131,65 @@ static const char *menucmd[] = { "bemenu-run", NULL };
/* named scratchpads - First arg only serves to match against key in rules*/
static const char *scratchpadcmd[] = { "s", "alacritty", "-t", "scratchpad", NULL };

#include "keys.h"
static const Key keys[] = {
	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
	/* modifier                  key                 function        argument */
	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd} },
	{ MODKEY,                    XKB_KEY_b,          togglebar,      {0} },
	{ MODKEY,                    XKB_KEY_grave,      togglescratch,  {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglescratch, {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglematchingscratch, {.v = scratchpadcmd } },
	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J,          movestack,      {.i = +1} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K,          movestack,      {.i = -1} },
	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} },
	{ MODKEY,                    XKB_KEY_d,          incnmaster,     {.i = -1} },
	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05f} },
	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} },
	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} },
	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C,          killclient,     {0} },
	{ MODKEY,                    XKB_KEY_t,          setlayout,      {.v = &layouts[0]} },
	{ MODKEY,                    XKB_KEY_f,          setlayout,      {.v = &layouts[1]} },
	{ MODKEY,                    XKB_KEY_m,          setlayout,      {.v = &layouts[2]} },
	{ MODKEY,                    XKB_KEY_c,          setlayout,      {.v = &layouts[3]} },
	{ MODKEY,                    XKB_KEY_u,          setlayout,      {.v = &layouts[4]} },
	{ MODKEY,                    XKB_KEY_o,          setlayout,      {.v = &layouts[5]} },
	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
	{ MODKEY,                    XKB_KEY_e,         togglefullscreen, {0} },
	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
	{ MODKEY,                    XKB_KEY_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less,       tagmon,         {.i = WLR_DIRECTION_LEFT} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater,    tagmon,         {.i = WLR_DIRECTION_RIGHT} },
	TAGKEYS(          XKB_KEY_1, XKB_KEY_exclam,                     0),
	TAGKEYS(          XKB_KEY_2, XKB_KEY_at,                         1),
	TAGKEYS(          XKB_KEY_3, XKB_KEY_numbersign,                 2),
	TAGKEYS(          XKB_KEY_4, XKB_KEY_dollar,                     3),
	TAGKEYS(          XKB_KEY_5, XKB_KEY_percent,                    4),
	TAGKEYS(          XKB_KEY_6, XKB_KEY_asciicircum,                5),
	TAGKEYS(          XKB_KEY_7, XKB_KEY_ampersand,                  6),
	TAGKEYS(          XKB_KEY_8, XKB_KEY_asterisk,                   7),
	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
	{ MODKEY,                    Key_p,          spawn,          {.v = menucmd} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_Return,     spawn,          {.v = termcmd} },
	{ MODKEY,                    Key_j,          focusstack,     {.i = +1} },
	{ MODKEY,                    Key_k,          focusstack,     {.i = -1} },
	{ MODKEY,                    Key_i,          incnmaster,     {.i = +1} },
	{ MODKEY,                    Key_d,          incnmaster,     {.i = -1} },
	{ MODKEY,                    Key_h,          setmfact,       {.f = -0.05f} },
	{ MODKEY,                    Key_l,          setmfact,       {.f = +0.05f} },
	{ MODKEY,                    Key_Return,     zoom,           {0} },
	{ MODKEY,                    Key_Tab,        view,           {0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_c,          killclient,     {0} },
	{ MODKEY,                    Key_t,          setlayout,      {.v = &layouts[0]} },
	{ MODKEY,                    Key_f,          setlayout,      {.v = &layouts[1]} },
	{ MODKEY,                    Key_m,          setlayout,      {.v = &layouts[2]} },
	{ MODKEY,                    Key_space,      setlayout,      {0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_space,      togglefloating, {0} },
	{ MODKEY,                    Key_e,          togglefullscreen, {0} },
	{ MODKEY,                    Key_0,          view,           {.ui = ~0} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_0,          tag,            {.ui = ~0} },
	{ MODKEY,                    Key_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
	{ MODKEY,                    Key_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_comma,      tagmon,         {.i = WLR_DIRECTION_LEFT} },
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_period,     tagmon,         {.i = WLR_DIRECTION_RIGHT} },
	TAGKEYS(                     Key_1,                          0),
	TAGKEYS(                     Key_2,                          1),
	TAGKEYS(                     Key_3,                          2),
	TAGKEYS(                     Key_4,                          3),
	TAGKEYS(                     Key_5,                          4),
	TAGKEYS(                     Key_6,                          5),
	TAGKEYS(                     Key_7,                          6),
	TAGKEYS(                     Key_8,                          7),
	TAGKEYS(                     Key_9,                          8),
	{ MODKEY|WLR_MODIFIER_SHIFT, Key_q,          quit,           {0} },

	{ MODKEY,                    Key_b,          entermode,      {.i = BROWSER} },

	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,Key_BackSpace, quit, {0} },
	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
	 * do not remove them.
	 */
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
	CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
#define CHVT(KEY,n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, KEY, chvt, {.ui = (n)} }
	CHVT(Key_F1, 1), CHVT(Key_F2,  2),  CHVT(Key_F3,  3),  CHVT(Key_F4,  4),
	CHVT(Key_F5, 5), CHVT(Key_F6,  6),  CHVT(Key_F7,  7),  CHVT(Key_F8,  8),
	CHVT(Key_F9, 9), CHVT(Key_F10, 10), CHVT(Key_F11, 11), CHVT(Key_F12, 12),
};

static const Modekey modekeys[] = {
	/* mode      modifier                  key                 function        argument */
	{ BROWSER, { 0, Key_f, spawn, SHCMD("firefox") } },
	{ BROWSER, { 0, Key_f, entermode, {.i = NORMAL} } },
	{ BROWSER, { 0, Key_b, spawn, SHCMD("brave") } },
	{ BROWSER, { 0, Key_b, entermode, {.i = NORMAL} } },
	{ BROWSER, { 0, Key_g, spawn, SHCMD("google-chrome-stable") } },
	{ BROWSER, { 0, Key_g, entermode, {.i = NORMAL} } },
	{ BROWSER, { 0, Key_Escape, entermode, {.i = NORMAL} } },
};

static const Button buttons[] = {

M dwl.c => dwl.c +55 -20
@@ 162,18 162,22 @@ typedef struct {

typedef struct {
	uint32_t mod;
	xkb_keysym_t keysym;
	xkb_keycode_t keycode;
	void (*func)(const Arg *);
	const Arg arg;
} Key;

typedef struct {
	int mode_index;
	Key key;
} Modekey;

typedef struct {
	struct wl_list link;
	struct wlr_keyboard_group *wlr_group;

	int nsyms;
	const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
	uint32_t mods; /* invalid if nsyms == 0 */
	xkb_keycode_t keycode;
	uint32_t mods; /* invalid if keycode == 0 */
	struct wl_event_source *key_repeat_source;

	struct wl_listener modifiers;


@@ 325,7 329,9 @@ static size_t getunusedtag(void);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keycode_t keycode);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
static int modekeybinding(uint32_t mods, xkb_keycode_t sym);
static void keypress(struct wl_listener *listener, void *data);
static void keypressmod(struct wl_listener *listener, void *data);
static int keyrepeat(void *data);


@@ 406,6 412,7 @@ static void factivatenotify(struct wl_listener *listener, void *data);
static void fclosenotify(struct wl_listener *listener, void *data);
static void fdestroynotify(struct wl_listener *listener, void *data);
static void ffullscreennotify(struct wl_listener *listener, void *data);
static void entermode(const Arg *arg);

/* variables */
static const char broken[] = "broken";


@@ 468,6 475,8 @@ static Monitor *selmon;

static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output};
static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags};
static const int NORMAL = -1;
static int active_mode_index = NORMAL;

#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);


@@ 1921,7 1930,7 @@ inputdevice(struct wl_listener *listener, void *data)
}

int
keybinding(uint32_t mods, xkb_keysym_t sym)
keybinding(uint32_t mods, xkb_keycode_t keycode)
{
	/*
	 * Here we handle compositor keybindings. This is when the compositor is


@@ 1929,9 1938,14 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
	 * processing.
	 */
	const Key *k;

	if (active_mode_index >= 0) {
		return modekeybinding(mods, keycode);
	}

	for (k = keys; k < END(keys); k++) {
		if (CLEANMASK(mods) == CLEANMASK(k->mod)
				&& sym == k->keysym && k->func) {
				&& keycode == k->keycode && k->func) {
			k->func(&k->arg);
			return 1;
		}


@@ 1939,20 1953,38 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
	return 0;
}

int
modekeybinding(uint32_t mods, xkb_keycode_t keycode)
{
	int handled = 0;
	const Modekey *mk;
	const Key *k;

	for (mk = modekeys; mk < END(modekeys); mk++) {
		if (active_mode_index != mk->mode_index) {
			continue;
		}

		k = &mk->key;
		if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
				keycode == k->keycode && k->func) {
			k->func(&k->arg);
			handled = 1;
		}
	}

	return handled;
}

void
keypress(struct wl_listener *listener, void *data)
{
	int i;
	/* This event is raised when a key is pressed or released. */
	KeyboardGroup *group = wl_container_of(listener, group, key);
	struct wlr_keyboard_key_event *event = data;

	/* Translate libinput keycode -> xkbcommon */
	uint32_t keycode = event->keycode + 8;
	/* Get a list of keysyms based on the keymap for this keyboard */
	const xkb_keysym_t *syms;
	int nsyms = xkb_state_key_get_syms(
			group->wlr_group->keyboard.xkb_state, keycode, &syms);

	int handled = 0;
	uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);


@@ 1962,18 1994,16 @@ keypress(struct wl_listener *listener, void *data)
	/* On _press_ if there is no active screen locker,
	 * attempt to process a compositor keybinding. */
	if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
		for (i = 0; i < nsyms; i++)
			handled = keybinding(mods, syms[i]) || handled;
		handled = keybinding(mods, keycode);
	}

	if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
		group->mods = mods;
		group->keysyms = syms;
		group->nsyms = nsyms;
		group->keycode = keycode;
		wl_event_source_timer_update(group->key_repeat_source,
				group->wlr_group->keyboard.repeat_info.delay);
	} else {
		group->nsyms = 0;
		group->keycode = 0;
		wl_event_source_timer_update(group->key_repeat_source, 0);
	}



@@ 2003,15 2033,13 @@ int
keyrepeat(void *data)
{
	KeyboardGroup *group = data;
	int i;
	if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
	if (!group->keycode || group->wlr_group->keyboard.repeat_info.rate <= 0)
		return 0;

	wl_event_source_timer_update(group->key_repeat_source,
			1000 / group->wlr_group->keyboard.repeat_info.rate);

	for (i = 0; i < group->nsyms; i++)
		keybinding(group->mods, group->keysyms[i]);
	keybinding(group->mods, group->keycode);

	return 0;
}


@@ 3725,6 3753,13 @@ fdestroynotify(struct wl_listener *listener, void *data)
	wl_list_remove(&c->fdestroy.link);
}

void
entermode(const Arg *arg)
{
	active_mode_index = arg->i;
	printstatus();
}

#ifdef XWAYLAND
void
activatex11(struct wl_listener *listener, void *data)

A generate-keys.c => generate-keys.c +82 -0
@@ 0,0 1,82 @@
/******************************************************************
 * Copyright 2023 Leonardo Hernández Hernández
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the “Software”), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 ******************************************************************/

/* cc -lxkbcommon -o generate-keys generate-keys.c */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#include <xkbcommon/xkbcommon.h>

int
main(void)
{
	struct xkb_context *context;
	/* Allow generate keys with a different layout and variant.
	 * You can also use XKB_DEFAULT_* environmental variables and let this as is */
	struct xkb_rule_names rules = {
		0
	};
	struct xkb_keymap *keymap;
	struct xkb_state *state;
	xkb_keycode_t keycode, min_keycode, max_keycode;
	int i, nsyms;
	const xkb_keysym_t *syms;
	char keyname[64];
	FILE *f = fopen("keys.h", "w");
	if (!f) {
		perror("Couldn't open keys.h");
		return EXIT_FAILURE;
	}

	if (!(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS))) {
		fputs("Couldn't create xkbcommon context\n", stderr);
		return EXIT_FAILURE;
	}

	if (!(keymap = xkb_keymap_new_from_names(context, &rules,
			XKB_KEYMAP_COMPILE_NO_FLAGS))) {
		fputs("Couldn't create xkbcommon keymap\n", stderr);
		return EXIT_FAILURE;
	}

	if (!(state = xkb_state_new(keymap))) {
		fputs("Couldn't create xkbcommon state\n", stderr);
		return EXIT_FAILURE;
	}

	min_keycode = xkb_keymap_min_keycode(keymap);
	max_keycode = xkb_keymap_max_keycode(keymap);

	for (keycode = min_keycode; keycode <= max_keycode; keycode++) {
		nsyms = xkb_state_key_get_syms(state, keycode, &syms);
		for (i = 0; i < nsyms; i++) {
			xkb_keysym_get_name(syms[i], keyname, sizeof(keyname) / sizeof(keyname[0]));
			fprintf(f, "#define Key_%-24s %d\n", keyname, keycode);
		}
	}

	xkb_state_unref(state);
	xkb_keymap_unref(keymap);
	xkb_context_unref(context);
}

A keycodes-diff.patch => keycodes-diff.patch +556 -0
@@ 0,0 1,556 @@
diff --git a/config.def.h b/config.def.h
index 8847e58..c8d1dc3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -104,11 +104,11 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 /* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
 #define MODKEY WLR_MODIFIER_ALT
 
-#define TAGKEYS(KEY,SKEY,TAG) \
+#define TAGKEYS(KEY,TAG) \
 	{ MODKEY,                    KEY,            view,            {.ui = 1 << TAG} }, \
 	{ MODKEY|WLR_MODIFIER_CTRL,  KEY,            toggleview,      {.ui = 1 << TAG} }, \
-	{ MODKEY|WLR_MODIFIER_SHIFT, SKEY,           tag,             {.ui = 1 << TAG} }, \
-	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
+	{ MODKEY|WLR_MODIFIER_SHIFT, KEY,            tag,             {.ui = 1 << TAG} }, \
+	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,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 } }
@@ -117,51 +117,52 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 static const char *termcmd[] = { "foot", NULL };
 static const char *menucmd[] = { "bemenu-run", NULL };
 
+#include "keys.h"
 static const Key keys[] = {
-	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
 	/* modifier                  key                 function        argument */
-	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd} },
-	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
-	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
-	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} },
-	{ MODKEY,                    XKB_KEY_d,          incnmaster,     {.i = -1} },
-	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05f} },
-	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} },
-	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} },
-	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C,          killclient,     {0} },
-	{ MODKEY,                    XKB_KEY_t,          setlayout,      {.v = &layouts[0]} },
-	{ MODKEY,                    XKB_KEY_f,          setlayout,      {.v = &layouts[1]} },
-	{ MODKEY,                    XKB_KEY_m,          setlayout,      {.v = &layouts[2]} },
-	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
-	{ MODKEY,                    XKB_KEY_e,         togglefullscreen, {0} },
-	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
-	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
-	{ MODKEY,                    XKB_KEY_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less,       tagmon,         {.i = WLR_DIRECTION_LEFT} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater,    tagmon,         {.i = WLR_DIRECTION_RIGHT} },
-	TAGKEYS(          XKB_KEY_1, XKB_KEY_exclam,                     0),
-	TAGKEYS(          XKB_KEY_2, XKB_KEY_at,                         1),
-	TAGKEYS(          XKB_KEY_3, XKB_KEY_numbersign,                 2),
-	TAGKEYS(          XKB_KEY_4, XKB_KEY_dollar,                     3),
-	TAGKEYS(          XKB_KEY_5, XKB_KEY_percent,                    4),
-	TAGKEYS(          XKB_KEY_6, XKB_KEY_asciicircum,                5),
-	TAGKEYS(          XKB_KEY_7, XKB_KEY_ampersand,                  6),
-	TAGKEYS(          XKB_KEY_8, XKB_KEY_asterisk,                   7),
-	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
+	{ MODKEY,                    Key_p,          spawn,          {.v = menucmd} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_Return,     spawn,          {.v = termcmd} },
+	{ MODKEY,                    Key_j,          focusstack,     {.i = +1} },
+	{ MODKEY,                    Key_k,          focusstack,     {.i = -1} },
+	{ MODKEY,                    Key_i,          incnmaster,     {.i = +1} },
+	{ MODKEY,                    Key_d,          incnmaster,     {.i = -1} },
+	{ MODKEY,                    Key_h,          setmfact,       {.f = -0.05f} },
+	{ MODKEY,                    Key_l,          setmfact,       {.f = +0.05f} },
+	{ MODKEY,                    Key_Return,     zoom,           {0} },
+	{ MODKEY,                    Key_Tab,        view,           {0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_c,          killclient,     {0} },
+	{ MODKEY,                    Key_t,          setlayout,      {.v = &layouts[0]} },
+	{ MODKEY,                    Key_f,          setlayout,      {.v = &layouts[1]} },
+	{ MODKEY,                    Key_m,          setlayout,      {.v = &layouts[2]} },
+	{ MODKEY,                    Key_space,      setlayout,      {0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_space,      togglefloating, {0} },
+	{ MODKEY,                    Key_e,          togglefullscreen, {0} },
+	{ MODKEY,                    Key_0,          view,           {.ui = ~0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_0,          tag,            {.ui = ~0} },
+	{ MODKEY,                    Key_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
+	{ MODKEY,                    Key_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_comma,      tagmon,         {.i = WLR_DIRECTION_LEFT} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_period,     tagmon,         {.i = WLR_DIRECTION_RIGHT} },
+	TAGKEYS(                     Key_1,                          0),
+	TAGKEYS(                     Key_2,                          1),
+	TAGKEYS(                     Key_3,                          2),
+	TAGKEYS(                     Key_4,                          3),
+	TAGKEYS(                     Key_5,                          4),
+	TAGKEYS(                     Key_6,                          5),
+	TAGKEYS(                     Key_7,                          6),
+	TAGKEYS(                     Key_8,                          7),
+	TAGKEYS(                     Key_9,                          8),
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_q,          quit,           {0} },
 
 	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
-	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
+	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,Key_BackSpace, quit, {0} },
 	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
 	 * do not remove them.
 	 */
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
-	CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
-	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
+#define CHVT(KEY,n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, KEY, chvt, {.ui = (n)} }
+	CHVT(Key_F1, 1), CHVT(Key_F2,  2),  CHVT(Key_F3,  3),  CHVT(Key_F4,  4),
+	CHVT(Key_F5, 5), CHVT(Key_F6,  6),  CHVT(Key_F7,  7),  CHVT(Key_F8,  8),
+	CHVT(Key_F9, 9), CHVT(Key_F10, 10), CHVT(Key_F11, 11), CHVT(Key_F12, 12),
 };
 
 static const Button buttons[] = {
diff --git a/dwl.c b/dwl.c
index bf763df..21b71d0 100644
--- a/dwl.c
+++ b/dwl.c
@@ -143,7 +143,7 @@ typedef struct {
 
 typedef struct {
 	uint32_t mod;
-	xkb_keysym_t keysym;
+	xkb_keycode_t keycode;
 	void (*func)(const Arg *);
 	const Arg arg;
 } Key;
@@ -152,9 +152,8 @@ typedef struct {
 	struct wl_list link;
 	struct wlr_keyboard_group *wlr_group;
 
-	int nsyms;
-	const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
-	uint32_t mods; /* invalid if nsyms == 0 */
+	xkb_keycode_t keycode;
+	uint32_t mods; /* invalid if keycode == 0 */
 	struct wl_event_source *key_repeat_source;
 
 	struct wl_listener modifiers;
@@ -286,7 +285,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data);
 static void handlesig(int signo);
 static void incnmaster(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
-static int keybinding(uint32_t mods, xkb_keysym_t sym);
+static int keybinding(uint32_t mods, xkb_keycode_t keycode);
 static void keypress(struct wl_listener *listener, void *data);
 static void keypressmod(struct wl_listener *listener, void *data);
 static int keyrepeat(void *data);
@@ -1428,7 +1427,7 @@ inputdevice(struct wl_listener *listener, void *data)
 }
 
 int
-keybinding(uint32_t mods, xkb_keysym_t sym)
+keybinding(uint32_t mods, xkb_keycode_t keycode)
 {
 	/*
 	 * Here we handle compositor keybindings. This is when the compositor is
@@ -1438,7 +1437,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	const Key *k;
 	for (k = keys; k < END(keys); k++) {
 		if (CLEANMASK(mods) == CLEANMASK(k->mod)
-				&& sym == k->keysym && k->func) {
+				&& keycode == k->keycode && k->func) {
 			k->func(&k->arg);
 			return 1;
 		}
@@ -1449,17 +1448,12 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 void
 keypress(struct wl_listener *listener, void *data)
 {
-	int i;
 	/* This event is raised when a key is pressed or released. */
 	KeyboardGroup *group = wl_container_of(listener, group, key);
 	struct wlr_keyboard_key_event *event = data;
 
 	/* Translate libinput keycode -> xkbcommon */
 	uint32_t keycode = event->keycode + 8;
-	/* Get a list of keysyms based on the keymap for this keyboard */
-	const xkb_keysym_t *syms;
-	int nsyms = xkb_state_key_get_syms(
-			group->wlr_group->keyboard.xkb_state, keycode, &syms);
 
 	int handled = 0;
 	uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
@@ -1469,18 +1463,16 @@ keypress(struct wl_listener *listener, void *data)
 	/* On _press_ if there is no active screen locker,
 	 * attempt to process a compositor keybinding. */
 	if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-		for (i = 0; i < nsyms; i++)
-			handled = keybinding(mods, syms[i]) || handled;
+		handled = keybinding(mods, keycode);
 	}
 
 	if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
 		group->mods = mods;
-		group->keysyms = syms;
-		group->nsyms = nsyms;
+		group->keycode = keycode;
 		wl_event_source_timer_update(group->key_repeat_source,
 				group->wlr_group->keyboard.repeat_info.delay);
 	} else {
-		group->nsyms = 0;
+		group->keycode = 0;
 		wl_event_source_timer_update(group->key_repeat_source, 0);
 	}
 
@@ -1510,15 +1502,13 @@ int
 keyrepeat(void *data)
 {
 	KeyboardGroup *group = data;
-	int i;
-	if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
+	if (!group->keycode || group->wlr_group->keyboard.repeat_info.rate <= 0)
 		return 0;
 
 	wl_event_source_timer_update(group->key_repeat_source,
 			1000 / group->wlr_group->keyboard.repeat_info.rate);
 
-	for (i = 0; i < group->nsyms; i++)
-		keybinding(group->mods, group->keysyms[i]);
+	keybinding(group->mods, group->keycode);
 
 	return 0;
 }
diff --git a/generate-keys.c b/generate-keys.c
new file mode 100644
index 0000000..83458fb
--- /dev/null
+++ b/generate-keys.c
@@ -0,0 +1,82 @@
+/******************************************************************
+ * Copyright 2023 Leonardo Hernández Hernández
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the “Software”), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************/
+
+/* cc -lxkbcommon -o generate-keys generate-keys.c */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <xkbcommon/xkbcommon.h>
+
+int
+main(void)
+{
+	struct xkb_context *context;
+	/* Allow generate keys with a different layout and variant.
+	 * You can also use XKB_DEFAULT_* environmental variables and let this as is */
+	struct xkb_rule_names rules = {
+		0
+	};
+	struct xkb_keymap *keymap;
+	struct xkb_state *state;
+	xkb_keycode_t keycode, min_keycode, max_keycode;
+	int i, nsyms;
+	const xkb_keysym_t *syms;
+	char keyname[64];
+	FILE *f = fopen("keys.h", "w");
+	if (!f) {
+		perror("Couldn't open keys.h");
+		return EXIT_FAILURE;
+	}
+
+	if (!(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS))) {
+		fputs("Couldn't create xkbcommon context\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	if (!(keymap = xkb_keymap_new_from_names(context, &rules,
+			XKB_KEYMAP_COMPILE_NO_FLAGS))) {
+		fputs("Couldn't create xkbcommon keymap\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	if (!(state = xkb_state_new(keymap))) {
+		fputs("Couldn't create xkbcommon state\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	min_keycode = xkb_keymap_min_keycode(keymap);
+	max_keycode = xkb_keymap_max_keycode(keymap);
+
+	for (keycode = min_keycode; keycode <= max_keycode; keycode++) {
+		nsyms = xkb_state_key_get_syms(state, keycode, &syms);
+		for (i = 0; i < nsyms; i++) {
+			xkb_keysym_get_name(syms[i], keyname, sizeof(keyname) / sizeof(keyname[0]));
+			fprintf(f, "#define Key_%-24s %d\n", keyname, keycode);
+		}
+	}
+
+	xkb_state_unref(state);
+	xkb_keymap_unref(keymap);
+	xkb_context_unref(context);
+}
diff --git a/keys.h b/keys.h
new file mode 100644
index 0000000..e732f80
--- /dev/null
+++ b/keys.h
@@ -0,0 +1,242 @@
+/* You can use the macros within this file
+ * instead of search the keycodes yourself
+ * with wev or something like that
+ * Also probably you search this:
+ *    Key_XF86AudioMute
+ *    Key_XF86AudioLowerVolume
+ *    Key_XF86AudioRaiseVolume
+ *    Key_XF86MonBrightnessDown
+ *    Key_XF86MonBrightnessUp
+*/
+
+#define Key_Escape                   9
+#define Key_1                        10
+#define Key_2                        11
+#define Key_3                        12
+#define Key_4                        13
+#define Key_5                        14
+#define Key_6                        15
+#define Key_7                        16
+#define Key_8                        17
+#define Key_9                        18
+#define Key_0                        19
+#define Key_minus                    20
+#define Key_equal                    21
+#define Key_BackSpace                22
+#define Key_Tab                      23
+#define Key_q                        24
+#define Key_w                        25
+#define Key_e                        26
+#define Key_r                        27
+#define Key_t                        28
+#define Key_y                        29
+#define Key_u                        30
+#define Key_i                        31
+#define Key_o                        32
+#define Key_p                        33
+#define Key_bracketleft              34
+#define Key_bracketright             35
+#define Key_Return                   36
+#define Key_Control_L                37
+#define Key_a                        38
+#define Key_s                        39
+#define Key_d                        40
+#define Key_f                        41
+#define Key_g                        42
+#define Key_h                        43
+#define Key_j                        44
+#define Key_k                        45
+#define Key_l                        46
+#define Key_semicolon                47
+#define Key_apostrophe               48
+#define Key_grave                    49
+#define Key_Shift_L                  50
+#define Key_backslash                51
+#define Key_z                        52
+#define Key_x                        53
+#define Key_c                        54
+#define Key_v                        55
+#define Key_b                        56
+#define Key_n                        57
+#define Key_m                        58
+#define Key_comma                    59
+#define Key_period                   60
+#define Key_slash                    61
+#define Key_Shift_R                  62
+#define Key_KP_Multiply              63
+#define Key_Alt_L                    64
+#define Key_space                    65
+#define Key_Caps_Lock                66
+#define Key_F1                       67
+#define Key_F2                       68
+#define Key_F3                       69
+#define Key_F4                       70
+#define Key_F5                       71
+#define Key_F6                       72
+#define Key_F7                       73
+#define Key_F8                       74
+#define Key_F9                       75
+#define Key_F10                      76
+#define Key_Num_Lock                 77
+#define Key_Scroll_Lock              78
+#define Key_KP_Home                  79
+#define Key_KP_7                     Key_KP_Home
+#define Key_KP_Up                    80
+#define Key_KP_8                     Key_KP_Up
+#define Key_KP_Prior                 81
+#define Key_KP_9                     Key_KP_Prior
+#define Key_KP_Subtract              82
+#define Key_KP_Left                  83
+#define Key_KP_4                     Key_KP_Left
+#define Key_KP_Begin                 84
+#define Key_KP_5                     Key_KP_Begin
+#define Key_KP_Right                 85
+#define Key_KP_6                     Key_KP_Right
+#define Key_KP_Add                   86
+#define Key_KP_End                   87
+#define Key_KP_1                     Key_KP_End
+#define Key_KP_Down                  88
+#define Key_KP_2                     Key_KP_Down
+#define Key_KP_Next                  89
+#define Key_KP_3                     Key_KP_Next
+#define Key_KP_Insert                90
+#define Key_KP_0                     Key_KP_Insert
+#define Key_KP_Delete                91
+#define Key_KP_Period                Key_KP_Insert
+#define Key_ISO_Level3_Shift         92
+#define Key_less                     94
+#define Key_F11                      95
+#define Key_F12                      96
+#define Key_Katakana                 98
+#define Key_Hiragana                 99
+#define Key_Henkan_Mode              100
+#define Key_Hiragana_Katakana        101
+#define Key_Muhenkan                 102
+#define Key_KP_Enter                 104
+#define Key_Control_R                105
+#define Key_KP_Divide                106
+#define Key_Print                    107
+#define Key_Alt_R                    108
+#define Key_Linefeed                 109
+#define Key_Home                     110
+#define Key_Up                       111
+#define Key_Prior                    112
+#define Key_Left                     113
+#define Key_Right                    114
+#define Key_End                      115
+#define Key_Down                     116
+#define Key_Next                     117
+#define Key_Insert                   118
+#define Key_Delete                   119
+#define Key_XF86AudioMute            121
+#define Key_XF86AudioLowerVolume     122
+#define Key_XF86AudioRaiseVolume     123
+#define Key_XF86PowerOff             124
+#define Key_KP_Equal                 125
+#define Key_plusminus                126
+#define Key_Pause                    127
+#define Key_XF86LaunchA              128
+#define Key_KP_Decimal               129
+#define Key_Hangul                   130
+#define Key_Hangul_Hanja             131
+#define Key_Super_L                  133
+#define Key_Super_R                  134
+#define Key_Menu                     135
+#define Key_Cancel                   136
+#define Key_Redo                     137
+#define Key_SunProps                 138
+#define Key_Undo                     139
+#define Key_SunFront                 140
+#define Key_XF86Copy                 141
+#define Key_XF86Open                 142
+#define Key_XF86Paste                143
+#define Key_Find                     144
+#define Key_XF86Cut                  145
+#define Key_Help                     146
+#define Key_XF86MenuKB               147
+#define Key_XF86Calculator           148
+#define Key_XF86Sleep                150
+#define Key_XF86WakeUp               151
+#define Key_XF86Explorer             152
+#define Key_XF86Send                 153
+#define Key_XF86Xfer                 155
+#define Key_XF86Launch1              156
+#define Key_XF86Launch2              157
+#define Key_XF86WWW                  158
+#define Key_XF86DOS                  159
+#define Key_XF86ScreenSaver          160
+#define Key_XF86RotateWindows        161
+#define Key_XF86TaskPane             162
+#define Key_XF86Mail                 163
+#define Key_XF86Favorites            164
+#define Key_XF86MyComputer           165
+#define Key_XF86Back                 166
+#define Key_XF86Forward              167
+#define Key_XF86Eject1               169
+#define Key_XF86Eject2               170
+#define Key_XF86AudioNext            171
+#define Key_XF86AudioPlay            172
+#define Key_XF86AudioPrev            173
+#define Key_XF86AudioStop            174
+#define Key_XF86AudioRecord          175
+#define Key_XF86AudioRewind          176
+#define Key_XF86Phone                177
+#define Key_XF86Tools                179
+#define Key_XF86HomePage             180
+#define Key_XF86Reload               181
+#define Key_XF86Close                182
+#define Key_XF86ScrollUp             185
+#define Key_XF86ScrollDown           186
+#define Key_parenleft                187
+#define Key_parenright               188
+#define Key_XF86New                  189
+#define Key_Redo2                    190
+#define Key_XF86Tools2               191
+#define Key_XF86Launch5              192
+#define Key_XF86Launch6              193
+#define Key_XF86Launch7              194
+#define Key_XF86Launch8              195
+#define Key_XF86Launch9              196
+#define Key_XF86AudioMicMute         198
+#define Key_XF86TouchpadToggle       199
+#define Key_XF86TouchpadOn           200
+#define Key_XF86TouchpadOff          201
+#define Key_Mode_switch              203
+#define Key_XF86AudioPlay2           208
+#define Key_XF86AudioPause           209
+#define Key_XF86Launch3              210
+#define Key_XF86Launch4              211
+#define Key_XF86LaunchB              212
+#define Key_XF86Suspend              213
+#define Key_XF86Close2               214
+#define Key_XF86AudioPlay3           215
+#define Key_XF86AudioForward         216
+#define Key_Print2                   218
+#define Key_XF86WebCam               220
+#define Key_XF86AudioPreset          221
+#define Key_XF86Mail2                223
+#define Key_XF86Messenger            224
+#define Key_XF86Search               225
+#define Key_XF86Go                   226
+#define Key_XF86Finance              227
+#define Key_XF86Game                 228
+#define Key_XF86Shop                 229
+#define Key_Cancel2                  231
+#define Key_XF86MonBrightnessDown    232
+#define Key_XF86MonBrightnessUp      233
+#define Key_XF86AudioMedia           234
+#define Key_XF86Display              235
+#define Key_XF86KbdLightOnOff        236
+#define Key_XF86KbdBrightnessDown    237
+#define Key_XF86KbdBrightnessUp      238
+#define Key_XF86Send2                239
+#define Key_XF86Reply                240
+#define Key_XF86MailForward          241
+#define Key_XF86Save                 242
+#define Key_XF86Documents            243
+#define Key_XF86Battery              244
+#define Key_XF86Bluetooth            245
+#define Key_XF86WLAN                 246
+#define Key_XF86MonBrightnessCycle   251
+#define Key_XF86WWAN                 254
+#define Key_XF86RFKill               255

A keycodes.patch => keycodes.patch +574 -0
@@ 0,0 1,574 @@
From 07eae726a122e57f5233eef89f659728bf4298b1 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 16:03:01 -0500
Subject: [PATCH] use keycodes instead of keysyms

inspiration: https://codeberg.org/dwl/dwl-patches/wiki/keycodes
---
 config.def.h    |  83 +++++++++--------
 dwl.c           |  32 +++----
 generate-keys.c |  82 ++++++++++++++++
 keys.h          | 242 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 377 insertions(+), 62 deletions(-)
 create mode 100644 generate-keys.c
 create mode 100644 keys.h

diff --git a/config.def.h b/config.def.h
index 8847e58..c8d1dc3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -104,11 +104,11 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 /* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
 #define MODKEY WLR_MODIFIER_ALT
 
-#define TAGKEYS(KEY,SKEY,TAG) \
+#define TAGKEYS(KEY,TAG) \
 	{ MODKEY,                    KEY,            view,            {.ui = 1 << TAG} }, \
 	{ MODKEY|WLR_MODIFIER_CTRL,  KEY,            toggleview,      {.ui = 1 << TAG} }, \
-	{ MODKEY|WLR_MODIFIER_SHIFT, SKEY,           tag,             {.ui = 1 << TAG} }, \
-	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
+	{ MODKEY|WLR_MODIFIER_SHIFT, KEY,            tag,             {.ui = 1 << TAG} }, \
+	{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,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 } }
@@ -117,51 +117,52 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 static const char *termcmd[] = { "foot", NULL };
 static const char *menucmd[] = { "bemenu-run", NULL };
 
+#include "keys.h"
 static const Key keys[] = {
-	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
 	/* modifier                  key                 function        argument */
-	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd} },
-	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
-	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
-	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} },
-	{ MODKEY,                    XKB_KEY_d,          incnmaster,     {.i = -1} },
-	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05f} },
-	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} },
-	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} },
-	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C,          killclient,     {0} },
-	{ MODKEY,                    XKB_KEY_t,          setlayout,      {.v = &layouts[0]} },
-	{ MODKEY,                    XKB_KEY_f,          setlayout,      {.v = &layouts[1]} },
-	{ MODKEY,                    XKB_KEY_m,          setlayout,      {.v = &layouts[2]} },
-	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
-	{ MODKEY,                    XKB_KEY_e,         togglefullscreen, {0} },
-	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
-	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
-	{ MODKEY,                    XKB_KEY_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less,       tagmon,         {.i = WLR_DIRECTION_LEFT} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater,    tagmon,         {.i = WLR_DIRECTION_RIGHT} },
-	TAGKEYS(          XKB_KEY_1, XKB_KEY_exclam,                     0),
-	TAGKEYS(          XKB_KEY_2, XKB_KEY_at,                         1),
-	TAGKEYS(          XKB_KEY_3, XKB_KEY_numbersign,                 2),
-	TAGKEYS(          XKB_KEY_4, XKB_KEY_dollar,                     3),
-	TAGKEYS(          XKB_KEY_5, XKB_KEY_percent,                    4),
-	TAGKEYS(          XKB_KEY_6, XKB_KEY_asciicircum,                5),
-	TAGKEYS(          XKB_KEY_7, XKB_KEY_ampersand,                  6),
-	TAGKEYS(          XKB_KEY_8, XKB_KEY_asterisk,                   7),
-	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
+	{ MODKEY,                    Key_p,          spawn,          {.v = menucmd} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_Return,     spawn,          {.v = termcmd} },
+	{ MODKEY,                    Key_j,          focusstack,     {.i = +1} },
+	{ MODKEY,                    Key_k,          focusstack,     {.i = -1} },
+	{ MODKEY,                    Key_i,          incnmaster,     {.i = +1} },
+	{ MODKEY,                    Key_d,          incnmaster,     {.i = -1} },
+	{ MODKEY,                    Key_h,          setmfact,       {.f = -0.05f} },
+	{ MODKEY,                    Key_l,          setmfact,       {.f = +0.05f} },
+	{ MODKEY,                    Key_Return,     zoom,           {0} },
+	{ MODKEY,                    Key_Tab,        view,           {0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_c,          killclient,     {0} },
+	{ MODKEY,                    Key_t,          setlayout,      {.v = &layouts[0]} },
+	{ MODKEY,                    Key_f,          setlayout,      {.v = &layouts[1]} },
+	{ MODKEY,                    Key_m,          setlayout,      {.v = &layouts[2]} },
+	{ MODKEY,                    Key_space,      setlayout,      {0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_space,      togglefloating, {0} },
+	{ MODKEY,                    Key_e,          togglefullscreen, {0} },
+	{ MODKEY,                    Key_0,          view,           {.ui = ~0} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_0,          tag,            {.ui = ~0} },
+	{ MODKEY,                    Key_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
+	{ MODKEY,                    Key_period,     focusmon,       {.i = WLR_DIRECTION_RIGHT} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_comma,      tagmon,         {.i = WLR_DIRECTION_LEFT} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_period,     tagmon,         {.i = WLR_DIRECTION_RIGHT} },
+	TAGKEYS(                     Key_1,                          0),
+	TAGKEYS(                     Key_2,                          1),
+	TAGKEYS(                     Key_3,                          2),
+	TAGKEYS(                     Key_4,                          3),
+	TAGKEYS(                     Key_5,                          4),
+	TAGKEYS(                     Key_6,                          5),
+	TAGKEYS(                     Key_7,                          6),
+	TAGKEYS(                     Key_8,                          7),
+	TAGKEYS(                     Key_9,                          8),
+	{ MODKEY|WLR_MODIFIER_SHIFT, Key_q,          quit,           {0} },
 
 	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
-	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
+	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,Key_BackSpace, quit, {0} },
 	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
 	 * do not remove them.
 	 */
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
-	CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
-	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
+#define CHVT(KEY,n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, KEY, chvt, {.ui = (n)} }
+	CHVT(Key_F1, 1), CHVT(Key_F2,  2),  CHVT(Key_F3,  3),  CHVT(Key_F4,  4),
+	CHVT(Key_F5, 5), CHVT(Key_F6,  6),  CHVT(Key_F7,  7),  CHVT(Key_F8,  8),
+	CHVT(Key_F9, 9), CHVT(Key_F10, 10), CHVT(Key_F11, 11), CHVT(Key_F12, 12),
 };
 
 static const Button buttons[] = {
diff --git a/dwl.c b/dwl.c
index bf763df..21b71d0 100644
--- a/dwl.c
+++ b/dwl.c
@@ -143,7 +143,7 @@ typedef struct {
 
 typedef struct {
 	uint32_t mod;
-	xkb_keysym_t keysym;
+	xkb_keycode_t keycode;
 	void (*func)(const Arg *);
 	const Arg arg;
 } Key;
@@ -152,9 +152,8 @@ typedef struct {
 	struct wl_list link;
 	struct wlr_keyboard_group *wlr_group;
 
-	int nsyms;
-	const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
-	uint32_t mods; /* invalid if nsyms == 0 */
+	xkb_keycode_t keycode;
+	uint32_t mods; /* invalid if keycode == 0 */
 	struct wl_event_source *key_repeat_source;
 
 	struct wl_listener modifiers;
@@ -286,7 +285,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data);
 static void handlesig(int signo);
 static void incnmaster(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
-static int keybinding(uint32_t mods, xkb_keysym_t sym);
+static int keybinding(uint32_t mods, xkb_keycode_t keycode);
 static void keypress(struct wl_listener *listener, void *data);
 static void keypressmod(struct wl_listener *listener, void *data);
 static int keyrepeat(void *data);
@@ -1428,7 +1427,7 @@ inputdevice(struct wl_listener *listener, void *data)
 }
 
 int
-keybinding(uint32_t mods, xkb_keysym_t sym)
+keybinding(uint32_t mods, xkb_keycode_t keycode)
 {
 	/*
 	 * Here we handle compositor keybindings. This is when the compositor is
@@ -1438,7 +1437,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	const Key *k;
 	for (k = keys; k < END(keys); k++) {
 		if (CLEANMASK(mods) == CLEANMASK(k->mod)
-				&& sym == k->keysym && k->func) {
+				&& keycode == k->keycode && k->func) {
 			k->func(&k->arg);
 			return 1;
 		}
@@ -1449,17 +1448,12 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 void
 keypress(struct wl_listener *listener, void *data)
 {
-	int i;
 	/* This event is raised when a key is pressed or released. */
 	KeyboardGroup *group = wl_container_of(listener, group, key);
 	struct wlr_keyboard_key_event *event = data;
 
 	/* Translate libinput keycode -> xkbcommon */
 	uint32_t keycode = event->keycode + 8;
-	/* Get a list of keysyms based on the keymap for this keyboard */
-	const xkb_keysym_t *syms;
-	int nsyms = xkb_state_key_get_syms(
-			group->wlr_group->keyboard.xkb_state, keycode, &syms);
 
 	int handled = 0;
 	uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
@@ -1469,18 +1463,16 @@ keypress(struct wl_listener *listener, void *data)
 	/* On _press_ if there is no active screen locker,
 	 * attempt to process a compositor keybinding. */
 	if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-		for (i = 0; i < nsyms; i++)
-			handled = keybinding(mods, syms[i]) || handled;
+		handled = keybinding(mods, keycode);
 	}
 
 	if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
 		group->mods = mods;
-		group->keysyms = syms;
-		group->nsyms = nsyms;
+		group->keycode = keycode;
 		wl_event_source_timer_update(group->key_repeat_source,
 				group->wlr_group->keyboard.repeat_info.delay);
 	} else {
-		group->nsyms = 0;
+		group->keycode = 0;
 		wl_event_source_timer_update(group->key_repeat_source, 0);
 	}
 
@@ -1510,15 +1502,13 @@ int
 keyrepeat(void *data)
 {
 	KeyboardGroup *group = data;
-	int i;
-	if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
+	if (!group->keycode || group->wlr_group->keyboard.repeat_info.rate <= 0)
 		return 0;
 
 	wl_event_source_timer_update(group->key_repeat_source,
 			1000 / group->wlr_group->keyboard.repeat_info.rate);
 
-	for (i = 0; i < group->nsyms; i++)
-		keybinding(group->mods, group->keysyms[i]);
+	keybinding(group->mods, group->keycode);
 
 	return 0;
 }
diff --git a/generate-keys.c b/generate-keys.c
new file mode 100644
index 0000000..83458fb
--- /dev/null
+++ b/generate-keys.c
@@ -0,0 +1,82 @@
+/******************************************************************
+ * Copyright 2023 Leonardo Hernández Hernández
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the “Software”), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************/
+
+/* cc -lxkbcommon -o generate-keys generate-keys.c */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <xkbcommon/xkbcommon.h>
+
+int
+main(void)
+{
+	struct xkb_context *context;
+	/* Allow generate keys with a different layout and variant.
+	 * You can also use XKB_DEFAULT_* environmental variables and let this as is */
+	struct xkb_rule_names rules = {
+		0
+	};
+	struct xkb_keymap *keymap;
+	struct xkb_state *state;
+	xkb_keycode_t keycode, min_keycode, max_keycode;
+	int i, nsyms;
+	const xkb_keysym_t *syms;
+	char keyname[64];
+	FILE *f = fopen("keys.h", "w");
+	if (!f) {
+		perror("Couldn't open keys.h");
+		return EXIT_FAILURE;
+	}
+
+	if (!(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS))) {
+		fputs("Couldn't create xkbcommon context\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	if (!(keymap = xkb_keymap_new_from_names(context, &rules,
+			XKB_KEYMAP_COMPILE_NO_FLAGS))) {
+		fputs("Couldn't create xkbcommon keymap\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	if (!(state = xkb_state_new(keymap))) {
+		fputs("Couldn't create xkbcommon state\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+	min_keycode = xkb_keymap_min_keycode(keymap);
+	max_keycode = xkb_keymap_max_keycode(keymap);
+
+	for (keycode = min_keycode; keycode <= max_keycode; keycode++) {
+		nsyms = xkb_state_key_get_syms(state, keycode, &syms);
+		for (i = 0; i < nsyms; i++) {
+			xkb_keysym_get_name(syms[i], keyname, sizeof(keyname) / sizeof(keyname[0]));
+			fprintf(f, "#define Key_%-24s %d\n", keyname, keycode);
+		}
+	}
+
+	xkb_state_unref(state);
+	xkb_keymap_unref(keymap);
+	xkb_context_unref(context);
+}
diff --git a/keys.h b/keys.h
new file mode 100644
index 0000000..e732f80
--- /dev/null
+++ b/keys.h
@@ -0,0 +1,242 @@
+/* You can use the macros within this file
+ * instead of search the keycodes yourself
+ * with wev or something like that
+ * Also probably you search this:
+ *    Key_XF86AudioMute
+ *    Key_XF86AudioLowerVolume
+ *    Key_XF86AudioRaiseVolume
+ *    Key_XF86MonBrightnessDown
+ *    Key_XF86MonBrightnessUp
+*/
+
+#define Key_Escape                   9
+#define Key_1                        10
+#define Key_2                        11
+#define Key_3                        12
+#define Key_4                        13
+#define Key_5                        14
+#define Key_6                        15
+#define Key_7                        16
+#define Key_8                        17
+#define Key_9                        18
+#define Key_0                        19
+#define Key_minus                    20
+#define Key_equal                    21
+#define Key_BackSpace                22
+#define Key_Tab                      23
+#define Key_q                        24
+#define Key_w                        25
+#define Key_e                        26
+#define Key_r                        27
+#define Key_t                        28
+#define Key_y                        29
+#define Key_u                        30
+#define Key_i                        31
+#define Key_o                        32
+#define Key_p                        33
+#define Key_bracketleft              34
+#define Key_bracketright             35
+#define Key_Return                   36
+#define Key_Control_L                37
+#define Key_a                        38
+#define Key_s                        39
+#define Key_d                        40
+#define Key_f                        41
+#define Key_g                        42
+#define Key_h                        43
+#define Key_j                        44
+#define Key_k                        45
+#define Key_l                        46
+#define Key_semicolon                47
+#define Key_apostrophe               48
+#define Key_grave                    49
+#define Key_Shift_L                  50
+#define Key_backslash                51
+#define Key_z                        52
+#define Key_x                        53
+#define Key_c                        54
+#define Key_v                        55
+#define Key_b                        56
+#define Key_n                        57
+#define Key_m                        58
+#define Key_comma                    59
+#define Key_period                   60
+#define Key_slash                    61
+#define Key_Shift_R                  62
+#define Key_KP_Multiply              63
+#define Key_Alt_L                    64
+#define Key_space                    65
+#define Key_Caps_Lock                66
+#define Key_F1                       67
+#define Key_F2                       68
+#define Key_F3                       69
+#define Key_F4                       70
+#define Key_F5                       71
+#define Key_F6                       72
+#define Key_F7                       73
+#define Key_F8                       74
+#define Key_F9                       75
+#define Key_F10                      76
+#define Key_Num_Lock                 77
+#define Key_Scroll_Lock              78
+#define Key_KP_Home                  79
+#define Key_KP_7                     Key_KP_Home
+#define Key_KP_Up                    80
+#define Key_KP_8                     Key_KP_Up
+#define Key_KP_Prior                 81
+#define Key_KP_9                     Key_KP_Prior
+#define Key_KP_Subtract              82
+#define Key_KP_Left                  83
+#define Key_KP_4                     Key_KP_Left
+#define Key_KP_Begin                 84
+#define Key_KP_5                     Key_KP_Begin
+#define Key_KP_Right                 85
+#define Key_KP_6                     Key_KP_Right
+#define Key_KP_Add                   86
+#define Key_KP_End                   87
+#define Key_KP_1                     Key_KP_End
+#define Key_KP_Down                  88
+#define Key_KP_2                     Key_KP_Down
+#define Key_KP_Next                  89
+#define Key_KP_3                     Key_KP_Next
+#define Key_KP_Insert                90
+#define Key_KP_0                     Key_KP_Insert
+#define Key_KP_Delete                91
+#define Key_KP_Period                Key_KP_Insert
+#define Key_ISO_Level3_Shift         92
+#define Key_less                     94
+#define Key_F11                      95
+#define Key_F12                      96
+#define Key_Katakana                 98
+#define Key_Hiragana                 99
+#define Key_Henkan_Mode              100
+#define Key_Hiragana_Katakana        101
+#define Key_Muhenkan                 102
+#define Key_KP_Enter                 104
+#define Key_Control_R                105
+#define Key_KP_Divide                106
+#define Key_Print                    107
+#define Key_Alt_R                    108
+#define Key_Linefeed                 109
+#define Key_Home                     110
+#define Key_Up                       111
+#define Key_Prior                    112
+#define Key_Left                     113
+#define Key_Right                    114
+#define Key_End                      115
+#define Key_Down                     116
+#define Key_Next                     117
+#define Key_Insert                   118
+#define Key_Delete                   119
+#define Key_XF86AudioMute            121
+#define Key_XF86AudioLowerVolume     122
+#define Key_XF86AudioRaiseVolume     123
+#define Key_XF86PowerOff             124
+#define Key_KP_Equal                 125
+#define Key_plusminus                126
+#define Key_Pause                    127
+#define Key_XF86LaunchA              128
+#define Key_KP_Decimal               129
+#define Key_Hangul                   130
+#define Key_Hangul_Hanja             131
+#define Key_Super_L                  133
+#define Key_Super_R                  134
+#define Key_Menu                     135
+#define Key_Cancel                   136
+#define Key_Redo                     137
+#define Key_SunProps                 138
+#define Key_Undo                     139
+#define Key_SunFront                 140
+#define Key_XF86Copy                 141
+#define Key_XF86Open                 142
+#define Key_XF86Paste                143
+#define Key_Find                     144
+#define Key_XF86Cut                  145
+#define Key_Help                     146
+#define Key_XF86MenuKB               147
+#define Key_XF86Calculator           148
+#define Key_XF86Sleep                150
+#define Key_XF86WakeUp               151
+#define Key_XF86Explorer             152
+#define Key_XF86Send                 153
+#define Key_XF86Xfer                 155
+#define Key_XF86Launch1              156
+#define Key_XF86Launch2              157
+#define Key_XF86WWW                  158
+#define Key_XF86DOS                  159
+#define Key_XF86ScreenSaver          160
+#define Key_XF86RotateWindows        161
+#define Key_XF86TaskPane             162
+#define Key_XF86Mail                 163
+#define Key_XF86Favorites            164
+#define Key_XF86MyComputer           165
+#define Key_XF86Back                 166
+#define Key_XF86Forward              167
+#define Key_XF86Eject1               169
+#define Key_XF86Eject2               170
+#define Key_XF86AudioNext            171
+#define Key_XF86AudioPlay            172
+#define Key_XF86AudioPrev            173
+#define Key_XF86AudioStop            174
+#define Key_XF86AudioRecord          175
+#define Key_XF86AudioRewind          176
+#define Key_XF86Phone                177
+#define Key_XF86Tools                179
+#define Key_XF86HomePage             180
+#define Key_XF86Reload               181
+#define Key_XF86Close                182
+#define Key_XF86ScrollUp             185
+#define Key_XF86ScrollDown           186
+#define Key_parenleft                187
+#define Key_parenright               188
+#define Key_XF86New                  189
+#define Key_Redo2                    190
+#define Key_XF86Tools2               191
+#define Key_XF86Launch5              192
+#define Key_XF86Launch6              193
+#define Key_XF86Launch7              194
+#define Key_XF86Launch8              195
+#define Key_XF86Launch9              196
+#define Key_XF86AudioMicMute         198
+#define Key_XF86TouchpadToggle       199
+#define Key_XF86TouchpadOn           200
+#define Key_XF86TouchpadOff          201
+#define Key_Mode_switch              203
+#define Key_XF86AudioPlay2           208
+#define Key_XF86AudioPause           209
+#define Key_XF86Launch3              210
+#define Key_XF86Launch4              211
+#define Key_XF86LaunchB              212
+#define Key_XF86Suspend              213
+#define Key_XF86Close2               214
+#define Key_XF86AudioPlay3           215
+#define Key_XF86AudioForward         216
+#define Key_Print2                   218
+#define Key_XF86WebCam               220
+#define Key_XF86AudioPreset          221
+#define Key_XF86Mail2                223
+#define Key_XF86Messenger            224
+#define Key_XF86Search               225
+#define Key_XF86Go                   226
+#define Key_XF86Finance              227
+#define Key_XF86Game                 228
+#define Key_XF86Shop                 229
+#define Key_Cancel2                  231
+#define Key_XF86MonBrightnessDown    232
+#define Key_XF86MonBrightnessUp      233
+#define Key_XF86AudioMedia           234
+#define Key_XF86Display              235
+#define Key_XF86KbdLightOnOff        236
+#define Key_XF86KbdBrightnessDown    237
+#define Key_XF86KbdBrightnessUp      238
+#define Key_XF86Send2                239
+#define Key_XF86Reply                240
+#define Key_XF86MailForward          241
+#define Key_XF86Save                 242
+#define Key_XF86Documents            243
+#define Key_XF86Battery              244
+#define Key_XF86Bluetooth            245
+#define Key_XF86WLAN                 246
+#define Key_XF86MonBrightnessCycle   251
+#define Key_XF86WWAN                 254
+#define Key_XF86RFKill               255
-- 
2.43.2


A keys.h => keys.h +242 -0
@@ 0,0 1,242 @@
/* You can use the macros within this file
 * instead of search the keycodes yourself
 * with wev or something like that
 * Also probably you search this:
 *    Key_XF86AudioMute
 *    Key_XF86AudioLowerVolume
 *    Key_XF86AudioRaiseVolume
 *    Key_XF86MonBrightnessDown
 *    Key_XF86MonBrightnessUp
*/

#define Key_Escape                   9
#define Key_1                        10
#define Key_2                        11
#define Key_3                        12
#define Key_4                        13
#define Key_5                        14
#define Key_6                        15
#define Key_7                        16
#define Key_8                        17
#define Key_9                        18
#define Key_0                        19
#define Key_minus                    20
#define Key_equal                    21
#define Key_BackSpace                22
#define Key_Tab                      23
#define Key_q                        24
#define Key_w                        25
#define Key_e                        26
#define Key_r                        27
#define Key_t                        28
#define Key_y                        29
#define Key_u                        30
#define Key_i                        31
#define Key_o                        32
#define Key_p                        33
#define Key_bracketleft              34
#define Key_bracketright             35
#define Key_Return                   36
#define Key_Control_L                37
#define Key_a                        38
#define Key_s                        39
#define Key_d                        40
#define Key_f                        41
#define Key_g                        42
#define Key_h                        43
#define Key_j                        44
#define Key_k                        45
#define Key_l                        46
#define Key_semicolon                47
#define Key_apostrophe               48
#define Key_grave                    49
#define Key_Shift_L                  50
#define Key_backslash                51
#define Key_z                        52
#define Key_x                        53
#define Key_c                        54
#define Key_v                        55
#define Key_b                        56
#define Key_n                        57
#define Key_m                        58
#define Key_comma                    59
#define Key_period                   60
#define Key_slash                    61
#define Key_Shift_R                  62
#define Key_KP_Multiply              63
#define Key_Alt_L                    64
#define Key_space                    65
#define Key_Caps_Lock                66
#define Key_F1                       67
#define Key_F2                       68
#define Key_F3                       69
#define Key_F4                       70
#define Key_F5                       71
#define Key_F6                       72
#define Key_F7                       73
#define Key_F8                       74
#define Key_F9                       75
#define Key_F10                      76
#define Key_Num_Lock                 77
#define Key_Scroll_Lock              78
#define Key_KP_Home                  79
#define Key_KP_7                     Key_KP_Home
#define Key_KP_Up                    80
#define Key_KP_8                     Key_KP_Up
#define Key_KP_Prior                 81
#define Key_KP_9                     Key_KP_Prior
#define Key_KP_Subtract              82
#define Key_KP_Left                  83
#define Key_KP_4                     Key_KP_Left
#define Key_KP_Begin                 84
#define Key_KP_5                     Key_KP_Begin
#define Key_KP_Right                 85
#define Key_KP_6                     Key_KP_Right
#define Key_KP_Add                   86
#define Key_KP_End                   87
#define Key_KP_1                     Key_KP_End
#define Key_KP_Down                  88
#define Key_KP_2                     Key_KP_Down
#define Key_KP_Next                  89
#define Key_KP_3                     Key_KP_Next
#define Key_KP_Insert                90
#define Key_KP_0                     Key_KP_Insert
#define Key_KP_Delete                91
#define Key_KP_Period                Key_KP_Insert
#define Key_ISO_Level3_Shift         92
#define Key_less                     94
#define Key_F11                      95
#define Key_F12                      96
#define Key_Katakana                 98
#define Key_Hiragana                 99
#define Key_Henkan_Mode              100
#define Key_Hiragana_Katakana        101
#define Key_Muhenkan                 102
#define Key_KP_Enter                 104
#define Key_Control_R                105
#define Key_KP_Divide                106
#define Key_Print                    107
#define Key_Alt_R                    108
#define Key_Linefeed                 109
#define Key_Home                     110
#define Key_Up                       111
#define Key_Prior                    112
#define Key_Left                     113
#define Key_Right                    114
#define Key_End                      115
#define Key_Down                     116
#define Key_Next                     117
#define Key_Insert                   118
#define Key_Delete                   119
#define Key_XF86AudioMute            121
#define Key_XF86AudioLowerVolume     122
#define Key_XF86AudioRaiseVolume     123
#define Key_XF86PowerOff             124
#define Key_KP_Equal                 125
#define Key_plusminus                126
#define Key_Pause                    127
#define Key_XF86LaunchA              128
#define Key_KP_Decimal               129
#define Key_Hangul                   130
#define Key_Hangul_Hanja             131
#define Key_Super_L                  133
#define Key_Super_R                  134
#define Key_Menu                     135
#define Key_Cancel                   136
#define Key_Redo                     137
#define Key_SunProps                 138
#define Key_Undo                     139
#define Key_SunFront                 140
#define Key_XF86Copy                 141
#define Key_XF86Open                 142
#define Key_XF86Paste                143
#define Key_Find                     144
#define Key_XF86Cut                  145
#define Key_Help                     146
#define Key_XF86MenuKB               147
#define Key_XF86Calculator           148
#define Key_XF86Sleep                150
#define Key_XF86WakeUp               151
#define Key_XF86Explorer             152
#define Key_XF86Send                 153
#define Key_XF86Xfer                 155
#define Key_XF86Launch1              156
#define Key_XF86Launch2              157
#define Key_XF86WWW                  158
#define Key_XF86DOS                  159
#define Key_XF86ScreenSaver          160
#define Key_XF86RotateWindows        161
#define Key_XF86TaskPane             162
#define Key_XF86Mail                 163
#define Key_XF86Favorites            164
#define Key_XF86MyComputer           165
#define Key_XF86Back                 166
#define Key_XF86Forward              167
#define Key_XF86Eject1               169
#define Key_XF86Eject2               170
#define Key_XF86AudioNext            171
#define Key_XF86AudioPlay            172
#define Key_XF86AudioPrev            173
#define Key_XF86AudioStop            174
#define Key_XF86AudioRecord          175
#define Key_XF86AudioRewind          176
#define Key_XF86Phone                177
#define Key_XF86Tools                179
#define Key_XF86HomePage             180
#define Key_XF86Reload               181
#define Key_XF86Close                182
#define Key_XF86ScrollUp             185
#define Key_XF86ScrollDown           186
#define Key_parenleft                187
#define Key_parenright               188
#define Key_XF86New                  189
#define Key_Redo2                    190
#define Key_XF86Tools2               191
#define Key_XF86Launch5              192
#define Key_XF86Launch6              193
#define Key_XF86Launch7              194
#define Key_XF86Launch8              195
#define Key_XF86Launch9              196
#define Key_XF86AudioMicMute         198
#define Key_XF86TouchpadToggle       199
#define Key_XF86TouchpadOn           200
#define Key_XF86TouchpadOff          201
#define Key_Mode_switch              203
#define Key_XF86AudioPlay2           208
#define Key_XF86AudioPause           209
#define Key_XF86Launch3              210
#define Key_XF86Launch4              211
#define Key_XF86LaunchB              212
#define Key_XF86Suspend              213
#define Key_XF86Close2               214
#define Key_XF86AudioPlay3           215
#define Key_XF86AudioForward         216
#define Key_Print2                   218
#define Key_XF86WebCam               220
#define Key_XF86AudioPreset          221
#define Key_XF86Mail2                223
#define Key_XF86Messenger            224
#define Key_XF86Search               225
#define Key_XF86Go                   226
#define Key_XF86Finance              227
#define Key_XF86Game                 228
#define Key_XF86Shop                 229
#define Key_Cancel2                  231
#define Key_XF86MonBrightnessDown    232
#define Key_XF86MonBrightnessUp      233
#define Key_XF86AudioMedia           234
#define Key_XF86Display              235
#define Key_XF86KbdLightOnOff        236
#define Key_XF86KbdBrightnessDown    237
#define Key_XF86KbdBrightnessUp      238
#define Key_XF86Send2                239
#define Key_XF86Reply                240
#define Key_XF86MailForward          241
#define Key_XF86Save                 242
#define Key_XF86Documents            243
#define Key_XF86Battery              244
#define Key_XF86Bluetooth            245
#define Key_XF86WLAN                 246
#define Key_XF86MonBrightnessCycle   251
#define Key_XF86WWAN                 254
#define Key_XF86RFKill               255

A modes-diff.patch => modes-diff.patch +151 -0
@@ 0,0 1,151 @@
diff --git a/config.def.h b/config.def.h
index db0babc..1616136 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,13 @@ static const float urgentcolor[]           = COLOR(0xff0000ff);
 /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
 static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */
 
+enum {
+	BROWSER,
+};
+const char *modes_labels[] = {
+	"browser",
+};
+
 /* tagging - TAGCOUNT must be no greater than 31 */
 #define TAGCOUNT (9)
 
@@ -152,6 +159,8 @@ static const Key keys[] = {
 	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
 
+	{ MODKEY,                    XKB_KEY_b,          entermode,      {.i = BROWSER} },
+
 	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
 	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
 	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
@@ -162,6 +171,17 @@ static const Key keys[] = {
 	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
 };
 
+static const Modekey modekeys[] = {
+	/* mode      modifier                  key                 function        argument */
+	{ BROWSER, { 0, XKB_KEY_f, spawn, SHCMD("firefox") } },
+	{ BROWSER, { 0, XKB_KEY_f, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_b, spawn, SHCMD("brave") } },
+	{ BROWSER, { 0, XKB_KEY_b, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_g, spawn, SHCMD("google-chrome-stable") } },
+	{ BROWSER, { 0, XKB_KEY_g, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_Escape, entermode, {.i = NORMAL} } },
+};
+
 static const Button buttons[] = {
 	{ MODKEY, BTN_LEFT,   moveresize,     {.ui = CurMove} },
 	{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..1ada006 100644
--- a/dwl.c
+++ b/dwl.c
@@ -139,6 +139,11 @@ typedef struct {
 	const Arg arg;
 } Key;
 
+typedef struct {
+	int mode_index;
+	Key key;
+} Modekey;
+
 typedef struct {
 	struct wl_list link;
 	struct wlr_keyboard *wlr_keyboard;
@@ -270,6 +275,7 @@ static void handlesig(int signo);
 static void incnmaster(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
 static int keybinding(uint32_t mods, xkb_keysym_t sym);
+static int modekeybinding(uint32_t mods, xkb_keysym_t sym);
 static void keypress(struct wl_listener *listener, void *data);
 static void keypressmod(struct wl_listener *listener, void *data);
 static int keyrepeat(void *data);
@@ -327,6 +333,7 @@ static Monitor *xytomon(double x, double y);
 static void xytonode(double x, double y, struct wlr_surface **psurface,
 		Client **pc, LayerSurface **pl, double *nx, double *ny);
 static void zoom(const Arg *arg);
+static void entermode(const Arg *arg);
 
 /* variables */
 static const char broken[] = "broken";
@@ -377,6 +384,9 @@ static struct wlr_box sgeom;
 static struct wl_list mons;
 static Monitor *selmon;
 
+static const int NORMAL = -1;
+static int active_mode_index = NORMAL;
+
 #ifdef XWAYLAND
 static void activatex11(struct wl_listener *listener, void *data);
 static void associatex11(struct wl_listener *listener, void *data);
@@ -1372,6 +1382,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	 */
 	int handled = 0;
 	const Key *k;
+
+	if (active_mode_index >= 0) {
+		return modekeybinding(mods, sym);
+	}
+
 	for (k = keys; k < END(keys); k++) {
 		if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
 				sym == k->keysym && k->func) {
@@ -1382,6 +1397,29 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	return handled;
 }
 
+int
+modekeybinding(uint32_t mods, xkb_keysym_t sym)
+{
+	int handled = 0;
+	const Modekey *mk;
+	const Key *k;
+
+	for (mk = modekeys; mk < END(modekeys); mk++) {
+		if (active_mode_index != mk->mode_index) {
+			continue;
+		}
+
+		k = &mk->key;
+		if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
+				sym == k->keysym && k->func) {
+			k->func(&k->arg);
+			handled = 1;
+		}
+	}
+
+	return handled;
+}
+
 void
 keypress(struct wl_listener *listener, void *data)
 {
@@ -1851,6 +1889,7 @@ printstatus(void)
 		printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
 				sel, urg);
 		printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
+		printf("%s mode %s\n", m->wlr_output->name, modes_labels[active_mode_index] ? modes_labels[active_mode_index] : "");
 	}
 	fflush(stdout);
 }
@@ -2746,6 +2785,13 @@ zoom(const Arg *arg)
 	arrange(selmon);
 }
 
+void
+entermode(const Arg *arg)
+{
+	active_mode_index = arg->i;
+	printstatus();
+}
+
 #ifdef XWAYLAND
 void
 activatex11(struct wl_listener *listener, void *data)

A modes.patch => modes.patch +165 -0
@@ 0,0 1,165 @@
From a32b85018ff2cea0fc9f9137789860a4aadc3b3a Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 6 Mar 2024 07:31:17 -0500
Subject: [PATCH] implement modes

like sway/river modes
---
 config.def.h | 20 ++++++++++++++++++++
 dwl.c        | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/config.def.h b/config.def.h
index db0babc..1616136 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,13 @@ static const float urgentcolor[]           = COLOR(0xff0000ff);
 /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
 static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */
 
+enum {
+	BROWSER,
+};
+const char *modes_labels[] = {
+	"browser",
+};
+
 /* tagging - TAGCOUNT must be no greater than 31 */
 #define TAGCOUNT (9)
 
@@ -152,6 +159,8 @@ static const Key keys[] = {
 	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
 
+	{ MODKEY,                    XKB_KEY_b,          entermode,      {.i = BROWSER} },
+
 	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
 	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
 	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
@@ -162,6 +171,17 @@ static const Key keys[] = {
 	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
 };
 
+static const Modekey modekeys[] = {
+	/* mode      modifier                  key                 function        argument */
+	{ BROWSER, { 0, XKB_KEY_f, spawn, SHCMD("firefox") } },
+	{ BROWSER, { 0, XKB_KEY_f, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_b, spawn, SHCMD("brave") } },
+	{ BROWSER, { 0, XKB_KEY_b, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_g, spawn, SHCMD("google-chrome-stable") } },
+	{ BROWSER, { 0, XKB_KEY_g, entermode, {.i = NORMAL} } },
+	{ BROWSER, { 0, XKB_KEY_Escape, entermode, {.i = NORMAL} } },
+};
+
 static const Button buttons[] = {
 	{ MODKEY, BTN_LEFT,   moveresize,     {.ui = CurMove} },
 	{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..1ada006 100644
--- a/dwl.c
+++ b/dwl.c
@@ -139,6 +139,11 @@ typedef struct {
 	const Arg arg;
 } Key;
 
+typedef struct {
+	int mode_index;
+	Key key;
+} Modekey;
+
 typedef struct {
 	struct wl_list link;
 	struct wlr_keyboard *wlr_keyboard;
@@ -270,6 +275,7 @@ static void handlesig(int signo);
 static void incnmaster(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
 static int keybinding(uint32_t mods, xkb_keysym_t sym);
+static int modekeybinding(uint32_t mods, xkb_keysym_t sym);
 static void keypress(struct wl_listener *listener, void *data);
 static void keypressmod(struct wl_listener *listener, void *data);
 static int keyrepeat(void *data);
@@ -327,6 +333,7 @@ static Monitor *xytomon(double x, double y);
 static void xytonode(double x, double y, struct wlr_surface **psurface,
 		Client **pc, LayerSurface **pl, double *nx, double *ny);
 static void zoom(const Arg *arg);
+static void entermode(const Arg *arg);
 
 /* variables */
 static const char broken[] = "broken";
@@ -377,6 +384,9 @@ static struct wlr_box sgeom;
 static struct wl_list mons;
 static Monitor *selmon;
 
+static const int NORMAL = -1;
+static int active_mode_index = NORMAL;
+
 #ifdef XWAYLAND
 static void activatex11(struct wl_listener *listener, void *data);
 static void associatex11(struct wl_listener *listener, void *data);
@@ -1372,6 +1382,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	 */
 	int handled = 0;
 	const Key *k;
+
+	if (active_mode_index >= 0) {
+		return modekeybinding(mods, sym);
+	}
+
 	for (k = keys; k < END(keys); k++) {
 		if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
 				sym == k->keysym && k->func) {
@@ -1382,6 +1397,29 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
 	return handled;
 }
 
+int
+modekeybinding(uint32_t mods, xkb_keysym_t sym)
+{
+	int handled = 0;
+	const Modekey *mk;
+	const Key *k;
+
+	for (mk = modekeys; mk < END(modekeys); mk++) {
+		if (active_mode_index != mk->mode_index) {
+			continue;
+		}
+
+		k = &mk->key;
+		if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
+				sym == k->keysym && k->func) {
+			k->func(&k->arg);
+			handled = 1;
+		}
+	}
+
+	return handled;
+}
+
 void
 keypress(struct wl_listener *listener, void *data)
 {
@@ -1851,6 +1889,7 @@ printstatus(void)
 		printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
 				sel, urg);
 		printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
+		printf("%s mode %s\n", m->wlr_output->name, modes_labels[active_mode_index] ? modes_labels[active_mode_index] : "");
 	}
 	fflush(stdout);
 }
@@ -2746,6 +2785,13 @@ zoom(const Arg *arg)
 	arrange(selmon);
 }
 
+void
+entermode(const Arg *arg)
+{
+	active_mode_index = arg->i;
+	printstatus();
+}
+
 #ifdef XWAYLAND
 void
 activatex11(struct wl_listener *listener, void *data)
-- 
2.42.0


Do not follow this link