From e42ca1c539437d3098d80983cfe2ad6f938d7a08 Mon Sep 17 00:00:00 2001 From: Eldar Yusupov Date: Sun, 17 Mar 2024 19:12:29 +0300 Subject: [PATCH] Restore correct monitor and floating position when reattached --- dwl.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 44f3ad9..41548cd 100644 --- a/dwl.c +++ b/dwl.c @@ -106,6 +106,8 @@ typedef struct { unsigned int type; /* XDGShell or X11* */ Monitor *mon; + char *output; + struct wlr_box floatgeom; /* saved geom for floating restore after monitor reconnect */ struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_tree *scene_surface; @@ -807,6 +809,13 @@ closemon(Monitor *m) } wl_list_for_each(c, &clients, link) { + + /* Save floating geom now, before destroymon modifies it below. + * destroymon subtracts m->w.width from c->geom.x for floating + * windows, which corrupts the layout-absolute position we need + * to restore on reconnect. */ + if (c->isfloating && c->mon == m) c->floatgeom = c->geom; + if (c->isfloating && c->geom.x > m->m.width) resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, .width = c->geom.width, .height = c->geom.height}, 0); @@ -1045,6 +1054,7 @@ createmon(struct wl_listener *listener, void *data) size_t i; struct wlr_output_state state; Monitor *m; + Client *c; if (!wlr_output_init_render(wlr_output, alloc, drw)) return; @@ -1114,6 +1124,15 @@ createmon(struct wl_listener *listener, void *data) wlr_output_layout_add_auto(output_layout, wlr_output); else wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); + + wl_list_for_each(c, &clients, link) { + if (!c->output || strcmp(wlr_output->name, c->output) != 0) + continue; + c->mon = m; + if (c->isfloating) + resize(c, c->floatgeom, 0); + } + updatemons(NULL, NULL); } void @@ -1347,7 +1366,8 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->unmap.link); wl_list_remove(&c->maximize.link); } - free(c); + free(c->output); + free(c); } void @@ -1792,6 +1812,9 @@ mapnotify(struct wl_listener *listener, void *data) } else { applyrules(c); } + c->output = strdup(c->mon->wlr_output->name); + if (c->output == NULL) die("oom"); + printstatus(); unset_fullscreen: @@ -2705,8 +2728,12 @@ void tagmon(const Arg *arg) { Client *sel = focustop(selmon); - if (sel) - setmon(sel, dirtomon(arg->i), 0); + if (!sel) return; + + setmon(sel, dirtomon(arg->i), 0); + free(sel->output); + sel->output = strdup(sel->mon->wlr_output->name); + if (sel->output == NULL) die("oom"); } void -- 2.44.0