dwm-moveresize.diff 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. From dd4d21ad7cebab8b6927f1446e5d1edd9cea94d5 Mon Sep 17 00:00:00 2001
  2. From: howoz <howoz@airmail.cc>
  3. Date: Mon, 23 Aug 2021 01:24:31 +0300
  4. Subject: [PATCH] [dwm][patch][moveresize] patch:
  5. prevent the cursor from going out of the window when resizing
  6. ---
  7. config.def.h | 16 ++++++
  8. dwm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++
  9. 2 files changed, 170 insertions(+)
  10. diff --git a/config.def.h b/config.def.h
  11. index a2ac963..87baa38 100644
  12. --- a/config.def.h
  13. +++ b/config.def.h
  14. @@ -79,6 +79,22 @@ static Key keys[] = {
  15. { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
  16. { MODKEY, XK_space, setlayout, {0} },
  17. { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
  18. + { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
  19. + { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
  20. + { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
  21. + { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
  22. + { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
  23. + { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
  24. + { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
  25. + { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
  26. + { MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
  27. + { MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
  28. + { MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
  29. + { MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
  30. + { MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
  31. + { MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
  32. + { MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
  33. + { MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
  34. { MODKEY, XK_0, view, {.ui = ~0 } },
  35. { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
  36. { MODKEY, XK_comma, focusmon, {.i = -1 } },
  37. diff --git a/dwm.c b/dwm.c
  38. index 5e4d494..0898236 100644
  39. --- a/dwm.c
  40. +++ b/dwm.c
  41. @@ -183,6 +183,8 @@ static void mappingnotify(XEvent *e);
  42. static void maprequest(XEvent *e);
  43. static void monocle(Monitor *m);
  44. static void motionnotify(XEvent *e);
  45. +static void moveresize(const Arg *arg);
  46. +static void moveresizeedge(const Arg *arg);
  47. static void movemouse(const Arg *arg);
  48. static Client *nexttiled(Client *c);
  49. static void pop(Client *);
  50. @@ -1193,6 +1195,158 @@ movemouse(const Arg *arg)
  51. }
  52. }
  53. +void
  54. +moveresize(const Arg *arg) {
  55. + /* only floating windows can be moved */
  56. + Client *c;
  57. + c = selmon->sel;
  58. + int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
  59. + char xAbs, yAbs, wAbs, hAbs;
  60. + int msx, msy, dx, dy, nmx, nmy;
  61. + unsigned int dui;
  62. + Window dummy;
  63. +
  64. + if (!c || !arg)
  65. + return;
  66. + if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
  67. + return;
  68. + if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
  69. + return;
  70. +
  71. + /* compute new window position; prevent window from be positioned outside the current monitor */
  72. + nw = c->w + w;
  73. + if (wAbs == 'W')
  74. + nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
  75. +
  76. + nh = c->h + h;
  77. + if (hAbs == 'H')
  78. + nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
  79. +
  80. + nx = c->x + x;
  81. + if (xAbs == 'X') {
  82. + if (x < selmon->mx)
  83. + nx = selmon->mx;
  84. + else if (x > selmon->mx + selmon->mw)
  85. + nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
  86. + else
  87. + nx = x;
  88. + }
  89. +
  90. + ny = c->y + y;
  91. + if (yAbs == 'Y') {
  92. + if (y < selmon->my)
  93. + ny = selmon->my;
  94. + else if (y > selmon->my + selmon->mh)
  95. + ny = selmon->my + selmon->mh - nh - 2 * c->bw;
  96. + else
  97. + ny = y;
  98. + }
  99. +
  100. + ox = c->x;
  101. + oy = c->y;
  102. + ow = c->w;
  103. + oh = c->h;
  104. +
  105. + XRaiseWindow(dpy, c->win);
  106. + Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
  107. + resize(c, nx, ny, nw, nh, True);
  108. +
  109. + /* move cursor along with the window to avoid problems caused by the sloppy focus */
  110. + if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
  111. + {
  112. + nmx = c->x - ox + c->w - ow;
  113. + nmy = c->y - oy + c->h - oh;
  114. + /* make sure the cursor stays inside the window */
  115. + if ((msx + nmx) > c->x && (msy + nmy) > c->y)
  116. + XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
  117. + }
  118. +}
  119. +
  120. +void
  121. +moveresizeedge(const Arg *arg) {
  122. + /* move or resize floating window to edge of screen */
  123. + Client *c;
  124. + c = selmon->sel;
  125. + char e;
  126. + int nx, ny, nw, nh, ox, oy, ow, oh, bp;
  127. + int msx, msy, dx, dy, nmx, nmy;
  128. + int starty;
  129. + unsigned int dui;
  130. + Window dummy;
  131. +
  132. + nx = c->x;
  133. + ny = c->y;
  134. + nw = c->w;
  135. + nh = c->h;
  136. +
  137. + starty = selmon->showbar && topbar ? bh : 0;
  138. + bp = selmon->showbar && !topbar ? bh : 0;
  139. +
  140. + if (!c || !arg)
  141. + return;
  142. + if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
  143. + return;
  144. + if(sscanf((char *)arg->v, "%c", &e) != 1)
  145. + return;
  146. +
  147. + if(e == 't')
  148. + ny = starty;
  149. +
  150. + if(e == 'b')
  151. + ny = c->h > selmon->mh - 2 * c->bw ? c->h - bp : selmon->mh - c->h - 2 * c->bw - bp;
  152. +
  153. + if(e == 'l')
  154. + nx = selmon->mx;
  155. +
  156. + if(e == 'r')
  157. + nx = c->w > selmon->mw - 2 * c->bw ? selmon->mx + c->w : selmon->mx + selmon->mw - c->w - 2 * c->bw;
  158. +
  159. + if(e == 'T') {
  160. + /* if you click to resize again, it will return to old size/position */
  161. + if(c->h + starty == c->oldh + c->oldy) {
  162. + nh = c->oldh;
  163. + ny = c->oldy;
  164. + } else {
  165. + nh = c->h + c->y - starty;
  166. + ny = starty;
  167. + }
  168. + }
  169. +
  170. + if(e == 'B')
  171. + nh = c->h + c->y + 2 * c->bw + bp == selmon->mh ? c->oldh : selmon->mh - c->y - 2 * c->bw - bp;
  172. +
  173. + if(e == 'L') {
  174. + if(selmon->mx + c->w == c->oldw + c->oldx) {
  175. + nw = c->oldw;
  176. + nx = c->oldx;
  177. + } else {
  178. + nw = c->w + c->x - selmon->mx;
  179. + nx = selmon->mx;
  180. + }
  181. + }
  182. +
  183. + if(e == 'R')
  184. + nw = c->w + c->x + 2 * c->bw == selmon->mx + selmon->mw ? c->oldw : selmon->mx + selmon->mw - c->x - 2 * c->bw;
  185. +
  186. + ox = c->x;
  187. + oy = c->y;
  188. + ow = c->w;
  189. + oh = c->h;
  190. +
  191. + XRaiseWindow(dpy, c->win);
  192. + Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
  193. + resize(c, nx, ny, nw, nh, True);
  194. +
  195. + /* move cursor along with the window to avoid problems caused by the sloppy focus */
  196. + if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) {
  197. + nmx = c->x - ox + c->w - ow;
  198. + nmy = c->y - oy + c->h - oh;
  199. + /* make sure the cursor stays inside the window */
  200. + if ((msx + nmx) > c->x && (msy + nmy) > c->y)
  201. + XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
  202. + }
  203. +}
  204. +
  205. Client *
  206. nexttiled(Client *c)
  207. {
  208. --
  209. 2.33.0