From 577d8da6d17dad5f847795582ebf813f3c5c04a7 Mon Sep 17 00:00:00 2001 From: choc Date: Thu, 4 Apr 2024 18:48:16 +0800 Subject: [PATCH 1/8] put wlr_layer_shell top layer below fullscreen fixes wlr_layer_shell top clients showing over fullscreen clients --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 39ce68c..bf763df 100644 --- a/dwl.c +++ b/dwl.c @@ -81,7 +81,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */ +enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */ #ifdef XWAYLAND enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ From 5c19e23146b6163e6508765f0062cde9a1718be7 Mon Sep 17 00:00:00 2001 From: sewn Date: Wed, 21 Feb 2024 20:41:29 +0300 Subject: [PATCH 2/8] switch to wmenu bemenu is very bloated, turning itself into a library, which makes it 7489 SLOC. wmenu on the other hand, looks suckless by default, and is only 2000 SLOC, which i also find alot nicer to use, since bemenu does nothing to replicate the original dmenu feel. --- config.def.h | 2 +- dwl.1 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config.def.h b/config.def.h index 8847e58..57acd39 100644 --- a/config.def.h +++ b/config.def.h @@ -115,7 +115,7 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA /* commands */ static const char *termcmd[] = { "foot", NULL }; -static const char *menucmd[] = { "bemenu-run", NULL }; +static const char *menucmd[] = { "wmenu_run", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ diff --git a/dwl.1 b/dwl.1 index ce1acf9..e64a71b 100644 --- a/dwl.1 +++ b/dwl.1 @@ -55,7 +55,7 @@ Move window to a single tag. Toggle tag for window. .It Mod-p Spawn -.Nm bemenu-run . +.Nm wmenu_run . .It Mod-Shift-Return Spawn .Nm foot . @@ -143,7 +143,7 @@ with s6 in the background: .Dl dwl -s 's6-svscan <&-' .Sh SEE ALSO .Xr foot 1 , -.Xr bemenu 1 , +.Xr wmenu 1 , .Xr dwm 1 , .Xr xkeyboard-config 7 .Sh CAVEATS From 34b7a5721134d63f8241af2f008c2e0d9f836dd5 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sun, 5 May 2024 13:52:25 -0500 Subject: [PATCH 3/8] Update wmenu-run name --- config.def.h | 2 +- dwl.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index 57acd39..8f498d2 100644 --- a/config.def.h +++ b/config.def.h @@ -115,7 +115,7 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA /* commands */ static const char *termcmd[] = { "foot", NULL }; -static const char *menucmd[] = { "wmenu_run", NULL }; +static const char *menucmd[] = { "wmenu-run", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ diff --git a/dwl.1 b/dwl.1 index e64a71b..387bcc9 100644 --- a/dwl.1 +++ b/dwl.1 @@ -55,7 +55,7 @@ Move window to a single tag. Toggle tag for window. .It Mod-p Spawn -.Nm wmenu_run . +.Nm wmenu-run . .It Mod-Shift-Return Spawn .Nm foot . From 9825c26cdd5dfed34022b77a8936c5d8f485e134 Mon Sep 17 00:00:00 2001 From: fauxmight Date: Fri, 10 May 2024 05:08:54 +0000 Subject: [PATCH 4/8] dwl-patches overhaul - doc changes --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b3d4f6..9d91923 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Wayland without restarting the entire display server, so any changes will take effect the next time dwl is executed. As in the dwm community, we encourage users to share patches they have created. -Check out the dwl [patches repository] and [patches wiki]! +Check out the dwl [patches repository]! ## Running dwl @@ -170,7 +170,6 @@ inspiration, and to the various contributors to the project, including: [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ [wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next [patches repository]: https://codeberg.org/dwl/dwl-patches -[patches wiki]: https://codeberg.org/dwl/dwl-patches/wiki [s6]: https://skarnet.org/software/s6/ [anopa]: https://jjacky.com/anopa/ [runit]: http://smarden.org/runit/faq.html#userservices From 0047ff740a4f8da430cecdb19084f626bf535b21 Mon Sep 17 00:00:00 2001 From: Forrest Bushstone Date: Fri, 5 Apr 2024 21:54:54 -0400 Subject: [PATCH 5/8] Replicate dwm behavior for sloppyfocus --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index bf763df..52bfbc8 100644 --- a/dwl.c +++ b/dwl.c @@ -1882,7 +1882,7 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, { struct timespec now; - if ((!active_constraint || active_constraint->surface != surface) && + if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && c && !client_is_unmanaged(c)) focusclient(c, 0); From bca077b9279f28c12cced63f0a556c0556f7169c Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sun, 2 Jun 2024 14:19:24 -0500 Subject: [PATCH 6/8] Allow negative coordinates in MonitorRules Monitor/output position (-1, -1) remains as a single indicator value for autoconfigure layout. Additionally, one minor comment typo is corrected. --- config.def.h | 2 ++ dwl.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index 8f498d2..a784eb4 100644 --- a/config.def.h +++ b/config.def.h @@ -36,6 +36,8 @@ static const Layout layouts[] = { }; /* monitors */ +/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator */ +/* WARNING: negative values other than (-1, -1) cause problems with xwayland clients' menus */ /* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */ static const MonitorRule monrules[] = { /* name mfact nmaster scale layout rotate/reflect x y */ diff --git a/dwl.c b/dwl.c index 52bfbc8..1ea7f2a 100644 --- a/dwl.c +++ b/dwl.c @@ -927,14 +927,14 @@ createmon(struct wl_listener *listener, void *data) m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg); wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); - /* Adds this to the output layout in the order it was configured in. + /* Adds this to the output layout in the order it was configured. * * The output layout utility automatically adds a wl_output global to the * display, which Wayland clients can see to find out information about the * output (such as DPI, scale factor, manufacturer, etc). */ m->scene_output = wlr_scene_output_create(scene, wlr_output); - if (m->m.x < 0 || m->m.y < 0) + if (m->m.x == -1 && m->m.y == -1) wlr_output_layout_add_auto(output_layout, wlr_output); else wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); From 8f6fca35d0710b347836dcaf3543e85e58783e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 30 Jan 2024 13:16:16 -0600 Subject: [PATCH 7/8] create a keyboard group for each virtual keyboard --- dwl.c | 128 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/dwl.c b/dwl.c index 1ea7f2a..356b913 100644 --- a/dwl.c +++ b/dwl.c @@ -159,6 +159,7 @@ typedef struct { struct wl_listener modifiers; struct wl_listener key; + struct wl_listener destroy; } KeyboardGroup; typedef struct { @@ -258,6 +259,7 @@ static void commitnotify(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data); static void createidleinhibitor(struct wl_listener *listener, void *data); static void createkeyboard(struct wlr_keyboard *keyboard); +static KeyboardGroup *createkeyboardgroup(void); static void createlayersurface(struct wl_listener *listener, void *data); static void createlocksurface(struct wl_listener *listener, void *data); static void createmon(struct wl_listener *listener, void *data); @@ -277,6 +279,7 @@ static void destroynotify(struct wl_listener *listener, void *data); static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); +static void destroykeyboardgroup(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void focusclient(Client *c, int lift); static void focusmon(const Arg *arg); @@ -393,8 +396,7 @@ static struct wlr_session_lock_v1 *cur_lock; static struct wl_listener lock_listener = {.notify = locksession}; static struct wlr_seat *seat; -static KeyboardGroup kb_group = {0}; -static KeyboardGroup vkb_group = {0}; +static KeyboardGroup *kb_group; static struct wlr_surface *held_grab; static unsigned int cursor_mode; static Client *grabc; @@ -667,9 +669,7 @@ cleanup(void) wlr_xcursor_manager_destroy(cursor_mgr); wlr_output_layout_destroy(output_layout); - /* Remove event source that use the dpy event loop before destroying dpy */ - wl_event_source_remove(kb_group.key_repeat_source); - wl_event_source_remove(vkb_group.key_repeat_source); + destroykeyboardgroup(&kb_group->destroy, NULL); wl_display_destroy(dpy); /* Destroy after the wayland display (when the monitors are already destroyed) @@ -790,11 +790,48 @@ void createkeyboard(struct wlr_keyboard *keyboard) { /* Set the keymap to match the group keymap */ - wlr_keyboard_set_keymap(keyboard, kb_group.wlr_group->keyboard.keymap); - wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay); + wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap); /* Add the new keyboard to the group */ - wlr_keyboard_group_add_keyboard(kb_group.wlr_group, keyboard); + wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard); +} + +KeyboardGroup * +createkeyboardgroup(void) +{ + KeyboardGroup *group = ecalloc(1, sizeof(*group)); + struct xkb_context *context; + struct xkb_keymap *keymap; + + group->wlr_group = wlr_keyboard_group_create(); + group->wlr_group->data = group; + + /* Prepare an XKB keymap and assign it to the keyboard group. */ + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, + XKB_KEYMAP_COMPILE_NO_FLAGS))) + die("failed to compile keymap"); + + wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + + wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, repeat_delay); + + /* Set up listeners for keyboard events */ + LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress); + LISTEN(&group->wlr_group->keyboard.events.modifiers, &group->modifiers, keypressmod); + + group->key_repeat_source = wl_event_loop_add_timer( + wl_display_get_event_loop(dpy), keyrepeat, group); + + /* 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 + * same wlr_keyboard_group, which provides a single wlr_keyboard interface for + * all of them. Set this combined wlr_keyboard as the seat keyboard. + */ + wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); + return group; } void @@ -1217,6 +1254,18 @@ destroysessionmgr(struct wl_listener *listener, void *data) wl_list_remove(&listener->link); } +void +destroykeyboardgroup(struct wl_listener *listener, void *data) +{ + KeyboardGroup *group = wl_container_of(listener, group, destroy); + wl_event_source_remove(group->key_repeat_source); + wlr_keyboard_group_destroy(group->wlr_group); + wl_list_remove(&group->key.link); + wl_list_remove(&group->modifiers.link); + wl_list_remove(&group->destroy.link); + free(group); +} + Monitor * dirtomon(enum wlr_direction dir) { @@ -1422,7 +1471,7 @@ inputdevice(struct wl_listener *listener, void *data) * there are no pointer devices, so we always include that capability. */ /* TODO do we actually require a cursor? */ caps = WL_SEAT_CAPABILITY_POINTER; - if (!wl_list_empty(&kb_group.wlr_group->devices)) + if (!wl_list_empty(&kb_group->wlr_group->devices)) caps |= WL_SEAT_CAPABILITY_KEYBOARD; wlr_seat_set_capabilities(seat, caps); } @@ -2269,9 +2318,6 @@ setsel(struct wl_listener *listener, void *data) void setup(void) { - struct xkb_context *context; - struct xkb_keymap *keymap; - int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; sigemptyset(&sa.sa_mask); @@ -2453,52 +2499,8 @@ setup(void) LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag); LISTEN_STATIC(&seat->events.start_drag, startdrag); - /* - * Configures a keyboard group, which will keep track of all connected - * keyboards, keep their modifier and LED states in sync, and handle - * keypresses - */ - kb_group.wlr_group = wlr_keyboard_group_create(); - kb_group.wlr_group->data = &kb_group; - - /* - * Virtual keyboards need to be in a different group - * https://codeberg.org/dwl/dwl/issues/554 - */ - vkb_group.wlr_group = wlr_keyboard_group_create(); - vkb_group.wlr_group->data = &vkb_group; - - /* Prepare an XKB keymap and assign it to the keyboard group. */ - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, - XKB_KEYMAP_COMPILE_NO_FLAGS))) - die("failed to compile keymap"); - - wlr_keyboard_set_keymap(&kb_group.wlr_group->keyboard, keymap); - wlr_keyboard_set_keymap(&vkb_group.wlr_group->keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); - - wlr_keyboard_set_repeat_info(&kb_group.wlr_group->keyboard, repeat_rate, repeat_delay); - wlr_keyboard_set_repeat_info(&vkb_group.wlr_group->keyboard, repeat_rate, repeat_delay); - - /* Set up listeners for keyboard events */ - LISTEN(&kb_group.wlr_group->keyboard.events.key, &kb_group.key, keypress); - LISTEN(&kb_group.wlr_group->keyboard.events.modifiers, &kb_group.modifiers, keypressmod); - LISTEN(&vkb_group.wlr_group->keyboard.events.key, &vkb_group.key, keypress); - LISTEN(&vkb_group.wlr_group->keyboard.events.modifiers, &vkb_group.modifiers, keypressmod); - - kb_group.key_repeat_source = wl_event_loop_add_timer( - wl_display_get_event_loop(dpy), keyrepeat, &kb_group); - vkb_group.key_repeat_source = wl_event_loop_add_timer( - wl_display_get_event_loop(dpy), keyrepeat, &vkb_group); - - /* 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 - * same wlr_keyboard_group, which provides a single wlr_keyboard interface for - * all of them. Set this combined wlr_keyboard as the seat keyboard. - */ - wlr_seat_set_keyboard(seat, &kb_group.wlr_group->keyboard); + kb_group = createkeyboardgroup(); + wl_list_init(&kb_group->destroy.link); output_mgr = wlr_output_manager_v1_create(dpy); LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply); @@ -2838,13 +2840,15 @@ view(const Arg *arg) void virtualkeyboard(struct wl_listener *listener, void *data) { - struct wlr_virtual_keyboard_v1 *keyboard = data; + struct wlr_virtual_keyboard_v1 *kb = data; + /* virtual keyboards shouldn't share keyboard group */ + KeyboardGroup *group = createkeyboardgroup(); /* Set the keymap to match the group keymap */ - wlr_keyboard_set_keymap(&keyboard->keyboard, vkb_group.wlr_group->keyboard.keymap); - wlr_keyboard_set_repeat_info(&keyboard->keyboard, repeat_rate, repeat_delay); + wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap); + LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, destroykeyboardgroup); /* Add the new keyboard to the group */ - wlr_keyboard_group_add_keyboard(vkb_group.wlr_group, &keyboard->keyboard); + wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard); } void From 21205f2f404ee2ae0680becbe914e6deb04df2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 30 May 2024 17:48:01 -0600 Subject: [PATCH 8/8] make sure clients share the same layer on floating layout --- dwl.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 356b913..6f041a0 100644 --- a/dwl.c +++ b/dwl.c @@ -495,6 +495,20 @@ arrange(Monitor *m) strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); + /* We move all clients (except fullscreen and unmanaged) to LyrTile while + * in floating layout to avoid "real" floating clients be always on top */ + wl_list_for_each(c, &clients, link) { + if (c->mon != m || c->isfullscreen) + continue; + + wlr_scene_node_reparent(&c->scene->node, + (!m->lt[m->sellt]->arrange && c->isfloating) + ? layers[LyrTile] + : (m->lt[m->sellt]->arrange && c->isfloating) + ? layers[LyrFloat] + : c->scene->node.parent); + } + if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); motionnotify(0, NULL, 0, 0, 0, 0); @@ -2198,7 +2212,8 @@ setfloating(Client *c, int floating) { Client *p = client_get_parent(c); c->isfloating = floating; - if (!c->mon) + /* If in floating layout do not change the client's layer */ + if (!c->mon || !c->mon->lt[c->mon->sellt]->arrange) return; wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || (p && p->isfullscreen) ? LyrFS