dwm-relative-controls.diff (10004B)
1 diff --git a/config.def.h b/config.def.h 2 index a2ac963..5e7ca5b 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -44,13 +44,14 @@ static const Layout layouts[] = { 6 { "[M]", monocle }, 7 }; 8 9 +#include "tags.c" 10 + 11 /* key definitions */ 12 #define MODKEY Mod1Mask 13 #define TAGKEYS(KEY,TAG) \ 14 - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 15 - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 16 - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 17 - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 18 + { MODKEY, KEY, view, {.ui = TAG} }, \ 19 + { MODKEY|ShiftMask, KEY, tag, {.ui = TAG} }, \ 20 + { MODKEY|ControlMask, KEY, viewtag, {.ui = TAG} }, 21 22 /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 23 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 24 @@ -95,6 +96,15 @@ static Key keys[] = { 25 TAGKEYS( XK_8, 7) 26 TAGKEYS( XK_9, 8) 27 { MODKEY|ShiftMask, XK_q, quit, {0} }, 28 + // Relative controls 29 + { MODKEY, XK_s, relativeview, {.i = +1} }, 30 + { MODKEY, XK_a, relativeview, {.i = -1} }, 31 + { MODKEY|ShiftMask, XK_s, relativemoveview, {.i = +1} }, 32 + { MODKEY|ShiftMask, XK_a, relativemoveview, {.i = -1} }, 33 + { MODKEY|ShiftMask, XK_x, relativemove, {.i = +1} }, 34 + // Different keyboard layouts 35 + { MODKEY|ShiftMask, XK_y, relativemove, {.i = -1} }, 36 + { MODKEY|ShiftMask, XK_z, relativemove, {.i = -1} }, 37 }; 38 39 /* button definitions */ 40 diff --git a/dwm.c b/dwm.c 41 index 5e4d494..97b1e6d 100644 42 --- a/dwm.c 43 +++ b/dwm.c 44 @@ -124,6 +124,7 @@ struct Monitor { 45 unsigned int tagset[2]; 46 int showbar; 47 int topbar; 48 + int selectedtag; 49 Client *clients; 50 Client *sel; 51 Client *stack; 52 @@ -639,6 +640,7 @@ createmon(void) 53 m->nmaster = nmaster; 54 m->showbar = showbar; 55 m->topbar = topbar; 56 + m->selectedtag = 1; 57 m->lt[0] = &layouts[0]; 58 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 59 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 60 @@ -1653,16 +1655,17 @@ spawn(const Arg *arg) 61 } 62 } 63 64 -void 65 -tag(const Arg *arg) 66 -{ 67 - if (selmon->sel && arg->ui & TAGMASK) { 68 - selmon->sel->tags = arg->ui & TAGMASK; 69 - focus(NULL); 70 - arrange(selmon); 71 - } 72 +void 73 +tag(const Arg *arg) { 74 + int endtag = 1 << arg->ui; 75 + if (selmon->sel && endtag & TAGMASK) { 76 + selmon->sel->tags = endtag & TAGMASK; 77 + focus(NULL); 78 + arrange(selmon); 79 + } 80 } 81 82 + 83 void 84 tagmon(const Arg *arg) 85 { 86 @@ -2035,16 +2038,18 @@ updatewmhints(Client *c) 87 } 88 } 89 90 + 91 void 92 -view(const Arg *arg) 93 -{ 94 - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 95 - return; 96 - selmon->seltags ^= 1; /* toggle sel tagset */ 97 - if (arg->ui & TAGMASK) 98 - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 99 - focus(NULL); 100 - arrange(selmon); 101 +view(const Arg *arg) { 102 + int endtag = 1 << arg->ui; 103 + if ((endtag & TAGMASK) == selmon->tagset[selmon->seltags]) 104 + return; 105 + selmon->seltags ^= 1; /* toggle sel tagset */ 106 + if (endtag & TAGMASK) 107 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 108 + selmon->selectedtag = arg->ui; 109 + focus(NULL); 110 + arrange(selmon); 111 } 112 113 Client * 114 diff --git a/tags.c b/tags.c 115 new file mode 100644 116 index 0000000..78b7b20 117 --- /dev/null 118 +++ b/tags.c 119 @@ -0,0 +1,52 @@ 120 +void relativemove(const Arg *arg) { 121 + if (selmon->sel && arg->i) { 122 + int endtag = selmon->selectedtag + arg->i; 123 + if (endtag < 0 || endtag > LENGTH(tags) - 1) 124 + return; 125 + selmon->sel->tags = 1 << endtag; 126 + focus(NULL); 127 + arrange(selmon); 128 + } 129 +} 130 + 131 +void relativeview(const Arg *arg) { 132 + int newmon = selmon->selectedtag + arg->i; 133 + if (newmon < 0 || newmon > LENGTH(tags) - 1) 134 + return; 135 + int endtag = 1 << newmon; 136 + if ((endtag & TAGMASK) == selmon->tagset[selmon->seltags]) 137 + return; 138 + selmon->seltags ^= 1; 139 + if (endtag & TAGMASK) 140 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 141 + selmon->selectedtag = newmon; 142 + focus(NULL); 143 + arrange(selmon); 144 +} 145 + 146 +void relativemoveview(const Arg *arg) { 147 + if (selmon->sel && arg->i) { 148 + int endtag = selmon->selectedtag + arg->i; 149 + if (endtag < 0 || endtag > LENGTH(tags) - 1) 150 + return; 151 + selmon->sel->tags = 1 << endtag; 152 + } 153 + int newmon = selmon->selectedtag + arg->i; 154 + int endtag = 1 << newmon; 155 + if (endtag & TAGMASK) 156 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 157 + selmon->selectedtag = newmon; 158 + focus(NULL); 159 + arrange(selmon); 160 +} 161 + 162 +void viewtag(const Arg *arg) { 163 + int endtag = 1 << arg->ui; 164 + if (selmon->sel && endtag) { 165 + selmon->sel->tags = endtag & TAGMASK; 166 + selmon->selectedtag = arg->ui; 167 + focus(NULL); 168 + view(arg); 169 + arrange(selmon); 170 + } 171 +} 172 \ No newline at end of file 173 diff --git a/config.def.h b/config.def.h 174 index a2ac963..5e7ca5b 100644 175 --- a/config.def.h 176 +++ b/config.def.h 177 @@ -44,13 +44,14 @@ static const Layout layouts[] = { 178 { "[M]", monocle }, 179 }; 180 181 +#include "tags.c" 182 + 183 /* key definitions */ 184 #define MODKEY Mod1Mask 185 #define TAGKEYS(KEY,TAG) \ 186 - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 187 - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 188 - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 189 - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 190 + { MODKEY, KEY, view, {.ui = TAG} }, \ 191 + { MODKEY|ShiftMask, KEY, tag, {.ui = TAG} }, \ 192 + { MODKEY|ControlMask, KEY, viewtag, {.ui = TAG} }, 193 194 /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 195 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 196 @@ -95,6 +96,15 @@ static Key keys[] = { 197 TAGKEYS( XK_8, 7) 198 TAGKEYS( XK_9, 8) 199 { MODKEY|ShiftMask, XK_q, quit, {0} }, 200 + // Relative controls 201 + { MODKEY, XK_s, relativeview, {.i = +1} }, 202 + { MODKEY, XK_a, relativeview, {.i = -1} }, 203 + { MODKEY|ShiftMask, XK_s, relativemoveview, {.i = +1} }, 204 + { MODKEY|ShiftMask, XK_a, relativemoveview, {.i = -1} }, 205 + { MODKEY|ShiftMask, XK_x, relativemove, {.i = +1} }, 206 + // Different keyboard layouts 207 + { MODKEY|ShiftMask, XK_y, relativemove, {.i = -1} }, 208 + { MODKEY|ShiftMask, XK_z, relativemove, {.i = -1} }, 209 }; 210 211 /* button definitions */ 212 diff --git a/dwm.c b/dwm.c 213 index 5e4d494..97b1e6d 100644 214 --- a/dwm.c 215 +++ b/dwm.c 216 @@ -124,6 +124,7 @@ struct Monitor { 217 unsigned int tagset[2]; 218 int showbar; 219 int topbar; 220 + int selectedtag; 221 Client *clients; 222 Client *sel; 223 Client *stack; 224 @@ -639,6 +640,7 @@ createmon(void) 225 m->nmaster = nmaster; 226 m->showbar = showbar; 227 m->topbar = topbar; 228 + m->selectedtag = 1; 229 m->lt[0] = &layouts[0]; 230 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 231 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 232 @@ -1653,16 +1655,17 @@ spawn(const Arg *arg) 233 } 234 } 235 236 -void 237 -tag(const Arg *arg) 238 -{ 239 - if (selmon->sel && arg->ui & TAGMASK) { 240 - selmon->sel->tags = arg->ui & TAGMASK; 241 - focus(NULL); 242 - arrange(selmon); 243 - } 244 +void 245 +tag(const Arg *arg) { 246 + int endtag = 1 << arg->ui; 247 + if (selmon->sel && endtag & TAGMASK) { 248 + selmon->sel->tags = endtag & TAGMASK; 249 + focus(NULL); 250 + arrange(selmon); 251 + } 252 } 253 254 + 255 void 256 tagmon(const Arg *arg) 257 { 258 @@ -2035,16 +2038,18 @@ updatewmhints(Client *c) 259 } 260 } 261 262 + 263 void 264 -view(const Arg *arg) 265 -{ 266 - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 267 - return; 268 - selmon->seltags ^= 1; /* toggle sel tagset */ 269 - if (arg->ui & TAGMASK) 270 - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 271 - focus(NULL); 272 - arrange(selmon); 273 +view(const Arg *arg) { 274 + int endtag = 1 << arg->ui; 275 + if ((endtag & TAGMASK) == selmon->tagset[selmon->seltags]) 276 + return; 277 + selmon->seltags ^= 1; /* toggle sel tagset */ 278 + if (endtag & TAGMASK) 279 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 280 + selmon->selectedtag = arg->ui; 281 + focus(NULL); 282 + arrange(selmon); 283 } 284 285 Client * 286 diff --git a/tags.c b/tags.c 287 new file mode 100644 288 index 0000000..78b7b20 289 --- /dev/null 290 +++ b/tags.c 291 @@ -0,0 +1,52 @@ 292 +void relativemove(const Arg *arg) { 293 + if (selmon->sel && arg->i) { 294 + int endtag = selmon->selectedtag + arg->i; 295 + if (endtag < 0 || endtag > LENGTH(tags) - 1) 296 + return; 297 + selmon->sel->tags = 1 << endtag; 298 + focus(NULL); 299 + arrange(selmon); 300 + } 301 +} 302 + 303 +void relativeview(const Arg *arg) { 304 + int newmon = selmon->selectedtag + arg->i; 305 + if (newmon < 0 || newmon > LENGTH(tags) - 1) 306 + return; 307 + int endtag = 1 << newmon; 308 + if ((endtag & TAGMASK) == selmon->tagset[selmon->seltags]) 309 + return; 310 + selmon->seltags ^= 1; 311 + if (endtag & TAGMASK) 312 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 313 + selmon->selectedtag = newmon; 314 + focus(NULL); 315 + arrange(selmon); 316 +} 317 + 318 +void relativemoveview(const Arg *arg) { 319 + if (selmon->sel && arg->i) { 320 + int endtag = selmon->selectedtag + arg->i; 321 + if (endtag < 0 || endtag > LENGTH(tags) - 1) 322 + return; 323 + selmon->sel->tags = 1 << endtag; 324 + } 325 + int newmon = selmon->selectedtag + arg->i; 326 + int endtag = 1 << newmon; 327 + if (endtag & TAGMASK) 328 + selmon->tagset[selmon->seltags] = endtag & TAGMASK; 329 + selmon->selectedtag = newmon; 330 + focus(NULL); 331 + arrange(selmon); 332 +} 333 + 334 +void viewtag(const Arg *arg) { 335 + int endtag = 1 << arg->ui; 336 + if (selmon->sel && endtag) { 337 + selmon->sel->tags = endtag & TAGMASK; 338 + selmon->selectedtag = arg->ui; 339 + focus(NULL); 340 + view(arg); 341 + arrange(selmon); 342 + } 343 +} 344 \ No newline at end of file