1 diff --git a/dwm.c b/dwm.c 2 index 664c527..ac8e4ec 100644 3 --- a/dwm.c 4 +++ b/dwm.c 5 @@ -111,6 +111,7 @@ typedef struct { 6 void (*arrange)(Monitor *); 7 } Layout; 8 9 +typedef struct Pertag Pertag; 10 struct Monitor { 11 char ltsymbol[16]; 12 float mfact; 13 @@ -130,6 +131,7 @@ struct Monitor { 14 Monitor *next; 15 Window barwin; 16 const Layout *lt[2]; 17 + Pertag *pertag; 18 }; 19 20 typedef struct { 21 @@ -272,6 +274,15 @@ static Window root, wmcheckwin; 22 /* configuration, allows nested code to access above variables */ 23 #include "config.h" 24 25 +struct Pertag { 26 + unsigned int curtag, prevtag; /* current and previous tag */ 27 + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ 28 + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ 29 + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ 30 + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ 31 + int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ 32 +}; 33 + 34 /* compile-time check if all tags fit into an unsigned int bit array. */ 35 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 36 37 @@ -632,6 +643,7 @@ Monitor * 38 createmon(void) 39 { 40 Monitor *m; 41 + unsigned int i; 42 43 m = ecalloc(1, sizeof(Monitor)); 44 m->tagset[0] = m->tagset[1] = 1; 45 @@ -642,6 +654,20 @@ createmon(void) 46 m->lt[0] = &layouts[0]; 47 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 48 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 49 + m->pertag = ecalloc(1, sizeof(Pertag)); 50 + m->pertag->curtag = m->pertag->prevtag = 1; 51 + 52 + for (i = 0; i <= LENGTH(tags); i++) { 53 + m->pertag->nmasters[i] = m->nmaster; 54 + m->pertag->mfacts[i] = m->mfact; 55 + 56 + m->pertag->ltidxs[i][0] = m->lt[0]; 57 + m->pertag->ltidxs[i][1] = m->lt[1]; 58 + m->pertag->sellts[i] = m->sellt; 59 + 60 + m->pertag->showbars[i] = m->showbar; 61 + } 62 + 63 return m; 64 } 65 66 @@ -967,7 +993,7 @@ grabkeys(void) 67 void 68 incnmaster(const Arg *arg) 69 { 70 - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 71 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); 72 arrange(selmon); 73 } 74 75 @@ -1502,9 +1528,9 @@ void 76 setlayout(const Arg *arg) 77 { 78 if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 79 - selmon->sellt ^= 1; 80 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; 81 if (arg && arg->v) 82 - selmon->lt[selmon->sellt] = (Layout *)arg->v; 83 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; 84 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 85 if (selmon->sel) 86 arrange(selmon); 87 @@ -1523,7 +1549,7 @@ setmfact(const Arg *arg) 88 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 89 if (f < 0.05 || f > 0.95) 90 return; 91 - selmon->mfact = f; 92 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; 93 arrange(selmon); 94 } 95 96 @@ -1702,7 +1728,7 @@ tile(Monitor *m) 97 void 98 togglebar(const Arg *arg) 99 { 100 - selmon->showbar = !selmon->showbar; 101 + selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; 102 updatebarpos(selmon); 103 XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 104 arrange(selmon); 105 @@ -1741,9 +1767,33 @@ void 106 toggleview(const Arg *arg) 107 { 108 unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 109 + int i; 110 111 if (newtagset) { 112 selmon->tagset[selmon->seltags] = newtagset; 113 + 114 + if (newtagset == ~0) { 115 + selmon->pertag->prevtag = selmon->pertag->curtag; 116 + selmon->pertag->curtag = 0; 117 + } 118 + 119 + /* test if the user did not select the same tag */ 120 + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { 121 + selmon->pertag->prevtag = selmon->pertag->curtag; 122 + for (i = 0; !(newtagset & 1 << i); i++) ; 123 + selmon->pertag->curtag = i + 1; 124 + } 125 + 126 + /* apply settings for this view */ 127 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 128 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 129 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 130 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 131 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 132 + 133 + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) 134 + togglebar(NULL); 135 + 136 focus(NULL); 137 arrange(selmon); 138 } 139 @@ -2038,11 +2088,37 @@ updatewmhints(Client *c) 140 void 141 view(const Arg *arg) 142 { 143 + int i; 144 + unsigned int tmptag; 145 + 146 if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 147 return; 148 selmon->seltags ^= 1; /* toggle sel tagset */ 149 - if (arg->ui & TAGMASK) 150 + if (arg->ui & TAGMASK) { 151 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 152 + selmon->pertag->prevtag = selmon->pertag->curtag; 153 + 154 + if (arg->ui == ~0) 155 + selmon->pertag->curtag = 0; 156 + else { 157 + for (i = 0; !(arg->ui & 1 << i); i++) ; 158 + selmon->pertag->curtag = i + 1; 159 + } 160 + } else { 161 + tmptag = selmon->pertag->prevtag; 162 + selmon->pertag->prevtag = selmon->pertag->curtag; 163 + selmon->pertag->curtag = tmptag; 164 + } 165 + 166 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 167 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 168 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 169 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 170 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 171 + 172 + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) 173 + togglebar(NULL); 174 + 175 focus(NULL); 176 arrange(selmon); 177 }