From 28f91b0326c0a049a02ad021708c88347d4cfa45 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 3 Nov 2026 01:20:08 +0100 Subject: [PATCH] foreign-toplevel-management: update --- patches/foreign-toplevel-management/README.md | 6 +- .../foreign-toplevel-management.patch | 132 +++++++++--------- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/patches/foreign-toplevel-management/README.md b/patches/foreign-toplevel-management/README.md index 6e30328..089671d 100644 --- a/patches/foreign-toplevel-management/README.md +++ b/patches/foreign-toplevel-management/README.md @@ -2,8 +2,10 @@ Implement `foreign-toplevel-management`, it add handlers for activate, close, fullscreen and destroy request events, it's missing minimize and maximize request handlers. ### Download -- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.6-a/foreign-toplevel-management) +- [git branch](https://codeberg.org/guidocella/dwl/src/branch/foreign-toplevel-management) +- [2026-10-20](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/foreign-toplevel-management/foreign-toplevel-management.patch) - [2024-05-02](https://codeberg.org/dwl/dwl-patches/raw/commit/e58c3ec41a39df934d2998161d7187ac965ea77a/foreign-toplevel-management/foreign-toplevel-management.patch) ### Authors -- [wochap](https://codeberg.org/wochap) \ No newline at end of file +- [wochap](https://codeberg.org/wochap) +- [Guido Cella](https://codeberg.org/guidocella) diff --git a/patches/foreign-toplevel-management/foreign-toplevel-management.patch b/patches/foreign-toplevel-management/foreign-toplevel-management.patch index 3dfa14f..2131d74 100644 --- a/patches/foreign-toplevel-management/foreign-toplevel-management.patch +++ b/patches/foreign-toplevel-management/foreign-toplevel-management.patch @@ -1,29 +1,29 @@ -From dc63d64cd69f515013464b3feb8acb411f5a348f Mon Sep 17 00:00:00 2001 +From 7820c6ca511de2fc41ab5bcf74dc0a5e0803d33f Mon Sep 17 00:00:00 2001 From: wochap -Date: Thu, 2 May 2024 17:25:45 -0500 +Date: Thu, 17 Sep 2026 08:22:59 +0200 Subject: [PATCH] implement foreign toplevel management --- Makefile | 5 +- - dwl.c | 93 +++++- + dwl.c | 95 +++++- ...oreign-toplevel-management-unstable-v1.xml | 270 ++++++++++++++++++ - 3 files changed, 366 insertions(+), 2 deletions(-) + 3 files changed, 367 insertions(+), 3 deletions(-) create mode 100644 protocols/wlr-foreign-toplevel-management-unstable-v1.xml diff --git a/Makefile b/Makefile -index a67fdd3..e0e1260 100644 +index 8304245..cfbc0e0 100644 --- a/Makefile +++ b/Makefile -@@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) - all: dwl - dwl: dwl.o util.o - $(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@ --dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h -+dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h wlr-foreign-toplevel-management-unstable-v1-protocol.h - util.o: util.c util.h +@@ -20,7 +20,7 @@ all: dwl + dwl: dwl.c client.h config.h ime.h util.h config.mk cursor-shape-v1-protocol.h \ + ext-image-copy-capture-v1-protocol.h \ + pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \ +- wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h ++ wlr-foreign-toplevel-management-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h + $(CC) dwl.c $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ # wayland-scanner is a tool which generates C headers and rigging for Wayland -@@ -37,6 +37,9 @@ wlr-layer-shell-unstable-v1-protocol.h: +@@ -47,6 +47,9 @@ wlr-output-power-management-unstable-v1-protocol.h: xdg-shell-protocol.h: $(WAYLAND_SCANNER) server-header \ $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ @@ -34,18 +34,18 @@ index a67fdd3..e0e1260 100644 config.h: cp config.def.h $@ diff --git a/dwl.c b/dwl.c -index bf763df..648616d 100644 +index 89e8caf..006c615 100644 --- a/dwl.c +++ b/dwl.c -@@ -22,6 +22,7 @@ - #include - #include - #include +@@ -30,6 +30,7 @@ + #include + #include + #include +#include #include #include #include -@@ -126,6 +127,11 @@ typedef struct { +@@ -151,6 +152,11 @@ typedef struct { struct wl_listener fullscreen; struct wl_listener set_decoration_mode; struct wl_listener destroy_decoration; @@ -54,10 +54,10 @@ index bf763df..648616d 100644 + struct wl_listener fclose; + struct wl_listener ffullscreen; + struct wl_listener fdestroy; - struct wlr_box prev; /* layout-relative, includes border */ - struct wlr_box bounds; #ifdef XWAYLAND -@@ -347,6 +353,11 @@ static Monitor *xytomon(double x, double y); + struct wl_listener activate; + struct wl_listener associate; +@@ -387,8 +393,14 @@ static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); static void zoom(const Arg *arg); @@ -68,19 +68,22 @@ index bf763df..648616d 100644 +static void ffullscreennotify(struct wl_listener *listener, void *data); /* variables */ - static const char broken[] = "broken"; -@@ -392,6 +403,8 @@ static struct wlr_scene_rect *locked_bg; ++static const char broken[] = "broken"; + static pid_t child_pid = -1; + static int locked; + static Client *focused_client; +@@ -433,6 +445,8 @@ static struct wlr_session_lock_manager_v1 *session_lock_mgr; + static struct wlr_scene_rect *locked_bg; static struct wlr_session_lock_v1 *cur_lock; - static struct wl_listener lock_listener = {.notify = locksession}; +static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_mgr; + static struct wlr_seat *seat; - static KeyboardGroup kb_group = {0}; - static KeyboardGroup vkb_group = {0}; -@@ -458,6 +471,11 @@ applyrules(Client *c) - if (!(title = client_get_title(c))) - title = broken; + static KeyboardGroup *kb_group; + static unsigned int cursor_mode; +@@ -588,6 +602,11 @@ applyrules(Client *c) + appid = client_get_appid(c); + title = client_get_title(c); + if (c->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, appid); @@ -90,34 +93,35 @@ index bf763df..648616d 100644 for (r = rules; r < END(rules); r++) { if ((!r->title || strstr(title, r->title)) && (!r->id || strstr(appid, r->id))) { -@@ -1288,6 +1306,8 @@ focusclient(Client *c, int lift) - client_set_border_color(old_c, bordercolor); - - client_activate_surface(old, 0); -+ if (old_c->foreign_toplevel) -+ wlr_foreign_toplevel_handle_v1_set_activated(old_c->foreign_toplevel, 0); - } +@@ -1631,6 +1650,8 @@ focusclient(Client *c, LayerSurface *l, int lift) + if (s && s->mapped) + client_activate_surface(s, 0); + focused_client = NULL; ++ if (old_c && old_c->foreign_toplevel) ++ wlr_foreign_toplevel_handle_v1_set_activated(old_c->foreign_toplevel, 0); } printstatus(); -@@ -1306,6 +1326,8 @@ focusclient(Client *c, int lift) - /* Activate the new client */ - client_activate_surface(client_surface(c), 1); +@@ -1653,6 +1674,9 @@ focusclient(Client *c, LayerSurface *l, int lift) + + if (!client_is_unmanaged(c)) + focused_client = c; ++ + if (c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, 1); } void -@@ -1599,6 +1621,8 @@ mapnotify(struct wl_listener *listener, void *data) +@@ -1975,6 +1999,8 @@ mapnotify(struct wl_listener *listener, void *data) c->border[i]->node.data = c; } + createforeigntoplevel(c); + /* Initialize client geometry with room for border */ - client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); - c->geom.width += 2 * c->bw; -@@ -2232,12 +2256,17 @@ setmon(Client *c, Monitor *m, uint32_t newtags) + client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | + WLR_EDGE_RIGHT); +@@ -2661,12 +2687,17 @@ setmon(Client *c, Monitor *m, uint32_t newtags) c->prev = c->geom; /* Scene graph sends surface leave/enter events on move and resize */ @@ -136,29 +140,28 @@ index bf763df..648616d 100644 setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ setfloating(c, c->isfloating); } -@@ -2351,6 +2380,9 @@ setup(void) - gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); - LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); +@@ -2806,7 +2837,10 @@ setup(void) + power_mgr = wlr_output_power_manager_v1_create(dpy); + wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); +- /* Creates an output layout, which is a wlroots utility for working with an + /* Initializes foreign toplevel management */ + foreign_toplevel_mgr = wlr_foreign_toplevel_manager_v1_create(dpy); + - /* Creates an output layout, which a wlroots utility for working with an ++ /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ - output_layout = wlr_output_layout_create(); -@@ -2691,6 +2723,11 @@ unmapnotify(struct wl_listener *listener, void *data) - wl_list_remove(&c->flink); + output_layout = wlr_output_layout_create(dpy); + wl_signal_add(&output_layout->events.change, &layout_change); +@@ -3261,6 +3295,8 @@ unmapnotify(struct wl_listener *listener, void *data) + wlr_ext_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel_handle); + c->foreign_toplevel_handle = NULL; } - -+ if (c->foreign_toplevel) { ++ if (c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); -+ c->foreign_toplevel = NULL; -+ } -+ - wlr_scene_node_destroy(&c->scene->node); - printstatus(); - motionnotify(0, NULL, 0, 0, 0, 0); -@@ -2802,6 +2839,12 @@ void + #ifdef XWAYLAND + if (c->type != XDGShell && c->capture.image_capture_scene_surface) { + wlr_scene_node_destroy(&c->capture.image_capture_scene_surface->buffer->node); +@@ -3393,6 +3429,12 @@ void updatetitle(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, set_title); @@ -170,8 +173,8 @@ index bf763df..648616d 100644 + } if (c == focustop(c->mon)) printstatus(); - } -@@ -2929,6 +2972,54 @@ zoom(const Arg *arg) + +@@ -3531,6 +3573,55 @@ zoom(const Arg *arg) arrange(selmon); } @@ -195,7 +198,7 @@ index bf763df..648616d 100644 + } else { + setmon(c, selmon, 0); + } -+ focusclient(c, 1); ++ focusclient(c, NULL, 1); + arrange(c->mon); +} + @@ -221,6 +224,7 @@ index bf763df..648616d 100644 + wl_list_remove(&c->fclose.link); + wl_list_remove(&c->ffullscreen.link); + wl_list_remove(&c->fdestroy.link); ++ c->foreign_toplevel = NULL; +} + #ifdef XWAYLAND @@ -503,5 +507,5 @@ index 0000000..44505bb + + -- -2.43.2 +2.56.0