mirror of
https://codeberg.org/dwl/dwl.git
synced 2025-01-14 21:07:28 -08:00
apply kblayout patch
This commit is contained in:
parent
bd0503927b
commit
035bc3b1a1
2 changed files with 72 additions and 1 deletions
|
@ -47,6 +47,12 @@ static const char kblayout_file[] = "/tmp/dwl-keymap";
|
|||
static const char *kblayout_cmd[] = {"pkill", "-RTMIN+1", "someblocks", NULL};
|
||||
static const int kblayout_perclient = 0;
|
||||
|
||||
/* keyboard layout change notification for status bar */
|
||||
/* example using someblocks:
|
||||
static const char kblayout_file[] = "/tmp/dwl-keymap";
|
||||
static const char *kblayout_cmd[] = {"pkill", "-RTMIN+1", "someblocks", NULL};
|
||||
*/
|
||||
|
||||
static const Rule rules[] = {
|
||||
/* app_id title tags mask isfloating opacity monitor */
|
||||
// { "firefox", NULL, 1 << 8, 0, -1, -1 },
|
||||
|
|
67
dwl.c
67
dwl.c
|
@ -133,6 +133,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;
|
||||
} Client;
|
||||
|
||||
typedef struct {
|
||||
|
@ -159,6 +160,8 @@ typedef struct {
|
|||
struct wl_listener modifiers;
|
||||
struct wl_listener key;
|
||||
struct wl_listener destroy;
|
||||
|
||||
xkb_layout_index_t layout_idx;
|
||||
} Keyboard;
|
||||
|
||||
typedef struct {
|
||||
|
@ -290,6 +293,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(Keyboard *kb, int update);
|
||||
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);
|
||||
|
@ -409,6 +413,8 @@ static struct wlr_box sgeom;
|
|||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
xkb_layout_index_t status_layout_idx = -1;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
static void associatex11(struct wl_listener *listener, void *data);
|
||||
|
@ -859,6 +865,8 @@ createkeyboard(struct wlr_keyboard *keyboard)
|
|||
|
||||
/* And add the keyboard to our list of keyboards */
|
||||
wl_list_insert(&keyboards, &kb->link);
|
||||
|
||||
kblayoutnotify(kb, 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1041,6 +1049,9 @@ createnotify(struct wl_listener *listener, void *data)
|
|||
c = xdg_surface->data = ecalloc(1, sizeof(*c));
|
||||
c->surface.xdg = xdg_surface;
|
||||
c->bw = borderpx;
|
||||
if (kblayout_perclient)
|
||||
c->layout_idx = xkb_state_serialize_layout(
|
||||
wlr_seat_get_keyboard(seat)->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
|
||||
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
|
||||
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
|
@ -1432,6 +1443,9 @@ focusclient(Client *c, int lift)
|
|||
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 wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
|
||||
|
||||
if (locked)
|
||||
return;
|
||||
|
@ -1494,10 +1508,21 @@ focusclient(Client *c, int lift)
|
|||
motionnotify(0);
|
||||
|
||||
/* Have a client, so focus its top-level wlr_surface */
|
||||
client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
|
||||
client_notify_enter(client_surface(c), kb);
|
||||
|
||||
/* Activate the new client */
|
||||
client_activate_surface(client_surface(c), 1);
|
||||
|
||||
/* Update keyboard layout */
|
||||
if (kblayout_perclient) {
|
||||
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->layout_idx;
|
||||
xkb_state_update_mask(kb->xkb_state, mdepr, mlatc, mlock, ldepr, llatc, llock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1630,6 +1655,41 @@ inputdevice(struct wl_listener *listener, void *data)
|
|||
wlr_seat_set_capabilities(seat, caps);
|
||||
}
|
||||
|
||||
void
|
||||
kblayoutnotify(Keyboard *kb, int update)
|
||||
{
|
||||
FILE *f;
|
||||
Client *c;
|
||||
xkb_layout_index_t old = kb->layout_idx;
|
||||
|
||||
if (update) {
|
||||
kb->layout_idx = xkb_state_serialize_layout(kb->wlr_keyboard->xkb_state,
|
||||
XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
|
||||
// Update client layout
|
||||
if (kblayout_perclient && kb->layout_idx != old && (c = focustop(selmon)))
|
||||
c->layout_idx = kb->layout_idx;
|
||||
}
|
||||
|
||||
// If layout did not change, do nothing
|
||||
if (status_layout_idx == kb->layout_idx)
|
||||
return;
|
||||
status_layout_idx = kb->layout_idx;
|
||||
|
||||
// Save current layout to kblayout_file
|
||||
if (*kblayout_file && (f = fopen(kblayout_file, "w"))) {
|
||||
fputs(xkb_keymap_layout_get_name(kb->wlr_keyboard->keymap,
|
||||
kb->layout_idx), f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Run kblayout_cmd
|
||||
if (kblayout_cmd[0] && fork() == 0) {
|
||||
execvp(kblayout_cmd[0], (char *const *)kblayout_cmd);
|
||||
die("dwl: execvp %s failed:", kblayout_cmd[0]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
keybinding(uint32_t mods, xkb_keycode_t keycode)
|
||||
{
|
||||
|
@ -1665,6 +1725,8 @@ keypress(struct wl_listener *listener, void *data)
|
|||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
kblayoutnotify(kb, 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)
|
||||
|
@ -1695,6 +1757,9 @@ keypressmod(struct wl_listener *listener, void *data)
|
|||
/* This event is raised when a modifier key, such as shift or alt, is
|
||||
* pressed. We simply communicate this to the client. */
|
||||
Keyboard *kb = wl_container_of(listener, kb, modifiers);
|
||||
|
||||
kblayoutnotify(kb, 1);
|
||||
|
||||
/*
|
||||
* A seat can only have one keyboard, but this is a limitation of the
|
||||
* Wayland protocol - not wlroots. We assign all connected keyboards to the
|
||||
|
|
Loading…
Reference in a new issue