summaryrefslogtreecommitdiffstats
path: root/dwl-patches/patches/dragresize/dragresize.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dwl-patches/patches/dragresize/dragresize.patch')
-rw-r--r--dwl-patches/patches/dragresize/dragresize.patch210
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
+