dwm-single_tagset-20211114-a786211.diff (18942B)
1 From 7c6ad58007d403c0f45043259227179a01c3dca4 Mon Sep 17 00:00:00 2001 2 From: BrunoCooper17 <BrunoCooper17@outlook.com> 3 Date: Sun, 14 Nov 2021 13:13:12 -0600 4 Subject: [PATCH] single tagset for dwm source a786211 20211015 5 6 Description 7 This patch addresses the multi-monitor setup. Instead of having separate tags for every monitor there is just one list of tags for all monitors. Instead of moving windows from one monitor to the other, the desired tag from the other monitor can just be selected and all windows will be drawn on the current monitor. 8 9 Several deep changes needed to be made: 10 11 Macro ISVISIBLE expects a second parameter, the monitor 12 Monitor->clients and Monitor->stack were moved to the global variable Clientlist cl. All monitors refer to this one list. 13 A new method attachclients was added. When changing between tags this function ensures that all clients are pointing to the right monitor. 14 15 This patch also add _NET_WM_DESKTOP attribute 16 17 Authors 18 Jan Christoph Ebersbach - jceb@e-jc.de 19 Mohammad Zeinali - mzeinali@tutanota.com 20 Jesus Mastache Caballero - <BrunoCooper17@outlook.com> 21 --- 22 dwm.c | 243 ++++++++++++++++++++++++++++++++++++++++++++-------------- 23 1 file changed, 187 insertions(+), 56 deletions(-) 24 25 diff --git a/dwm.c b/dwm.c 26 index 5e4d494..b93b071 100644 27 --- a/dwm.c 28 +++ b/dwm.c 29 @@ -20,6 +20,7 @@ 30 * 31 * To understand everything else, start reading main(). 32 */ 33 +#include <X11/X.h> 34 #include <errno.h> 35 #include <locale.h> 36 #include <signal.h> 37 @@ -49,7 +50,7 @@ 38 #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) 39 #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ 40 * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) 41 -#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) 42 +#define ISVISIBLE(C, M) ((C->tags & M->tagset[M->seltags])) 43 #define LENGTH(X) (sizeof X / sizeof X[0]) 44 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) 45 #define WIDTH(X) ((X)->w + 2 * (X)->bw) 46 @@ -62,7 +63,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 47 enum { SchemeNorm, SchemeSel }; /* color schemes */ 48 enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 49 NetWMFullscreen, NetActiveWindow, NetWMWindowType, 50 - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 51 + NetWMWindowTypeDialog, NetClientList, NetWMDesktop, NetLast }; /* EWMH atoms */ 52 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 53 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 54 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 55 @@ -82,6 +83,7 @@ typedef struct { 56 const Arg arg; 57 } Button; 58 59 +typedef struct Clientlist Clientlist; 60 typedef struct Monitor Monitor; 61 typedef struct Client Client; 62 struct Client { 63 @@ -124,9 +126,8 @@ struct Monitor { 64 unsigned int tagset[2]; 65 int showbar; 66 int topbar; 67 - Client *clients; 68 + Clientlist *cl; 69 Client *sel; 70 - Client *stack; 71 Monitor *next; 72 Window barwin; 73 const Layout *lt[2]; 74 @@ -141,12 +142,18 @@ typedef struct { 75 int monitor; 76 } Rule; 77 78 +struct Clientlist { 79 + Client *clients; 80 + Client *stack; 81 +}; 82 + 83 /* function declarations */ 84 static void applyrules(Client *c); 85 static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); 86 static void arrange(Monitor *m); 87 static void arrangemon(Monitor *m); 88 static void attach(Client *c); 89 +static void attachclients(Monitor *m); 90 static void attachstack(Client *c); 91 static void buttonpress(XEvent *e); 92 static void checkotherwm(void); 93 @@ -184,7 +191,7 @@ static void maprequest(XEvent *e); 94 static void monocle(Monitor *m); 95 static void motionnotify(XEvent *e); 96 static void movemouse(const Arg *arg); 97 -static Client *nexttiled(Client *c); 98 +static Client *nexttiled(Client *c, Monitor *m); 99 static void pop(Client *); 100 static void propertynotify(XEvent *e); 101 static void quit(const Arg *arg); 102 @@ -226,6 +233,7 @@ static void updatesizehints(Client *c); 103 static void updatestatus(void); 104 static void updatetitle(Client *c); 105 static void updatewindowtype(Client *c); 106 +static void updatewmdesktop(Window w, int tag); 107 static void updatewmhints(Client *c); 108 static void view(const Arg *arg); 109 static Client *wintoclient(Window w); 110 @@ -268,6 +276,7 @@ static Display *dpy; 111 static Drw *drw; 112 static Monitor *mons, *selmon; 113 static Window root, wmcheckwin; 114 +static Clientlist *cl; 115 116 /* configuration, allows nested code to access above variables */ 117 #include "config.h" 118 @@ -300,7 +309,7 @@ applyrules(Client *c) 119 { 120 c->isfloating = r->isfloating; 121 c->tags |= r->tags; 122 - for (m = mons; m && m->num != r->monitor; m = m->next); 123 + for (m = mons; m && (m->tagset[m->seltags] & c->tags) == 0; m = m->next); 124 if (m) 125 c->mon = m; 126 } 127 @@ -382,9 +391,9 @@ void 128 arrange(Monitor *m) 129 { 130 if (m) 131 - showhide(m->stack); 132 + showhide(m->cl->stack); 133 else for (m = mons; m; m = m->next) 134 - showhide(m->stack); 135 + showhide(m->cl->stack); 136 if (m) { 137 arrangemon(m); 138 restack(m); 139 @@ -396,6 +405,10 @@ void 140 arrangemon(Monitor *m) 141 { 142 strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); 143 + if (m->cl) 144 + for (Client* c = m->cl->clients; c; c = c->next) 145 + updatewmdesktop(c->win, c->tags); 146 + 147 if (m->lt[m->sellt]->arrange) 148 m->lt[m->sellt]->arrange(m); 149 } 150 @@ -403,15 +416,49 @@ arrangemon(Monitor *m) 151 void 152 attach(Client *c) 153 { 154 - c->next = c->mon->clients; 155 - c->mon->clients = c; 156 + c->next = c->mon->cl->clients; 157 + c->mon->cl->clients = c; 158 +} 159 + 160 +void 161 +attachclients(Monitor *m) { 162 + /* attach clients to the specified monitor */ 163 + Monitor *tm; 164 + Client *c; 165 + unsigned int utags = 0; 166 + Bool rmons = False; 167 + if(!m) 168 + return; 169 + 170 + /* collect information about the tags in use */ 171 + for (tm = mons; tm; tm = tm->next) 172 + if(tm != m) 173 + utags |= tm->tagset[tm->seltags]; 174 + 175 + for (c = m->cl->clients; c; c = c->next) 176 + if(ISVISIBLE(c, m)) { 177 + /* if client is also visible on other tags that are displayed on 178 + * other monitors, remove these tags */ 179 + if(c->tags & utags) { 180 + c->tags = c->tags & m->tagset[m->seltags]; 181 + rmons = True; 182 + } 183 + unfocus(c, True); 184 + c->mon = m; 185 + } 186 + 187 + if (rmons) 188 + for (tm = mons; tm; tm = tm->next) 189 + if(tm != m) 190 + arrange(tm); 191 + 192 } 193 194 void 195 attachstack(Client *c) 196 { 197 - c->snext = c->mon->stack; 198 - c->mon->stack = c; 199 + c->snext = c->mon->cl->stack; 200 + c->mon->cl->stack = c; 201 } 202 203 void 204 @@ -478,8 +525,8 @@ cleanup(void) 205 view(&a); 206 selmon->lt[selmon->sellt] = &foo; 207 for (m = mons; m; m = m->next) 208 - while (m->stack) 209 - unmanage(m->stack, 0); 210 + while (m->cl->stack) 211 + unmanage(m->cl->stack, 0); 212 XUngrabKey(dpy, AnyKey, AnyModifier, root); 213 while (mons) 214 cleanupmon(mons); 215 @@ -565,7 +612,7 @@ configurenotify(XEvent *e) 216 drw_resize(drw, sw, bh); 217 updatebars(); 218 for (m = mons; m; m = m->next) { 219 - for (c = m->clients; c; c = c->next) 220 + for (c = m->cl->clients; c; c = c->next) 221 if (c->isfullscreen) 222 resizeclient(c, m->mx, m->my, m->mw, m->mh); 223 XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); 224 @@ -611,7 +658,7 @@ configurerequest(XEvent *e) 225 c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ 226 if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) 227 configure(c); 228 - if (ISVISIBLE(c)) 229 + if (ISVISIBLE(c, m)) 230 XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); 231 } else 232 configure(c); 233 @@ -631,10 +678,31 @@ configurerequest(XEvent *e) 234 Monitor * 235 createmon(void) 236 { 237 - Monitor *m; 238 + Monitor *m, *tm; 239 + int i; 240 241 + /* bail out if the number of monitors exceeds the number of tags */ 242 + for (i=1, tm=mons; tm; i++, tm=tm->next); 243 + if (i > LENGTH(tags)) { 244 + fprintf(stderr, "dwm: failed to add monitor, number of tags exceeded\n"); 245 + return NULL; 246 + } 247 + /* find the first tag that isn't in use */ 248 + for (i=0; i < LENGTH(tags); i++) { 249 + for (tm=mons; tm && !(tm->tagset[tm->seltags] & (1<<i)); tm=tm->next); 250 + if (!tm) 251 + break; 252 + } 253 + /* reassign all tags to monitors since there's currently no free tag for the 254 + * new monitor */ 255 + if (i >= LENGTH(tags)) 256 + for (i=0, tm=mons; tm; tm=tm->next, i++) { 257 + tm->seltags ^= 1; 258 + tm->tagset[tm->seltags] = (1<<i) & TAGMASK; 259 + } 260 m = ecalloc(1, sizeof(Monitor)); 261 - m->tagset[0] = m->tagset[1] = 1; 262 + m->cl = cl; 263 + m->tagset[0] = m->tagset[1] = (1<<i) & TAGMASK; 264 m->mfact = mfact; 265 m->nmaster = nmaster; 266 m->showbar = showbar; 267 @@ -660,7 +728,7 @@ detach(Client *c) 268 { 269 Client **tc; 270 271 - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); 272 + for (tc = &c->mon->cl->clients; *tc && *tc != c; tc = &(*tc)->next); 273 *tc = c->next; 274 } 275 276 @@ -669,11 +737,11 @@ detachstack(Client *c) 277 { 278 Client **tc, *t; 279 280 - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); 281 + for (tc = &c->mon->cl->stack; *tc && *tc != c; tc = &(*tc)->snext); 282 *tc = c->snext; 283 284 if (c == c->mon->sel) { 285 - for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); 286 + for (t = c->mon->cl->stack; t && !ISVISIBLE(t, c->mon); t = t->snext); 287 c->mon->sel = t; 288 } 289 } 290 @@ -709,7 +777,7 @@ drawbar(Monitor *m) 291 drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); 292 } 293 294 - for (c = m->clients; c; c = c->next) { 295 + for (c = m->cl->clients; c; c = c->next) { 296 occ |= c->tags; 297 if (c->isurgent) 298 urg |= c->tags; 299 @@ -784,8 +852,8 @@ expose(XEvent *e) 300 void 301 focus(Client *c) 302 { 303 - if (!c || !ISVISIBLE(c)) 304 - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); 305 + if (!c || !ISVISIBLE(c, selmon)) 306 + for (c = selmon->cl->stack; c && !ISVISIBLE(c, selmon); c = c->snext); 307 if (selmon->sel && selmon->sel != c) 308 unfocus(selmon->sel, 0); 309 if (c) { 310 @@ -838,16 +906,16 @@ focusstack(const Arg *arg) 311 if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) 312 return; 313 if (arg->i > 0) { 314 - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); 315 + for (c = selmon->sel->next; c && !ISVISIBLE(c, selmon); c = c->next); 316 if (!c) 317 - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); 318 + for (c = selmon->cl->clients; c && !ISVISIBLE(c, selmon); c = c->next); 319 } else { 320 - for (i = selmon->clients; i != selmon->sel; i = i->next) 321 - if (ISVISIBLE(i)) 322 + for (i = selmon->cl->clients; i != selmon->sel; i = i->next) 323 + if (ISVISIBLE(i, selmon)) 324 c = i; 325 if (!c) 326 for (; i; i = i->next) 327 - if (ISVISIBLE(i)) 328 + if (ISVISIBLE(i, selmon)) 329 c = i; 330 } 331 if (c) { 332 @@ -1107,12 +1175,12 @@ monocle(Monitor *m) 333 unsigned int n = 0; 334 Client *c; 335 336 - for (c = m->clients; c; c = c->next) 337 - if (ISVISIBLE(c)) 338 + for (c = m->cl->clients; c; c = c->next) 339 + if (ISVISIBLE(c, m)) 340 n++; 341 if (n > 0) /* override layout symbol */ 342 snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); 343 - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) 344 + for (c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m)) 345 resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); 346 } 347 348 @@ -1194,9 +1262,9 @@ movemouse(const Arg *arg) 349 } 350 351 Client * 352 -nexttiled(Client *c) 353 +nexttiled(Client *c, Monitor *m) 354 { 355 - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); 356 + for (; c && (c->isfloating || !ISVISIBLE(c, m)); c = c->next); 357 return c; 358 } 359 360 @@ -1360,8 +1428,8 @@ restack(Monitor *m) 361 if (m->lt[m->sellt]->arrange) { 362 wc.stack_mode = Below; 363 wc.sibling = m->barwin; 364 - for (c = m->stack; c; c = c->snext) 365 - if (!c->isfloating && ISVISIBLE(c)) { 366 + for (c = m->cl->stack; c; c = c->snext) 367 + if (!c->isfloating && ISVISIBLE(c, m)) { 368 XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); 369 wc.sibling = c->win; 370 } 371 @@ -1414,11 +1482,9 @@ sendmon(Client *c, Monitor *m) 372 if (c->mon == m) 373 return; 374 unfocus(c, 1); 375 - detach(c); 376 detachstack(c); 377 c->mon = m; 378 c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 379 - attach(c); 380 attachstack(c); 381 focus(NULL); 382 arrange(NULL); 383 @@ -1541,6 +1607,8 @@ setup(void) 384 screen = DefaultScreen(dpy); 385 sw = DisplayWidth(dpy, screen); 386 sh = DisplayHeight(dpy, screen); 387 + if(!(cl = (Clientlist *)calloc(1, sizeof(Clientlist)))) 388 + die("fatal: could not malloc() %u bytes\n", sizeof(Clientlist)); 389 root = RootWindow(dpy, screen); 390 drw = drw_create(dpy, screen, root, sw, sh); 391 if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) 392 @@ -1559,6 +1627,7 @@ setup(void) 393 netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); 394 netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); 395 netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); 396 + netatom[NetWMDesktop] = XInternAtom(dpy, "_NET_WM_DESKTOP", False); 397 netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); 398 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 399 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 400 @@ -1616,7 +1685,7 @@ showhide(Client *c) 401 { 402 if (!c) 403 return; 404 - if (ISVISIBLE(c)) { 405 + if (ISVISIBLE(c, c->mon)) { 406 /* show clients top down */ 407 XMoveWindow(dpy, c->win, c->x, c->y); 408 if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) 409 @@ -1656,7 +1725,23 @@ spawn(const Arg *arg) 410 void 411 tag(const Arg *arg) 412 { 413 + Monitor *m; 414 + unsigned int newtags; 415 if (selmon->sel && arg->ui & TAGMASK) { 416 + newtags = arg->ui & TAGMASK; 417 + for (m = mons; m; m = m->next) 418 + /* if tag is visible on another monitor, move client to the new monitor */ 419 + if (m != selmon && m->tagset[m->seltags] & newtags) { 420 + /* prevent moving client to all tags (MODKEY-Shift-0) when multiple monitors are connected */ 421 + if(newtags & selmon->tagset[selmon->seltags]) 422 + return; 423 + selmon->sel->tags = newtags; 424 + selmon->sel->mon = m; 425 + arrange(m); 426 + break; 427 + } 428 + /* workaround in case just one monitor is connected */ 429 + 430 selmon->sel->tags = arg->ui & TAGMASK; 431 focus(NULL); 432 arrange(selmon); 433 @@ -1677,7 +1762,7 @@ tile(Monitor *m) 434 unsigned int i, n, h, mw, my, ty; 435 Client *c; 436 437 - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 438 + for (n = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), n++); 439 if (n == 0) 440 return; 441 442 @@ -1685,7 +1770,7 @@ tile(Monitor *m) 443 mw = m->nmaster ? m->ww * m->mfact : 0; 444 else 445 mw = m->ww; 446 - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 447 + for (i = my = ty = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), i++) 448 if (i < m->nmaster) { 449 h = (m->wh - my) / (MIN(n, m->nmaster) - i); 450 resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); 451 @@ -1725,12 +1810,17 @@ togglefloating(const Arg *arg) 452 void 453 toggletag(const Arg *arg) 454 { 455 + Monitor *m; 456 unsigned int newtags; 457 458 if (!selmon->sel) 459 return; 460 newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 461 if (newtags) { 462 + /* prevent adding tags that are in use on other monitors */ 463 + for (m = mons; m; m = m->next) 464 + if (m != selmon && newtags & m->tagset[m->seltags]) 465 + return; 466 selmon->sel->tags = newtags; 467 focus(NULL); 468 arrange(selmon); 469 @@ -1740,12 +1830,27 @@ toggletag(const Arg *arg) 470 void 471 toggleview(const Arg *arg) 472 { 473 + Monitor *m; 474 unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 475 476 if (newtagset) { 477 + /* prevent displaying the same tags on multiple monitors */ 478 + for(m = mons; m; m = m->next) 479 + if(m != selmon && newtagset & m->tagset[m->seltags]) 480 + return; 481 selmon->tagset[selmon->seltags] = newtagset; 482 - focus(NULL); 483 + attachclients(selmon); 484 arrange(selmon); 485 + focus(NULL); 486 + 487 + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 488 + 489 + if (newtagset) { 490 + selmon->tagset[selmon->seltags] = newtagset; 491 + attachclients(selmon); 492 + arrange(selmon); 493 + focus(NULL); 494 + } 495 } 496 } 497 498 @@ -1844,7 +1949,7 @@ updateclientlist() 499 500 XDeleteProperty(dpy, root, netatom[NetClientList]); 501 for (m = mons; m; m = m->next) 502 - for (c = m->clients; c; c = c->next) 503 + for (c = m->cl->clients; c; c = c->next) 504 XChangeProperty(dpy, root, netatom[NetClientList], 505 XA_WINDOW, 32, PropModeAppend, 506 (unsigned char *) &(c->win), 1); 507 @@ -1874,8 +1979,10 @@ updategeom(void) 508 if (n <= nn) { /* new monitors available */ 509 for (i = 0; i < (nn - n); i++) { 510 for (m = mons; m && m->next; m = m->next); 511 - if (m) 512 + if (m) { 513 m->next = createmon(); 514 + attachclients(m->next); 515 + } 516 else 517 mons = createmon(); 518 } 519 @@ -1895,16 +2002,13 @@ updategeom(void) 520 } else { /* less monitors available nn < n */ 521 for (i = nn; i < n; i++) { 522 for (m = mons; m && m->next; m = m->next); 523 - while ((c = m->clients)) { 524 - dirty = 1; 525 - m->clients = c->next; 526 - detachstack(c); 527 - c->mon = mons; 528 - attach(c); 529 - attachstack(c); 530 - } 531 if (m == selmon) 532 selmon = mons; 533 + for (c = m->cl->clients; c; c = c->next) { 534 + dirty = True; 535 + if (c->mon == m) 536 + c->mon = selmon; 537 + } 538 cleanupmon(m); 539 } 540 } 541 @@ -2016,6 +2120,14 @@ updatewindowtype(Client *c) 542 c->isfloating = 1; 543 } 544 545 +void updatewmdesktop(Window w, int tag) { 546 + long data[] = { tag }; 547 + int i=0; 548 + while(*data >> (i+1)) { i++; } 549 + data[0] = i; 550 + XChangeProperty(dpy, w, netatom[NetWMDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); 551 +} 552 + 553 void 554 updatewmhints(Client *c) 555 { 556 @@ -2038,13 +2150,32 @@ updatewmhints(Client *c) 557 void 558 view(const Arg *arg) 559 { 560 + Monitor *m; 561 + unsigned int newtagset = selmon->tagset[selmon->seltags ^ 1]; 562 if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 563 return; 564 + /* swap tags when trying to display a tag from another monitor */ 565 + if (arg->ui & TAGMASK) 566 + newtagset = arg->ui & TAGMASK; 567 + for (m = mons; m; m = m->next) 568 + if (m != selmon && newtagset & m->tagset[m->seltags]) { 569 + /* prevent displaying all tags (MODKEY-0) when multiple monitors 570 + * are connected */ 571 + if (newtagset & selmon->tagset[selmon->seltags]) 572 + return; 573 + m->sel = selmon->sel; 574 + m->seltags ^= 1; 575 + m->tagset[m->seltags] = selmon->tagset[selmon->seltags]; 576 + attachclients(m); 577 + arrange(m); 578 + break; 579 + } 580 selmon->seltags ^= 1; /* toggle sel tagset */ 581 if (arg->ui & TAGMASK) 582 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 583 - focus(NULL); 584 + attachclients(selmon); 585 arrange(selmon); 586 + focus(NULL); 587 } 588 589 Client * 590 @@ -2054,7 +2185,7 @@ wintoclient(Window w) 591 Monitor *m; 592 593 for (m = mons; m; m = m->next) 594 - for (c = m->clients; c; c = c->next) 595 + for (c = m->cl->clients; c; c = c->next) 596 if (c->win == w) 597 return c; 598 return NULL; 599 @@ -2121,8 +2252,8 @@ zoom(const Arg *arg) 600 if (!selmon->lt[selmon->sellt]->arrange 601 || (selmon->sel && selmon->sel->isfloating)) 602 return; 603 - if (c == nexttiled(selmon->clients)) 604 - if (!c || !(c = nexttiled(c->next))) 605 + if (c == nexttiled(selmon->cl->clients, selmon)) 606 + if (!c || !(c = nexttiled(c->next, selmon))) 607 return; 608 pop(c); 609 } 610 -- 611 2.33.1 612