dwm-movescratch-20240623.diff 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. From manual edit 20240622
  2. From: digit <Digit @ notabug.org>
  3. Date: Wed, 26 June 2024 21:40:57 +0100
  4. Subject: [PATCH] MoveScratch patch
  5. This plugin combines MoveStack and Scratchpad patches with reconfigurations.
  6. MoveStack allows you to move clients around in the stack and swap them
  7. with the master. It emulates the behavior off mod+shift+e and mod+shift+d
  8. in tabular boonad. movestack(+1) will swap the client with the current focus with
  9. the next client. movestack(-1) will swap the client with the current focus
  10. with the previous client.
  11. ---
  12. config.def.h | 7 +++
  13. movestack.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
  14. dwm.c | 33 +++++++++++++++++++++++++++++++++
  15. 3 files changed, 88 insertions(+)
  16. create mode 100644 movestack.c
  17. diff --git a/config.def.h b/config.def.h
  18. --- a/config.def.h
  19. +++ b/config.def.h
  20. @@ -4,14 +4,14 @@
  21. static const unsigned int borderpx = 1; /* border pixel of windows */
  22. static const unsigned int snap = 32; /* snap pixel */
  23. static const int showbar = 1; /* 0 means no bar */
  24. -static const int topbar = 1; /* 0 means bottom bar */
  25. -static const char *fonts[] = { "monospace:size=10" };
  26. -static const char dmenufont[] = "monospace:size=10";
  27. -static const char col_gray1[] = "#222222";
  28. -static const char col_gray2[] = "#444444";
  29. -static const char col_gray3[] = "#bbbbbb";
  30. -static const char col_gray4[] = "#eeeeee";
  31. -static const char col_cyan[] = "#005577";
  32. +static const int topbar = 0; /* 0 means bottom bar */
  33. +static const char *fonts[] = { "nztt:pixelsize=12" };
  34. +static const char dmenufont[] = "nztt:pixelsize=12";
  35. +static const char col_gray1[] = "#391300";
  36. +static const char col_gray2[] = "#5f4c00";
  37. +static const char col_gray3[] = "#857200";
  38. +static const char col_gray4[] = "#be9800";
  39. +static const char col_cyan[] = "#fbc200";
  40. static const char *colors[][3] = {
  41. /* fg bg border */
  42. [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
  43. @@ -27,7 +27,7 @@
  44. * WM_NAME(STRING) = title
  45. */
  46. /* class instance title tags mask isfloating monitor */
  47. - { "Gimp", NULL, NULL, 0, 1, -1 },
  48. + { "Gimp", NULL, NULL, 0, 0, -1 },
  49. { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
  50. };
  51. @@ -57,30 +57,36 @@
  52. /* commands */
  53. static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
  54. -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
  55. +static const char *dmenucmd[] = { "dmenu_run", "-b", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
  56. +static const char scratchpadname[] = "scratchpad";
  57. +static const char *scratchpadcmd[] = { "st", "-t", scratchpadname, "-g", "120x34", NULL };
  58. static const char *termcmd[] = { "st", NULL };
  59. +#include "movestack.c"
  60. static const Key keys[] = {
  61. /* modifier key function argument */
  62. - { MODKEY, XK_p, spawn, {.v = dmenucmd } },
  63. - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
  64. + { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } },
  65. + { MODKEY|ShiftMask, XK_e, movestack, {.i = +1 } },
  66. + { MODKEY|ShiftMask, XK_d, movestack, {.i = -1 } },
  67. + { MODKEY, XK_r, spawn, {.v = dmenucmd } },
  68. + { MODKEY, XK_Return, spawn, {.v = termcmd } },
  69. { MODKEY, XK_b, togglebar, {0} },
  70. - { MODKEY, XK_j, focusstack, {.i = +1 } },
  71. - { MODKEY, XK_k, focusstack, {.i = -1 } },
  72. - { MODKEY, XK_i, incnmaster, {.i = +1 } },
  73. - { MODKEY, XK_d, incnmaster, {.i = -1 } },
  74. - { MODKEY, XK_h, setmfact, {.f = -0.05} },
  75. - { MODKEY, XK_l, setmfact, {.f = +0.05} },
  76. - { MODKEY, XK_Return, zoom, {0} },
  77. + { MODKEY, XK_e, focusstack, {.i = +1 } },
  78. + { MODKEY, XK_d, focusstack, {.i = -1 } },
  79. + { MODKEY, XK_a, incnmaster, {.i = +1 } },
  80. + { MODKEY, XK_z, incnmaster, {.i = -1 } },
  81. + { MODKEY, XK_s, setmfact, {.f = -0.05} },
  82. + { MODKEY, XK_f, setmfact, {.f = +0.05} },
  83. + { MODKEY|ShiftMask, XK_Return, zoom, {0} },
  84. { MODKEY, XK_Tab, view, {0} },
  85. - { MODKEY|ShiftMask, XK_c, killclient, {0} },
  86. + { MODKEY|ShiftMask, XK_F4, killclient, {0} },
  87. { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
  88. - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
  89. - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
  90. + { MODKEY, XK_g, setlayout, {.v = &layouts[1]} },
  91. + { MODKEY, XK_v, setlayout, {.v = &layouts[2]} },
  92. { MODKEY, XK_space, setlayout, {0} },
  93. - { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
  94. - { MODKEY, XK_0, view, {.ui = ~0 } },
  95. - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
  96. + { MODKEY|ShiftMask, XK_t, togglefloating, {0} },
  97. + { MODKEY, XK_c, view, {.ui = ~0 } },
  98. + { MODKEY|ShiftMask, XK_c, tag, {.ui = ~0 } },
  99. { MODKEY, XK_comma, focusmon, {.i = -1 } },
  100. { MODKEY, XK_period, focusmon, {.i = +1 } },
  101. { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
  102. diff --git a/dwm.c b/dwm.c
  103. index f1d86b2..a8db21a 100644
  104. --- a/dwm.c
  105. +++ b/dwm.c
  106. @@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
  107. static void tile(Monitor *m);
  108. static void togglebar(const Arg *arg);
  109. static void togglefloating(const Arg *arg);
  110. +static void togglescratch(const Arg *arg);
  111. static void toggletag(const Arg *arg);
  112. static void toggleview(const Arg *arg);
  113. static void unfocus(Client *c, int setfocus);
  114. @@ -271,6 +272,8 @@ static Window root, wmcheckwin;
  115. /* configuration, allows nested code to access above variables */
  116. #include "config.h"
  117. +static unsigned int scratchtag = 1 << LENGTH(tags);
  118. +
  119. /* compile-time check if all tags fit into an unsigned int bit array. */
  120. struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
  121. @@ -1061,6 +1064,14 @@ manage(Window w, XWindowAttributes *wa)
  122. c->y = MAX(c->y, c->mon->wy);
  123. c->bw = borderpx;
  124. + selmon->tagset[selmon->seltags] &= ~scratchtag;
  125. + if (!strcmp(c->name, scratchpadname)) {
  126. + c->mon->tagset[c->mon->seltags] |= c->tags = scratchtag;
  127. + c->isfloating = True;
  128. + c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
  129. + c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
  130. + }
  131. +
  132. wc.border_width = c->bw;
  133. XConfigureWindow(dpy, w, CWBorderWidth, &wc);
  134. XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
  135. @@ -1651,6 +1662,7 @@ spawn(const Arg *arg)
  136. if (arg->v == dmenucmd)
  137. dmenumon[0] = '0' + selmon->num;
  138. + selmon->tagset[selmon->seltags] &= ~scratchtag;
  139. if (fork() == 0) {
  140. if (dpy)
  141. close(ConnectionNumber(dpy));
  142. @@ -1735,6 +1747,28 @@ togglefloating(const Arg *arg)
  143. arrange(selmon);
  144. }
  145. +void
  146. +togglescratch(const Arg *arg)
  147. +{
  148. + Client *c;
  149. + unsigned int found = 0;
  150. +
  151. + for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
  152. + if (found) {
  153. + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
  154. + if (newtagset) {
  155. + selmon->tagset[selmon->seltags] = newtagset;
  156. + focus(NULL);
  157. + arrange(selmon);
  158. + }
  159. + if (ISVISIBLE(c)) {
  160. + focus(c);
  161. + restack(selmon);
  162. + }
  163. + } else
  164. + spawn(arg);
  165. +}
  166. +
  167. void
  168. toggletag(const Arg *arg)
  169. {
  170. diff --git a/movestack.c b/movestack.c
  171. new file mode 100644
  172. index 0000000..520f4ae
  173. --- /dev/null
  174. +++ b/movestack.c
  175. @@ -0,0 +1,48 @@
  176. +void
  177. +movestack(const Arg *arg) {
  178. + Client *c = NULL, *p = NULL, *pc = NULL, *i;
  179. +
  180. + if(arg->i > 0) {
  181. + /* find the client after selmon->sel */
  182. + for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
  183. + if(!c)
  184. + for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
  185. +
  186. + }
  187. + else {
  188. + /* find the client before selmon->sel */
  189. + for(i = selmon->clients; i != selmon->sel; i = i->next)
  190. + if(ISVISIBLE(i) && !i->isfloating)
  191. + c = i;
  192. + if(!c)
  193. + for(; i; i = i->next)
  194. + if(ISVISIBLE(i) && !i->isfloating)
  195. + c = i;
  196. + }
  197. + /* find the client before selmon->sel and c */
  198. + for(i = selmon->clients; i && (!p || !pc); i = i->next) {
  199. + if(i->next == selmon->sel)
  200. + p = i;
  201. + if(i->next == c)
  202. + pc = i;
  203. + }
  204. +
  205. + /* swap c and selmon->sel selmon->clients in the selmon->clients list */
  206. + if(c && c != selmon->sel) {
  207. + Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
  208. + selmon->sel->next = c->next==selmon->sel?c:c->next;
  209. + c->next = temp;
  210. +
  211. + if(p && p != c)
  212. + p->next = c;
  213. + if(pc && pc != selmon->sel)
  214. + pc->next = selmon->sel;
  215. +
  216. + if(selmon->sel == selmon->clients)
  217. + selmon->clients = c;
  218. + else if(c == selmon->clients)
  219. + selmon->clients = selmon->sel;
  220. +
  221. + arrange(selmon);
  222. + }
  223. +}