From d04df999acc1b0c0a0bdf5fe8a737e9e0fae0a2f Mon Sep 17 00:00:00 2001 From: Stivvo Date: Fri, 18 Sep 2020 12:56:23 +0200 Subject: [PATCH 1/2] Switch between keyboard layouts ar runtime setkblayout() avoids to rewrite the code necessary to set the keyboard layout in createkeyboard() and togglekblayout() --- config.def.h | 6 ++++++ dwl.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/config.def.h b/config.def.h index 53021cf7..b0fb9321 100644 --- a/config.def.h +++ b/config.def.h @@ -44,6 +44,11 @@ static const struct xkb_rule_names xkb_rules = { static const int repeat_rate = 25; static const int repeat_delay = 600; +/* gb will be set the first time togglekblayout is called, then us.. it is + * recommended to set the same layout in position 0 of kblayouts and in + * xkb_rules */ +static const char *kblayouts[] = {"us", "gb"}; + #define MODKEY WLR_MODIFIER_ALT #define TAGKEYS(KEY,SKEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ @@ -81,6 +86,7 @@ static const Key keys[] = { { MODKEY, XKB_KEY_period, focusmon, {.i = +1} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = -1} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = +1} }, + { MODKEY, XKB_KEY_w, togglekblayout, {0} }, TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), diff --git a/dwl.c b/dwl.c index 730e46a1..5256eec0 100644 --- a/dwl.c +++ b/dwl.c @@ -221,6 +221,7 @@ static void run(char *startup_cmd); static void scalebox(struct wlr_box *box, float scale); static Client *selclient(void); static void setcursor(struct wl_listener *listener, void *data); +static void setkblayout(Keyboard *kb, const struct xkb_rule_names *newrule); static void setpsel(struct wl_listener *listener, void *data); static void setsel(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); @@ -234,6 +235,7 @@ static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); static void togglefloating(const Arg *arg); +static void togglekblayout(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unmapnotify(struct wl_listener *listener, void *data); @@ -261,6 +263,7 @@ static struct wlr_xcursor_manager *cursor_mgr; static struct wlr_seat *seat; static struct wl_list keyboards; +static unsigned int kblayout = 0; /* index of kblayouts */ static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ @@ -480,24 +483,28 @@ commitnotify(struct wl_listener *listener, void *data) c->resize = 0; } +void +setkblayout(Keyboard *kb, const struct xkb_rule_names *newrule) +{ + /* Prepare an XKB keymap and assign it to the keyboard. */ + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, newrule, + XKB_KEYMAP_COMPILE_NO_FLAGS); + wlr_keyboard_set_keymap(kb->device->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); +} + void createkeyboard(struct wlr_input_device *device) { - struct xkb_context *context; - struct xkb_keymap *keymap; Keyboard *kb; kb = device->data = calloc(1, sizeof(*kb)); kb->device = device; - /* Prepare an XKB keymap and assign it to the keyboard. */ - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - keymap = xkb_map_new_from_names(context, &xkb_rules, - XKB_KEYMAP_COMPILE_NO_FLAGS); + setkblayout(kb, &xkb_rules); - wlr_keyboard_set_keymap(device->keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); wlr_keyboard_set_repeat_info(device->keyboard, repeat_rate, repeat_delay); /* Here we set up listeners for keyboard events. */ @@ -1675,6 +1682,19 @@ togglefloating(const Arg *arg) setfloating(sel, !sel->isfloating /* || sel->isfixed */); } +void +togglekblayout(const Arg *arg) +{ + Keyboard *kb; + struct xkb_rule_names newrule = xkb_rules; + + kblayout = (kblayout + 1) % LENGTH(kblayouts); + newrule.layout = kblayouts[kblayout]; + wl_list_for_each(kb, &keyboards, link) { + setkblayout(kb, &newrule); + } +} + void toggletag(const Arg *arg) { From 382ec6b9cddbde9e66a08bc11d4836327b8f084a Mon Sep 17 00:00:00 2001 From: Stivvo Date: Mon, 8 Mar 2021 17:19:18 +0100 Subject: [PATCH 2/2] Don't interfere with the dwl codebase Removing setkblayout duplicates a few lines of code to avoid touch the codebase --- dwl.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/dwl.c b/dwl.c index 83dc16d0..4749936f 100644 --- a/dwl.c +++ b/dwl.c @@ -270,7 +270,6 @@ static void run(char *startup_cmd); static void scalebox(struct wlr_box *box, float scale); static Client *selclient(void); static void setcursor(struct wl_listener *listener, void *data); -static void setkblayout(Keyboard *kb, const struct xkb_rule_names *newrule); static void setpsel(struct wl_listener *listener, void *data); static void setsel(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); @@ -784,25 +783,22 @@ commitnotify(struct wl_listener *listener, void *data) c->resize = 0; } -void -setkblayout(Keyboard *kb, const struct xkb_rule_names *newrule) -{ - /* Prepare an XKB keymap and assign it to the keyboard. */ - struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - struct xkb_keymap *keymap = xkb_map_new_from_names(context, newrule, - XKB_KEYMAP_COMPILE_NO_FLAGS); - wlr_keyboard_set_keymap(kb->device->keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); -} - void createkeyboard(struct wlr_input_device *device) { + struct xkb_context *context; + struct xkb_keymap *keymap; Keyboard *kb = device->data = calloc(1, sizeof(*kb)); kb->device = device; - setkblayout(kb, &xkb_rules); + /* Prepare an XKB keymap and assign it to the keyboard. */ + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + keymap = xkb_map_new_from_names(context, &xkb_rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); wlr_keyboard_set_repeat_info(device->keyboard, repeat_rate, repeat_delay); /* Here we set up listeners for keyboard events. */ @@ -2234,8 +2230,14 @@ togglekblayout(const Arg *arg) kblayout = (kblayout + 1) % LENGTH(kblayouts); newrule.layout = kblayouts[kblayout]; - wl_list_for_each(kb, &keyboards, link) - setkblayout(kb, &newrule); + wl_list_for_each(kb, &keyboards, link) { + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &newrule, + XKB_KEYMAP_COMPILE_NO_FLAGS); + wlr_keyboard_set_keymap(kb->device->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + } } void