From e4130ff865eebae51b0dd0ce6d3d447371f577a0 Mon Sep 17 00:00:00 2001 From: Nikita Ivanov Date: Sun, 30 Nov 2025 23:27:17 +0100 Subject: [PATCH 1/3] en-keycodes: make it work with grp:caps_toggle --- patches/en-keycodes/README.md | 2 +- patches/en-keycodes/en-keycodes.patch | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/patches/en-keycodes/README.md b/patches/en-keycodes/README.md index ee3aae4..c089dc2 100644 --- a/patches/en-keycodes/README.md +++ b/patches/en-keycodes/README.md @@ -6,6 +6,6 @@ Always use the English keymap to get keycodes, so key bindings work even when us - [v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/en-keycodes/en-keycodes.patch) ### Authors -- [ForzCross](https://codeberg.org/ForzCross) - [Nikita Ivanov](https://codeberg.org/nikitaivanov) ([GitHub](https://github.com/NikitaIvanovV)) +- [ForzCross](https://codeberg.org/ForzCross) - [dimkr](https://codeberg.org/dimkr) () diff --git a/patches/en-keycodes/en-keycodes.patch b/patches/en-keycodes/en-keycodes.patch index 445d900..a9cb4d4 100644 --- a/patches/en-keycodes/en-keycodes.patch +++ b/patches/en-keycodes/en-keycodes.patch @@ -1,21 +1,21 @@ -From cd61fac9cb6e9d0172e2f7a01e6a514d676ba5f0 Mon Sep 17 00:00:00 2001 +From 556e47f7ce7f729ecc1b285ece0c82744741c81c Mon Sep 17 00:00:00 2001 From: Nikita Ivanov -Date: Tue, 4 Feb 2025 23:53:11 +0100 +Date: Sun, 30 Nov 2025 23:16:53 +0100 Subject: [PATCH] Always use the English keymap to get keycodes --- - dwl.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) + dwl.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c -index def2562..c299365 100644 +index def2562..31e98ca 100644 --- a/dwl.c +++ b/dwl.c @@ -413,6 +413,11 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; -+static const struct xkb_rule_names en_rules = {.layout = "us"}; ++static struct xkb_rule_names en_rules; +static struct xkb_context *en_context; +static struct xkb_keymap *en_keymap; +static struct xkb_state *en_state; @@ -57,11 +57,13 @@ index def2562..c299365 100644 wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); -@@ -2607,6 +2618,10 @@ setup(void) +@@ -2607,6 +2618,12 @@ setup(void) * pointer, touch, and drawing tablet device. We also rig up a listener to * let us know when new input devices are available on the backend. */ + en_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); ++ en_rules = xkb_rules; ++ en_rules.layout = "us"; + en_keymap = xkb_keymap_new_from_names(en_context, &en_rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + en_state = xkb_state_new(en_keymap); @@ -69,5 +71,5 @@ index def2562..c299365 100644 virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard); -- -2.48.1 +2.51.2 From e85e01efd32e4d746680966f3bcb17c84c6cce38 Mon Sep 17 00:00:00 2001 From: Alex Denes Date: Mon, 17 Nov 2025 07:25:28 +0000 Subject: [PATCH 2/3] drm_lease: introduce new rebased patch --- patches/drm_lease/README.md | 12 ++++ patches/drm_lease/drm_lease.patch | 110 ++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 patches/drm_lease/README.md create mode 100644 patches/drm_lease/drm_lease.patch diff --git a/patches/drm_lease/README.md b/patches/drm_lease/README.md new file mode 100644 index 0000000..55f83b4 --- /dev/null +++ b/patches/drm_lease/README.md @@ -0,0 +1,12 @@ +### Description +Adds support for drm-lease-v1 for embedded displays such as VR headsets + +### Download +- [git branch](/caskd/dwl/src/branch/patches/drm_lease) +- [main 2025-06-18](/dwl/dwl-patches/raw/branch/main/patches/drm_lease/drm_lease.patch) +### Authors +- [caskd](https://codeberg.org/caskd) + caskd@redxen.eu + caskd at [Libera IRC dwl channel](https://web.libera.chat/?channels=#dwl) +- Micah Gorrell + micah.gorrell@venafi.com diff --git a/patches/drm_lease/drm_lease.patch b/patches/drm_lease/drm_lease.patch new file mode 100644 index 0000000..b4d91a4 --- /dev/null +++ b/patches/drm_lease/drm_lease.patch @@ -0,0 +1,110 @@ +From be620ef43f6a37bc70331d6db69a3d0f60d2bb0d Mon Sep 17 00:00:00 2001 +From: Micah Gorrell +Date: Fri, 26 May 2023 08:17:20 -0600 +Subject: [PATCH] Implemented support for the DRM lease protocol, as needed to + use devices such as VR headsets + +--- + dwl.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/dwl.c b/dwl.c +index 12f441e..6864f18 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -315,6 +316,7 @@ static void powermgrsetmode(struct wl_listener *listener, void *data); + static void quit(const Arg *arg); + static void rendermon(struct wl_listener *listener, void *data); + static void requestdecorationmode(struct wl_listener *listener, void *data); ++static void requestdrmlease(struct wl_listener *listener, void *data); + static void requeststartdrag(struct wl_listener *listener, void *data); + static void requestmonstate(struct wl_listener *listener, void *data); + static void resize(Client *c, struct wlr_box geo, int interact); +@@ -376,6 +378,7 @@ static struct wl_list clients; /* tiling order */ + static struct wl_list fstack; /* focus order */ + static struct wlr_idle_notifier_v1 *idle_notifier; + static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; ++static struct wlr_drm_lease_v1_manager *drm_lease_manager; + static struct wlr_layer_shell_v1 *layer_shell; + static struct wlr_output_manager_v1 *output_mgr; + static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; +@@ -435,6 +438,7 @@ static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape}; + static struct wl_listener request_start_drag = {.notify = requeststartdrag}; + static struct wl_listener start_drag = {.notify = startdrag}; + static struct wl_listener new_session_lock = {.notify = locksession}; ++static struct wl_listener drm_lease_request = {.notify = requestdrmlease}; + + #ifdef XWAYLAND + static void activatex11(struct wl_listener *listener, void *data); +@@ -782,6 +786,9 @@ cleanuplisteners(void) + wl_list_remove(&request_start_drag.link); + wl_list_remove(&start_drag.link); + wl_list_remove(&new_session_lock.link); ++ if (drm_lease_manager) { ++ wl_list_remove(&drm_lease_request.link); ++ } + #ifdef XWAYLAND + wl_list_remove(&new_xwayland_surface.link); + wl_list_remove(&xwayland_ready.link); +@@ -1049,6 +1056,14 @@ createmon(struct wl_listener *listener, void *data) + if (!wlr_output_init_render(wlr_output, alloc, drw)) + return; + ++ if (wlr_output->non_desktop) { ++ if (drm_lease_manager) { ++ wlr_drm_lease_v1_manager_offer_output(drm_lease_manager, wlr_output); ++ } ++ ++ return; ++ } ++ + m = wlr_output->data = ecalloc(1, sizeof(*m)); + m->wlr_output = wlr_output; + +@@ -2181,6 +2196,16 @@ requestdecorationmode(struct wl_listener *listener, void *data) + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + } + ++static void requestdrmlease(struct wl_listener *listener, void *data) { ++ struct wlr_drm_lease_request_v1 *req = data; ++ struct wlr_drm_lease_v1 *lease = wlr_drm_lease_request_v1_grant(req); ++ ++ if (!lease) { ++ fprintf(stderr, "Failed to grant lease request"); ++ wlr_drm_lease_request_v1_reject(req); ++ } ++} ++ + void + requeststartdrag(struct wl_listener *listener, void *data) + { +@@ -2645,10 +2670,18 @@ setup(void) + wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); + wl_signal_add(&output_mgr->events.test, &output_mgr_test); + ++ drm_lease_manager = wlr_drm_lease_v1_manager_create(dpy, backend); ++ if (drm_lease_manager) { ++ wl_signal_add(&drm_lease_manager->events.request, &drm_lease_request); ++ } else { ++ fprintf(stderr, "Failed to create wlr_drm_lease_device_v1; VR will not be available\n"); ++ } ++ + /* Make sure XWayland clients don't connect to the parent X server, + * e.g when running in the x11 backend or the wayland backend and the + * compositor has Xwayland support */ + unsetenv("DISPLAY"); ++ + #ifdef XWAYLAND + /* + * Initialise the XWayland X server. +-- +2.51.1 + From 955529b809d16c0dab5d57dcba01a80dad0e8e91 Mon Sep 17 00:00:00 2001 From: Rumen Date: Mon, 1 Dec 2025 20:36:01 +0100 Subject: [PATCH 3/3] fix(bar-appicons): fixed compiler warnings --- patches/bar-appicons/bar-appicons.patch | 103 +++++++++++++----------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/patches/bar-appicons/bar-appicons.patch b/patches/bar-appicons/bar-appicons.patch index 95a0c85..eaacf3d 100644 --- a/patches/bar-appicons/bar-appicons.patch +++ b/patches/bar-appicons/bar-appicons.patch @@ -1,12 +1,12 @@ -From f0c747be0deca64801fe01eebfa78ce5b3d803fe Mon Sep 17 00:00:00 2001 +From f5d1206f7f467cafd5a0217a46c31928316ba2fe Mon Sep 17 00:00:00 2001 From: Rumen -Date: Fri, 24 Oct 2025 17:14:02 +0200 -Subject: [PATCH] fix: appicons displaying on all monitors +Date: Mon, 1 Dec 2025 20:29:49 +0100 +Subject: [PATCH] fix(bar-appicons): fixed various compiler warnings --- config.def.h | 14 +++-- - dwl.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 149 insertions(+), 7 deletions(-) + dwl.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index 1b7472d..a48b78d 100644 @@ -15,7 +15,7 @@ index 1b7472d..a48b78d 100644 @@ -26,12 +26,20 @@ static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* logging */ static int log_level = WLR_ERROR; - + +/* appicons */ +/* NOTE: set to 0 to set to default (whitespace) */ +static char outer_separator_beg = '['; @@ -34,10 +34,10 @@ index 1b7472d..a48b78d 100644 + { "Gimp_EXAMPLE", NULL, 0, 1, -1, NULL }, /* Start on currently visible tags floating, not tiled */ + { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1, "" }, /* Start on ONLY tag "9" */ }; - + /* layout(s) */ diff --git a/dwl.c b/dwl.c -index bf340d8..ba6388a 100644 +index bf340d8..e2baf66 100644 --- a/dwl.c +++ b/dwl.c @@ -143,6 +143,7 @@ typedef struct { @@ -62,7 +62,7 @@ index bf340d8..ba6388a 100644 int monitor; + const char *appicon; } Rule; - + typedef struct { @@ -313,6 +316,9 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); @@ -70,28 +70,27 @@ index bf340d8..ba6388a 100644 static Monitor *dirtomon(enum wlr_direction dir); +static void remove_outer_separators(char **str); +static void appiconsappend(char **str, const char *appicon, size_t new_size); -+static void applyappicon(char *tag_icons[], int *icons_per_tag, const Client *c); ++static void applyappicon(char *tag_icons[], unsigned int *icons_per_tag, const Client *c); static void drawbar(Monitor *m); static void drawbars(void); static void focusclient(Client *c, int lift); -@@ -520,6 +526,11 @@ applybounds(Client *c, struct wlr_box *bbox) - void - applyrules(Client *c) - { +@@ -527,12 +533,19 @@ applyrules(Client *c) + const Rule *r; + Monitor *mon = selmon, *m; + + outer_separator_beg = outer_separator_beg ? outer_separator_beg : ' '; + outer_separator_end = outer_separator_end ? outer_separator_end : ' '; + inner_separator = inner_separator ? inner_separator : ' '; + truncate_icons_after = truncate_icons_after > 0 ? truncate_icons_after : 1; + - /* rule matching */ - const char *appid, *title; - uint32_t newtags = 0; -@@ -533,6 +544,8 @@ applyrules(Client *c) + appid = client_get_appid(c); + title = client_get_title(c); + for (r = rules; r < END(rules); r++) { if ((!r->title || strstr(title, r->title)) && (!r->id || strstr(appid, r->id))) { + /* r->appicon is static, so lifetime is sufficient */ -+ c->appicon = (char*) r->appicon; ++ c->appicon = (char*) r->appicon; c->isfloating = r->isfloating; newtags |= r->tags; i = 0; @@ -107,10 +106,10 @@ index bf340d8..ba6388a 100644 @@ -905,6 +918,16 @@ cleanupmon(struct wl_listener *listener, void *data) wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); - -+ for (int i = 0; i < LENGTH(tags); i++) { -+ if (m->tag_icons[i]) free(m->tag_icons[i]); -+ m->tag_icons[i] = NULL; + ++ for (long unsigned int tag_idx = 0; tag_idx < LENGTH(tags); tag_idx++) { ++ if (m->tag_icons[tag_idx]) free(m->tag_icons[tag_idx]); ++ m->tag_icons[tag_idx] = NULL; + } + + if (m->tag_icons) { @@ -128,32 +127,32 @@ index bf340d8..ba6388a 100644 + + m->tag_icons = (char**) malloc(LENGTH(tags) * sizeof(char*)); + if (m->tag_icons == NULL) perror("dwm: malloc()"); -+ for (int i = 0; i < LENGTH(tags); i++) { -+ m->tag_icons[i] = NULL; ++ for (long unsigned int tag_idx = 0; tag_idx < LENGTH(tags); tag_idx++) { ++ m->tag_icons[tag_idx] = NULL; + } + wlr_output_state_set_scale(&state, r->scale); wlr_output_state_set_transform(&state, r->rr); break; -@@ -1566,6 +1596,97 @@ dirtomon(enum wlr_direction dir) +@@ -1566,6 +1596,98 @@ dirtomon(enum wlr_direction dir) return selmon; } - + +void +remove_outer_separators(char **str) +{ -+ size_t clean_tag_name_len = strlen(*str) - 2; ++ const char *clean_tag_name_beg = *str + 1; ++ const size_t clean_tag_name_len = strlen(*str) - 2; + -+ char *temp_tag_name = (char*) ++ char *temp_tag_name = (char*) + malloc(clean_tag_name_len + 1); + + if (temp_tag_name == NULL) perror("dwm: malloc()"); + + memset(temp_tag_name, 0, clean_tag_name_len + 1); + -+ char *clean_tag_name_beg = *str + 1; -+ strncpy(temp_tag_name, -+ clean_tag_name_beg, ++ strncpy(temp_tag_name, ++ clean_tag_name_beg, + clean_tag_name_len); + + if (*str) free(*str); @@ -185,11 +184,15 @@ index bf340d8..ba6388a 100644 +} + +void -+applyappicon(char *tag_icons[], int *icons_per_tag, const Client *c) ++applyappicon(char *tag_icons[], unsigned int *icons_per_tag, const Client *c) +{ ++ const size_t outer_separators_size = 2; ++ const size_t inner_separator_size = 1; ++ size_t new_size = 0; ++ + for (unsigned t = 1, i = 0; + i < LENGTH(tags); -+ t <<= 1, i++) ++ t <<= 1, i++) + { + if (c->tags & t) { + if (icons_per_tag[i] == 0) { @@ -205,18 +208,15 @@ index bf340d8..ba6388a 100644 + icons_per_tag[i]++; + continue; + } -+ ++ + /* remove outer separators from previous iterations + * otherwise they get applied recursively */ + if (icons_per_tag[i] > 1) { + remove_outer_separators(&tag_icons[i]); + } + -+ size_t outer_separators_size = 2; -+ size_t inner_separator_size = 1; -+ -+ size_t new_size = strlen(tag_icons[i]) -+ + outer_separators_size ++ new_size = strlen(tag_icons[i]) ++ + outer_separators_size + + inner_separator_size + + strlen(icon) + + 1; @@ -233,16 +233,23 @@ index bf340d8..ba6388a 100644 void drawbar(Monitor *m) { -@@ -1588,9 +1709,22 @@ drawbar(Monitor *m) +@@ -1575,6 +1697,7 @@ drawbar(Monitor *m) + uint32_t i, occ = 0, urg = 0; + Client *c; + Buffer *buf; ++ unsigned int icons_per_tag[LENGTH(tags)]; + + if (!m->scene_buffer->node.enabled) + return; +@@ -1588,9 +1711,21 @@ drawbar(Monitor *m) drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0); } - -+ int icons_per_tag[LENGTH(tags)]; + + memset(icons_per_tag, 0, LENGTH(tags) * sizeof(int)); + -+ for (int i = 0; i < LENGTH(tags); i++) { ++ for (long unsigned int tag_idx = 0; tag_idx < LENGTH(tags); tag_idx++) { + /* set each tag to default value */ -+ m->tag_icons[i] = strndup(tags[i], strlen(tags[i])); ++ m->tag_icons[tag_idx] = strndup(tags[tag_idx], strlen(tags[tag_idx])); + } + wl_list_for_each(c, &clients, link) { @@ -256,7 +263,7 @@ index bf340d8..ba6388a 100644 occ |= c->tags; if (c->isurgent) urg |= c->tags; -@@ -1598,10 +1732,10 @@ drawbar(Monitor *m) +@@ -1598,10 +1733,10 @@ drawbar(Monitor *m) x = 0; c = focustop(m); for (i = 0; i < LENGTH(tags); i++) { @@ -270,6 +277,6 @@ index bf340d8..ba6388a 100644 drwl_rect(m->drw, x + boxs, boxs, boxw, boxw, m == selmon && c && c->tags & 1 << i, urg & 1 << i); --- -2.51.1 +-- +2.52.0