diff options
Diffstat (limited to 'dwl-patches/patches/dragresize/dragresize.patch')
-rw-r--r-- | dwl-patches/patches/dragresize/dragresize.patch | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/dwl-patches/patches/dragresize/dragresize.patch b/dwl-patches/patches/dragresize/dragresize.patch new file mode 100644 index 0000000..1e4cfe0 --- /dev/null +++ b/dwl-patches/patches/dragresize/dragresize.patch @@ -0,0 +1,210 @@ +From 83ae7d4816a49f46063ab16ffecd32b2e7e61784 Mon Sep 17 00:00:00 2001 +From: choc <notchoc@proton.me> +Date: Fri, 15 Sep 2023 11:45:16 +0800 +Subject: [PATCH] dragresize: implement rio-like window resizing + +select window to resize then drag out an area for it to occupy +--- + dwl.c | 132 +++++++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 98 insertions(+), 34 deletions(-) + +diff --git a/dwl.c b/dwl.c +index dc0437e..843aa7a 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -80,7 +80,7 @@ + #define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0) + + /* enums */ +-enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ ++enum { CurNormal, CurPressed, CurSelect, CurMove, CurResize, CurBind }; /* cursor */ + enum { XDGShell, LayerShell, X11 }; /* client types */ + enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */ + #ifdef XWAYLAND +@@ -603,15 +603,21 @@ buttonpress(struct wl_listener *listener, void *data) + + switch (event->state) { + case WLR_BUTTON_PRESSED: +- cursor_mode = CurPressed; + selmon = xytomon(cursor->x, cursor->y); +- if (locked) ++ if (locked) { ++ cursor_mode = CurPressed; + break; ++ } + +- /* Change focus if the button was _pressed_ over a client */ +- xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL); +- if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) +- focusclient(c, 1); ++ if (cursor_mode == CurNormal) ++ cursor_mode = CurPressed; ++ ++ if (cursor_mode != CurResize) { ++ /* Change focus if the button was _pressed_ over a client */ ++ xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL); ++ if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) ++ focusclient(c, 1); ++ } + + keyboard = wlr_seat_get_keyboard(seat); + mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; +@@ -624,17 +630,42 @@ buttonpress(struct wl_listener *listener, void *data) + } + break; + case WLR_BUTTON_RELEASED: ++ if (locked) { ++ cursor_mode = CurNormal; ++ break; ++ } + /* If you released any buttons, we exit interactive move/resize mode. */ +- /* TODO should reset to the pointer focus's current setcursor */ +- if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { +- wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); ++ switch (cursor_mode) { ++ case CurPressed: + cursor_mode = CurNormal; +- /* Drop the window off on its new monitor */ +- selmon = xytomon(cursor->x, cursor->y); +- setmon(grabc, selmon, 0); ++ case CurNormal: ++ break; ++ case CurSelect: + return; +- } else { ++ case CurResize: ++ /* a label can only be part of a statement - Wpedantic */ ++ { ++ int nw = abs((int) cursor->x - grabcx); ++ int nh = abs((int) cursor->y - grabcy); ++ if (nw > 1 && nh > 1) { ++ setfloating(grabc, 1); ++ resize(grabc, (struct wlr_box){.x = MIN(ROUND(cursor->x), grabcx), ++ .y = MIN(ROUND(cursor->y), grabcy), ++ .width = nw, .height = nh}, 1); ++ } ++ } ++ /* fallthrough */ ++ default: ++ /* TODO should reset to the pointer focus's current setcursor */ ++ wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); ++ /* Drop the window off on its new monitor */ ++ if (grabc && cursor_mode != CurBind) { ++ selmon = xytomon(cursor->x, cursor->y); ++ setmon(grabc, selmon, 0); ++ grabc = NULL; ++ } + cursor_mode = CurNormal; ++ return; + } + break; + } +@@ -1815,15 +1846,33 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d + wlr_scene_node_set_position(&drag_icon->node, (int)round(cursor->x), (int)round(cursor->y)); + + /* If we are currently grabbing the mouse, handle and return */ +- if (cursor_mode == CurMove) { ++ switch (cursor_mode) { ++ case CurSelect: ++ return; ++ case CurMove: + /* Move the grabbed client to the new position. */ + resize(grabc, (struct wlr_box){.x = (int)round(cursor->x) - grabcx, .y = (int)round(cursor->y) - grabcy, + .width = grabc->geom.width, .height = grabc->geom.height}, 1); + return; +- } else if (cursor_mode == CurResize) { +- resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, +- .width = (int)round(cursor->x) - grabc->geom.x, .height = (int)round(cursor->y) - grabc->geom.y}, 1); +- return; ++ case CurResize: ++ { ++ int w, h, x, y; ++ if (!grabc) ++ return; ++ w = abs(grabcx - (int)round(cursor->x)); ++ h = abs(grabcy - (int)round(cursor->y)); ++ x = MIN(grabcx, (int)round(cursor->x)) - grabc->geom.x; ++ y = MIN(grabcy, (int)round(cursor->y)) - grabc->geom.y; ++ wlr_scene_rect_set_size(grabc->border[0], w, grabc->bw); ++ wlr_scene_rect_set_size(grabc->border[1], w, grabc->bw); ++ wlr_scene_rect_set_size(grabc->border[2], grabc->bw, h - 2 * grabc->bw); ++ wlr_scene_rect_set_size(grabc->border[3], grabc->bw, h - 2 * grabc->bw); ++ wlr_scene_node_set_position(&grabc->border[0]->node, x, y); ++ wlr_scene_node_set_position(&grabc->border[1]->node, x, y + h - grabc->bw); ++ wlr_scene_node_set_position(&grabc->border[2]->node, x, y + grabc->bw); ++ wlr_scene_node_set_position(&grabc->border[3]->node, x + w - grabc->bw, y + grabc->bw); ++ return; ++ } + } + + /* If there's no client surface under the cursor, set the cursor image to a +@@ -1853,29 +1902,43 @@ motionrelative(struct wl_listener *listener, void *data) + void + moveresize(const Arg *arg) + { +- if (cursor_mode != CurNormal && cursor_mode != CurPressed) +- return; +- xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); +- if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) ++ /* Consider global select bool instead of this + CurSelect enum */ ++ bool selected = (cursor_mode == CurSelect); ++ if (!selected) { ++ if (cursor_mode != CurNormal && cursor_mode != CurPressed) ++ return; ++ xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); ++ } ++ ++ if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) { ++ grabc = NULL; ++ cursor_mode = CurNormal; + return; ++ } + +- /* Float the window and tell motionnotify to grab it */ +- setfloating(grabc, 1); ++ /* TODO: factor out selected bool */ + switch (cursor_mode = arg->ui) { ++ case CurResize: ++ if (!selected) break; ++ grabcx = ROUND(cursor->x); ++ grabcy = ROUND(cursor->y); ++ wlr_cursor_set_xcursor(cursor, cursor_mgr, "tcross"); ++ return; + case CurMove: + grabcx = (int)round(cursor->x) - grabc->geom.x; + grabcy = (int)round(cursor->y) - grabc->geom.y; ++ setfloating(grabc, 1); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); +- break; +- case CurResize: +- /* Doesn't work for X11 output - the next absolute motion event +- * returns the cursor to where it started */ +- wlr_cursor_warp_closest(cursor, NULL, +- grabc->geom.x + grabc->geom.width, +- grabc->geom.y + grabc->geom.height); +- wlr_cursor_set_xcursor(cursor, cursor_mgr, "se-resize"); +- break; ++ return; ++ default: ++ grabc = NULL; ++ cursor_mode = CurNormal; ++ wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); ++ return; + } ++ ++ cursor_mode = CurSelect; ++ wlr_cursor_set_xcursor(cursor, cursor_mgr, "crosshair"); + } + + void +@@ -2149,6 +2212,7 @@ resize(Client *c, struct wlr_box geo, int interact) + wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw); + wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw); + wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw); ++ wlr_scene_node_set_position(&c->border[0]->node, 0, 0); + wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw); + wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); + wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw); +-- +2.43.0 + |