From 7bd3a440969c82d768e0eb81d8f391f76365b653 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 19 Jul 2024 20:38:41 +0200 Subject: [PATCH] applybounds-relative When client is moved between monitors, it's put on the same relative position instead of on border closest to current monitor. --- dwl.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 5bf995e..6bd338c 100644 --- a/dwl.c +++ b/dwl.c @@ -130,6 +130,7 @@ typedef struct { struct wl_listener destroy_decoration; struct wlr_box prev; /* layout-relative, includes border */ struct wlr_box bounds; + struct wlr_box prev_bounds; #ifdef XWAYLAND struct wl_listener activate; struct wl_listener associate; @@ -294,6 +295,7 @@ static void gpureset(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 int is_inbounds(struct wlr_box *box, struct wlr_box *bounds); static int keybinding(uint32_t mods, xkb_keysym_t sym); static void keypress(struct wl_listener *listener, void *data); static void keypressmod(struct wl_listener *listener, void *data); @@ -432,6 +434,13 @@ static xcb_atom_t netatom[NetLast]; /* attempt to encapsulate suck into one file */ #include "client.h" +int +is_inbounds(struct wlr_box *box, struct wlr_box *bounds) +{ + return box->x >= bounds->x && box->y >= bounds->y && + box->x + box->width <= bounds->x + bounds->width && box->y + box->height <= bounds->y + bounds->height; +} + /* function implementations */ void applybounds(Client *c, struct wlr_box *bbox) @@ -440,6 +449,12 @@ applybounds(Client *c, struct wlr_box *bbox) c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); + if (c->isfloating && c->prev_bounds.width && c->prev_bounds.height && + is_inbounds(&c->geom, &c->prev_bounds) && !is_inbounds(&c->geom, bbox)) { + c->geom.x = bbox->x + (c->geom.x - c->prev_bounds.x) * (bbox->width / c->prev_bounds.width); + c->geom.y = bbox->y + (c->geom.y - c->prev_bounds.y) * (bbox->height / c->prev_bounds.height); + } + if (c->geom.x >= bbox->x + bbox->width) c->geom.x = bbox->x + bbox->width - c->geom.width; if (c->geom.y >= bbox->y + bbox->height) @@ -2389,10 +2404,13 @@ setmon(Client *c, Monitor *m, uint32_t newtags) return; c->mon = m; c->prev = c->geom; + c->prev_bounds = (struct wlr_box){.x = 0, .y = 0, .width = 0, .height = 0}; /* Scene graph sends surface leave/enter events on move and resize */ - if (oldmon) + if (oldmon) { arrange(oldmon); + c->prev_bounds = oldmon->w; + } if (m) { /* Make sure window actually overlaps with the monitor */ resize(c, c->geom, 0); @@ -2400,6 +2418,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags) setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ setfloating(c, c->isfloating); } + c->prev_bounds = (struct wlr_box){.x = 0, .y = 0, .width = 0, .height = 0}; focusclient(focustop(selmon), 1); } -- 2.48.1