diff --git a/config.def.h b/config.def.h index f08540c..b17405d 100644 --- a/config.def.h +++ b/config.def.h @@ -79,6 +79,18 @@ static const struct xkb_rule_names xkb_rules = { .options = NULL, }; +/* input devices */ +static const InputRule inputrules[] = { + /* name kbcreate ptrcreate */ + /* ignore bad device - like a touchpad ;) */ + { "BAD DEVICE", NULL, NULL }, + /* ungroup ydotool device - fixes a bug */ + { "ydotoold virtual device", createungroupedkeyboard, createpointer }, + /* put your touchpad name here to enable toggle touchpad */ + { "SYNA8020:00 06CB:CE5C Touchpad", createkeyboard, createtogglepointer }, + { NULL, createkeyboard, createpointer }, +}; + static const int repeat_rate = 25; static const int repeat_delay = 600; @@ -171,6 +183,7 @@ static const Key keys[] = { { MODKEY, XKB_KEY_r, spawn, {.v = menucmd} }, { MODKEY, XKB_KEY_f, spawn, {.v = filecmd} }, { MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} }, + { MODKEY, XKB_KEY_space, togglepointer, {0} }, TAGKEYS(XKB_KEY_1, XKB_KEY_exclam, 0), TAGKEYS(XKB_KEY_2, XKB_KEY_quotedbl, 1), diff --git a/dwl.c b/dwl.c index f716026..61b7b19 100644 --- a/dwl.c +++ b/dwl.c @@ -149,6 +149,12 @@ typedef struct { Monitor *mon; } DwlIpcOutput; +typedef struct { + const char *name; + void (*kbcreate)(struct wlr_keyboard *); + void (*ptrcreate)(struct wlr_pointer *); +} InputRule; + typedef struct { uint32_t mod; xkb_keysym_t keysym; @@ -278,6 +284,8 @@ static void createnotify(struct wl_listener *listener, void *data); static void createpointer(struct wlr_pointer *pointer); static void createpointerconstraint(struct wl_listener *listener, void *data); static void createpopup(struct wl_listener *listener, void *data); +static void createtogglepointer(struct wlr_pointer *pointer); +static void createungroupedkeyboard(struct wlr_keyboard *keyboard); static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint); static void cursorframe(struct wl_listener *listener, void *data); static void cursorwarptohint(void); @@ -359,6 +367,7 @@ static void tile(Monitor *m); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); +static void togglepointer(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unlocksession(struct wl_listener *listener, void *data); @@ -461,6 +470,7 @@ static struct wl_listener new_session_lock = {.notify = locksession}; 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 struct libinput_device *togglepointerdevice = NULL; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -1253,6 +1263,33 @@ createpopup(struct wl_listener *listener, void *data) LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); } +void +createtogglepointer(struct wlr_pointer *pointer) +{ + struct libinput_device *device; + + createpointer(pointer); + + if (wlr_input_device_is_libinput(&pointer->base) + && (device = wlr_libinput_get_device_handle(&pointer->base))) { + togglepointerdevice = device; + } +} + +void +createungroupedkeyboard(struct wlr_keyboard *keyboard) +{ + /* for keyboards that need their own keyboard group */ + KeyboardGroup *group = createkeyboardgroup(); + + /* Set the keymap to match the group keymap */ + wlr_keyboard_set_keymap(keyboard, group->wlr_group->keyboard.keymap); + LISTEN(&keyboard->base.events.destroy, &group->destroy, destroykeyboardgroup); + + /* Add the new keyboard to the group */ + wlr_keyboard_group_add_keyboard(group->wlr_group, keyboard); +} + void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) { @@ -1861,13 +1898,27 @@ inputdevice(struct wl_listener *listener, void *data) * available. */ struct wlr_input_device *device = data; uint32_t caps; + const InputRule *r; switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - createkeyboard(wlr_keyboard_from_input_device(device)); + for (r = inputrules; r < END(inputrules); r++) { + if (!r->name || strstr(device->name, r->name)) { + if (r->kbcreate) + r->kbcreate(wlr_keyboard_from_input_device(device)); + break; + } + } + break; case WLR_INPUT_DEVICE_POINTER: - createpointer(wlr_pointer_from_input_device(device)); + for (r = inputrules; r < END(inputrules); r++) { + if (!r->name || strstr(device->name, r->name)) { + if (r->ptrcreate) + r->ptrcreate(wlr_pointer_from_input_device(device)); + break; + } + } break; default: /* TODO handle other input device types */ @@ -3029,6 +3080,18 @@ togglefullscreen(const Arg *arg) setfullscreen(sel, !sel->isfullscreen); } +void +togglepointer(const Arg *arg) +{ + if (!togglepointerdevice) + return; + + libinput_device_config_send_events_set_mode( + togglepointerdevice, + libinput_device_config_send_events_get_mode(togglepointerdevice) ^ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED + ); +} + void toggletag(const Arg *arg) { diff --git a/inputdevicerules-v0.7.patch b/inputdevicerules-v0.7.patch new file mode 100644 index 0000000..18f6f9e --- /dev/null +++ b/inputdevicerules-v0.7.patch @@ -0,0 +1,173 @@ +From 89f870a04f903681b0a7a0ac4eb1ae70c4984b46 Mon Sep 17 00:00:00 2001 +From: Ben Collerson +Date: Sat, 15 Jun 2024 12:34:01 +1000 +Subject: [PATCH] input device rules + +* customise input device handling +* ignore unwanted input devices +* configure a toggle for an input device +--- + config.def.h | 13 ++++++++++ + dwl.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 79 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 22d2171d..0b287ab5 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -60,6 +60,18 @@ static const struct xkb_rule_names xkb_rules = { + .options = NULL, + }; + ++/* input devices */ ++static const InputRule inputrules[] = { ++ /* name kbcreate ptrcreate */ ++ /* ignore bad device - like a touchpad ;) */ ++ { "BAD DEVICE", NULL, NULL }, ++ /* ungroup ydotool device - fixes a bug */ ++ { "ydotoold virtual device", createungroupedkeyboard, createpointer }, ++ /* put your touchpad name here to enable toggle touchpad */ ++ { "Elan Touchpad", createkeyboard, createtogglepointer }, ++ { NULL, createkeyboard, createpointer }, ++}; ++ + static const int repeat_rate = 25; + static const int repeat_delay = 600; + +@@ -142,6 +154,7 @@ static const Key keys[] = { + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, ++ { MODKEY, XKB_KEY_u, togglepointer, {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} }, +diff --git a/dwl.c b/dwl.c +index a2711f67..f6f91938 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -143,6 +143,12 @@ typedef struct { + uint32_t resize; /* configure serial of a pending resize */ + } Client; + ++typedef struct { ++ const char *name; ++ void (*kbcreate)(struct wlr_keyboard *); ++ void (*ptrcreate)(struct wlr_pointer *); ++} InputRule; ++ + typedef struct { + uint32_t mod; + xkb_keysym_t keysym; +@@ -270,6 +276,8 @@ static void createnotify(struct wl_listener *listener, void *data); + static void createpointer(struct wlr_pointer *pointer); + static void createpointerconstraint(struct wl_listener *listener, void *data); + static void createpopup(struct wl_listener *listener, void *data); ++static void createtogglepointer(struct wlr_pointer *pointer); ++static void createungroupedkeyboard(struct wlr_keyboard *keyboard); + static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint); + static void cursorframe(struct wl_listener *listener, void *data); + static void cursorwarptohint(void); +@@ -340,6 +348,7 @@ static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglefloating(const Arg *arg); + static void togglefullscreen(const Arg *arg); ++static void togglepointer(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unlocksession(struct wl_listener *listener, void *data); +@@ -413,6 +422,8 @@ static struct wlr_box sgeom; + static struct wl_list mons; + static Monitor *selmon; + ++static struct libinput_device *togglepointerdevice = NULL; ++ + #ifdef XWAYLAND + static void activatex11(struct wl_listener *listener, void *data); + static void associatex11(struct wl_listener *listener, void *data); +@@ -1133,6 +1144,33 @@ createpopup(struct wl_listener *listener, void *data) + LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); + } + ++void ++createtogglepointer(struct wlr_pointer *pointer) ++{ ++ struct libinput_device *device; ++ ++ createpointer(pointer); ++ ++ if (wlr_input_device_is_libinput(&pointer->base) ++ && (device = wlr_libinput_get_device_handle(&pointer->base))) { ++ togglepointerdevice = device; ++ } ++} ++ ++void ++createungroupedkeyboard(struct wlr_keyboard *keyboard) ++{ ++ /* for keyboards that need their own keyboard group */ ++ KeyboardGroup *group = createkeyboardgroup(); ++ ++ /* Set the keymap to match the group keymap */ ++ wlr_keyboard_set_keymap(keyboard, group->wlr_group->keyboard.keymap); ++ LISTEN(&keyboard->base.events.destroy, &group->destroy, destroykeyboardgroup); ++ ++ /* Add the new keyboard to the group */ ++ wlr_keyboard_group_add_keyboard(group->wlr_group, keyboard); ++} ++ + void + cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) + { +@@ -1531,13 +1569,27 @@ inputdevice(struct wl_listener *listener, void *data) + * available. */ + struct wlr_input_device *device = data; + uint32_t caps; ++ const InputRule *r; + + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: +- createkeyboard(wlr_keyboard_from_input_device(device)); ++ for (r = inputrules; r < END(inputrules); r++) { ++ if (!r->name || strstr(device->name, r->name)) { ++ if (r->kbcreate) ++ r->kbcreate(wlr_keyboard_from_input_device(device)); ++ break; ++ } ++ } ++ + break; + case WLR_INPUT_DEVICE_POINTER: +- createpointer(wlr_pointer_from_input_device(device)); ++ for (r = inputrules; r < END(inputrules); r++) { ++ if (!r->name || strstr(device->name, r->name)) { ++ if (r->ptrcreate) ++ r->ptrcreate(wlr_pointer_from_input_device(device)); ++ break; ++ } ++ } + break; + default: + /* TODO handle other input device types */ +@@ -2739,6 +2791,18 @@ togglefullscreen(const Arg *arg) + setfullscreen(sel, !sel->isfullscreen); + } + ++void ++togglepointer(const Arg *arg) ++{ ++ if (!togglepointerdevice) ++ return; ++ ++ libinput_device_config_send_events_set_mode( ++ togglepointerdevice, ++ libinput_device_config_send_events_get_mode(togglepointerdevice) ^ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED ++ ); ++} ++ + void + toggletag(const Arg *arg) + { +-- +2.45.2 +