mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-09-08 12:14:50 +00:00
kblayout: per tag layout does not work
This commit is contained in:
parent
168d6bf045
commit
c29d2464da
@ -12,7 +12,7 @@ with the example settings in `config.h`:
|
||||
```c
|
||||
static const Block blocks[] = {
|
||||
/*Icon*/ /*Command*/ /*Update Interval*/ /*Update Signal*/
|
||||
{"", "cat /tmp/dwl-keymap", 0, 1},
|
||||
{"", "cat /tmp/dwl-kblayout", 0, 1},
|
||||
};
|
||||
```
|
||||
|
||||
@ -21,8 +21,7 @@ implementation happens to share some code. If you don't need
|
||||
any of these features, just disable it in `config.h`.
|
||||
|
||||
### Download
|
||||
- [git branch](https://codeberg.org/ForzCross/dwl/src/branch/kblayout.patch)
|
||||
- [2024-01-21](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/kblayout/kblayout.patch)
|
||||
- [2024-05-17](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/kblayout/kblayout.patch)
|
||||
|
||||
### Authors
|
||||
- [ForzCross](https://codeberg.org/ForzCross)
|
||||
|
@ -1,73 +1,62 @@
|
||||
From a0c758953fe0cbb20ea74d0acfa3e44b8173d12d Mon Sep 17 00:00:00 2001
|
||||
From: ForzCross <forzcross@gmail.com>
|
||||
Date: Sun, 21 Jan 2024 15:52:31 +0300
|
||||
Subject: [PATCH] Add per client keyboard layout and status bar info
|
||||
commit dc72dae11b1ae4d76b70881e8c5bd62055234e60
|
||||
Author: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
|
||||
Date: Sun Apr 7 22:03:49 2024 +0200
|
||||
|
||||
---
|
||||
config.def.h | 3 +++
|
||||
dwl.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 67 insertions(+), 1 deletion(-)
|
||||
Add per client keyboard layout and status bar info
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 9009517..81bb10d 100644
|
||||
index 8f498d2..484e522 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -13,6 +13,9 @@ static const float focuscolor[] = COLOR(0x005577ff);
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||
/* 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 */
|
||||
+/* keyboard layout change notification for status bar */
|
||||
+static const char kblayout_file[] = "/tmp/dwl-keymap";
|
||||
+static const char *kblayout_cmd[] = {"pkill", "-RTMIN+3", "someblocks", NULL};
|
||||
+static const char kblayout_file[] = "/tmp/dwl-kblayout";
|
||||
+static const char *kblayout_cmd[] = {"pkill", "-RTMIN+1", "someblocks", NULL};
|
||||
|
||||
/* tagging - TAGCOUNT must be no greater than 31 */
|
||||
#define TAGCOUNT (9)
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index bf02a6d..17c8fa4 100644
|
||||
index bf763df..c8da00e 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -135,6 +135,7 @@ typedef struct {
|
||||
@@ -139,6 +139,7 @@ typedef struct {
|
||||
uint32_t tags;
|
||||
int isfloating, isurgent, isfullscreen;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
+ xkb_layout_index_t layout_idx;
|
||||
+ unsigned int kblayout_idx;
|
||||
} Client;
|
||||
|
||||
typedef struct {
|
||||
@@ -155,6 +156,7 @@ typedef struct {
|
||||
|
||||
struct wl_listener modifiers;
|
||||
struct wl_listener key;
|
||||
+ xkb_layout_index_t layout_idx;
|
||||
} KeyboardGroup;
|
||||
|
||||
typedef struct {
|
||||
@@ -273,6 +275,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
@@ -286,6 +287,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 void kblayoutnotify(KeyboardGroup *kb, int update);
|
||||
+static void kblayout(KeyboardGroup *kb);
|
||||
static int keybinding(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);
|
||||
@@ -385,6 +388,8 @@ static struct wlr_box sgeom;
|
||||
@@ -405,6 +407,8 @@ static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
+xkb_layout_index_t status_layout_idx = -1;
|
||||
+static unsigned int kblayout_idx = -1;
|
||||
+
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
static void associatex11(struct wl_listener *listener, void *data);
|
||||
@@ -772,6 +777,7 @@ createkeyboard(struct wlr_keyboard *keyboard)
|
||||
@@ -795,6 +799,8 @@ createkeyboard(struct wlr_keyboard *keyboard)
|
||||
|
||||
/* Add the new keyboard to the group */
|
||||
wlr_keyboard_group_add_keyboard(kb_group.wlr_group, keyboard);
|
||||
+ kblayoutnotify(&kb_group, 1);
|
||||
+
|
||||
+ kblayout(&kb_group);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -927,6 +933,7 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
@@ -951,6 +957,7 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
struct wlr_xdg_surface *xdg_surface = data;
|
||||
Client *c = NULL;
|
||||
LayerSurface *l = NULL;
|
||||
@ -75,46 +64,64 @@ index bf02a6d..17c8fa4 100644
|
||||
|
||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
struct wlr_xdg_popup *popup = xdg_surface->popup;
|
||||
@@ -949,6 +956,9 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
@@ -973,6 +980,7 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
c = xdg_surface->data = ecalloc(1, sizeof(*c));
|
||||
c->surface.xdg = xdg_surface;
|
||||
c->bw = borderpx;
|
||||
+ c->layout_idx = kb
|
||||
+ ? xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE)
|
||||
+ : 0;
|
||||
+ c->kblayout_idx = kb ? kb->modifiers.group : 0;
|
||||
|
||||
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
|
||||
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
@@ -1165,6 +1175,9 @@ focusclient(Client *c, int lift)
|
||||
@@ -1236,10 +1244,26 @@ dirtomon(enum wlr_direction dir)
|
||||
void
|
||||
focusclient(Client *c, int lift)
|
||||
{
|
||||
+ /* Copied from wlroots/types/wlr_keyboard_group.c */
|
||||
+ struct keyboard_group_device {
|
||||
+ struct wlr_keyboard *keyboard;
|
||||
+ struct wl_listener key;
|
||||
+ struct wl_listener modifiers;
|
||||
+ struct wl_listener keymap;
|
||||
+ struct wl_listener repeat_info;
|
||||
+ struct wl_listener destroy;
|
||||
+ struct wl_list link; // wlr_keyboard_group.devices
|
||||
+ };
|
||||
+
|
||||
struct wlr_surface *old = seat->keyboard_state.focused_surface;
|
||||
int unused_lx, unused_ly, old_client_type;
|
||||
Client *old_c = NULL;
|
||||
LayerSurface *old_l = NULL;
|
||||
+ xkb_mod_mask_t mdepr, mlatc, mlock;
|
||||
+ xkb_layout_index_t ldepr, llatc, llock;
|
||||
+ struct keyboard_group_device *device;
|
||||
+ struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
|
||||
+ struct wlr_keyboard_group *group = kb ? wlr_keyboard_group_from_wlr_keyboard(kb) : NULL;
|
||||
|
||||
if (locked)
|
||||
return;
|
||||
@@ -1217,6 +1230,17 @@ focusclient(Client *c, int lift)
|
||||
@@ -1292,6 +1316,20 @@ focusclient(Client *c, int lift)
|
||||
}
|
||||
printstatus();
|
||||
|
||||
+ /* Update keyboard layout */
|
||||
+ if (kb) {
|
||||
+ mdepr = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
+ mlatc = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_LATCHED);
|
||||
+ mlock = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
+ ldepr = xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_DEPRESSED);
|
||||
+ llatc = xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_LATCHED);
|
||||
+ llock = c ? c->layout_idx : 0;
|
||||
+ xkb_state_update_mask(kb->xkb_state, mdepr, mlatc, mlock, ldepr, llatc, llock);
|
||||
+ if (group) {
|
||||
+ // Update the first real device, because kb or group->kb is not a real
|
||||
+ // keyboard and its effective layout gets overwritten
|
||||
+ device = wl_container_of(group->devices.next, device, link);
|
||||
+ mdepr = xkb_state_serialize_mods(device->keyboard->xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
+ mlatc = xkb_state_serialize_mods(device->keyboard->xkb_state, XKB_STATE_MODS_LATCHED);
|
||||
+ mlock = xkb_state_serialize_mods(device->keyboard->xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
+ ldepr = xkb_state_serialize_layout(device->keyboard->xkb_state, XKB_STATE_LAYOUT_DEPRESSED);
|
||||
+ llatc = xkb_state_serialize_layout(device->keyboard->xkb_state, XKB_STATE_LAYOUT_LATCHED);
|
||||
+ llock = c ? c->kblayout_idx : 0;
|
||||
+ xkb_state_update_mask(device->keyboard->xkb_state, mdepr, mlatc, mlock, ldepr, llatc, llock);
|
||||
+ }
|
||||
+
|
||||
if (!c) {
|
||||
/* With no client, all we have left is to clear focus */
|
||||
wlr_seat_keyboard_notify_clear_focus(seat);
|
||||
@@ -1227,7 +1251,7 @@ focusclient(Client *c, int lift)
|
||||
motionnotify(0);
|
||||
@@ -1302,7 +1340,7 @@ focusclient(Client *c, int lift)
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
|
||||
/* Have a client, so focus its top-level wlr_surface */
|
||||
- client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
|
||||
@ -122,35 +129,30 @@ index bf02a6d..17c8fa4 100644
|
||||
|
||||
/* Activate the new client */
|
||||
client_activate_surface(client_surface(c), 1);
|
||||
@@ -1352,6 +1376,41 @@ inputdevice(struct wl_listener *listener, void *data)
|
||||
@@ -1427,6 +1465,36 @@ inputdevice(struct wl_listener *listener, void *data)
|
||||
wlr_seat_set_capabilities(seat, caps);
|
||||
}
|
||||
|
||||
+void
|
||||
+kblayoutnotify(KeyboardGroup *kb, int update)
|
||||
+kblayout(KeyboardGroup *kb)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ Client *c;
|
||||
+ xkb_layout_index_t old = kb->layout_idx;
|
||||
+
|
||||
+ if (update) {
|
||||
+ kb->layout_idx = xkb_state_serialize_layout(kb->wlr_group->keyboard.xkb_state,
|
||||
+ XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
+
|
||||
+ // Update client layout
|
||||
+ if (kb->layout_idx != old && (c = focustop(selmon)))
|
||||
+ c->layout_idx = kb->layout_idx;
|
||||
+ }
|
||||
+ unsigned int idx = kb->wlr_group->keyboard.modifiers.group;
|
||||
+
|
||||
+ // If layout did not change, do nothing
|
||||
+ if (status_layout_idx == kb->layout_idx)
|
||||
+ if (kblayout_idx == idx)
|
||||
+ return;
|
||||
+ status_layout_idx = kb->layout_idx;
|
||||
+ kblayout_idx = idx;
|
||||
+
|
||||
+ // Update client layout
|
||||
+ if ((c = focustop(selmon)))
|
||||
+ c->kblayout_idx = kblayout_idx;
|
||||
+
|
||||
+ // Save current layout to kblayout_file
|
||||
+ if (*kblayout_file && (f = fopen(kblayout_file, "w"))) {
|
||||
+ fputs(xkb_keymap_layout_get_name(kb->wlr_group->keyboard.keymap,
|
||||
+ kb->layout_idx), f);
|
||||
+ idx), f);
|
||||
+ fclose(f);
|
||||
+ }
|
||||
+
|
||||
@ -164,24 +166,12 @@ index bf02a6d..17c8fa4 100644
|
||||
int
|
||||
keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
{
|
||||
@@ -1391,6 +1450,8 @@ keypress(struct wl_listener *listener, void *data)
|
||||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
+ kblayoutnotify(group, 0);
|
||||
+
|
||||
/* On _press_ if there is no active screen locker,
|
||||
* attempt to process a compositor keybinding. */
|
||||
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
@@ -1429,6 +1490,8 @@ keypressmod(struct wl_listener *listener, void *data)
|
||||
@@ -1504,6 +1572,8 @@ keypressmod(struct wl_listener *listener, void *data)
|
||||
/* Send modifiers to the client. */
|
||||
wlr_seat_keyboard_notify_modifiers(seat,
|
||||
&group->wlr_group->keyboard.modifiers);
|
||||
+
|
||||
+ kblayoutnotify(group, 1);
|
||||
+ kblayout(group);
|
||||
}
|
||||
|
||||
int
|
||||
--
|
||||
2.43.0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user