dwm-6.2-taggrid.diff (8492B)
1 diff --git a/config.def.h b/config.def.h 2 index 1c0b587..2f8f34b 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -21,6 +21,22 @@ static const char *colors[][3] = { 6 /* tagging */ 7 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 8 9 +/* grid of tags */ 10 +#define DRAWCLASSICTAGS 1 << 0 11 +#define DRAWTAGGRID 1 << 1 12 + 13 +#define SWITCHTAG_UP 1 << 0 14 +#define SWITCHTAG_DOWN 1 << 1 15 +#define SWITCHTAG_LEFT 1 << 2 16 +#define SWITCHTAG_RIGHT 1 << 3 17 +#define SWITCHTAG_TOGGLETAG 1 << 4 18 +#define SWITCHTAG_TAG 1 << 5 19 +#define SWITCHTAG_VIEW 1 << 6 20 +#define SWITCHTAG_TOGGLEVIEW 1 << 7 21 + 22 +static const unsigned int drawtagmask = DRAWTAGGRID; /* | DRAWCLASSICTAGS to show classic row of tags */ 23 +static const int tagrows = 2; 24 + 25 static const Rule rules[] = { 26 /* xprop(1): 27 * WM_CLASS(STRING) = instance, class 28 @@ -94,6 +110,16 @@ static Key keys[] = { 29 TAGKEYS( XK_8, 7) 30 TAGKEYS( XK_9, 8) 31 { MODKEY|ShiftMask, XK_q, quit, {0} }, 32 + 33 + { MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } }, 34 + { MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } }, 35 + { MODKEY|ControlMask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_VIEW } }, 36 + { MODKEY|ControlMask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_VIEW } }, 37 + 38 + { MODKEY|Mod4Mask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, 39 + { MODKEY|Mod4Mask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, 40 + { MODKEY|Mod4Mask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, 41 + { MODKEY|Mod4Mask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, 42 }; 43 44 /* button definitions */ 45 diff --git a/dwm.c b/dwm.c 46 index 4465af1..5c29232 100644 47 --- a/dwm.c 48 +++ b/dwm.c 49 @@ -163,6 +163,7 @@ static void detachstack(Client *c); 50 static Monitor *dirtomon(int dir); 51 static void drawbar(Monitor *m); 52 static void drawbars(void); 53 +static void drawtaggrid(Monitor *m, int *x_pos, unsigned int occ); 54 static void enternotify(XEvent *e); 55 static void expose(XEvent *e); 56 static void focus(Client *c); 57 @@ -206,6 +207,7 @@ static void seturgent(Client *c, int urg); 58 static void showhide(Client *c); 59 static void sigchld(int unused); 60 static void spawn(const Arg *arg); 61 +static void switchtag(const Arg *arg); 62 static void tag(const Arg *arg); 63 static void tagmon(const Arg *arg); 64 static void tile(Monitor *); 65 @@ -417,11 +419,13 @@ void 66 buttonpress(XEvent *e) 67 { 68 unsigned int i, x, click; 69 + unsigned int columns; 70 Arg arg = {0}; 71 Client *c; 72 Monitor *m; 73 XButtonPressedEvent *ev = &e->xbutton; 74 75 + columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); 76 click = ClkRootWin; 77 /* focus monitor if necessary */ 78 if ((m = wintomon(ev->window)) && m != selmon) { 79 @@ -431,13 +435,23 @@ buttonpress(XEvent *e) 80 } 81 if (ev->window == selmon->barwin) { 82 i = x = 0; 83 + if (drawtagmask & DRAWCLASSICTAGS) 84 do 85 x += TEXTW(tags[i]); 86 while (ev->x >= x && ++i < LENGTH(tags)); 87 - if (i < LENGTH(tags)) { 88 + if(i < LENGTH(tags) && (drawtagmask & DRAWCLASSICTAGS)) { 89 click = ClkTagBar; 90 arg.ui = 1 << i; 91 - } else if (ev->x < x + blw) 92 + } else if(ev->x < x + columns * bh / tagrows && (drawtagmask & DRAWTAGGRID)) { 93 + click = ClkTagBar; 94 + i = (ev->x - x) / (bh / tagrows); 95 + i = i + columns * (ev->y / (bh / tagrows)); 96 + if (i >= LENGTH(tags)) { 97 + i = LENGTH(tags) - 1; 98 + } 99 + arg.ui = 1 << i; 100 + } 101 + else if(ev->x < x + blw + columns * bh / tagrows) 102 click = ClkLtSymbol; 103 else if (ev->x > selmon->ww - TEXTW(stext)) 104 click = ClkStatusText; 105 @@ -714,6 +728,7 @@ drawbar(Monitor *m) 106 urg |= c->tags; 107 } 108 x = 0; 109 + if (drawtagmask & DRAWCLASSICTAGS) 110 for (i = 0; i < LENGTH(tags); i++) { 111 w = TEXTW(tags[i]); 112 drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 113 @@ -724,6 +739,9 @@ drawbar(Monitor *m) 114 urg & 1 << i); 115 x += w; 116 } 117 + if (drawtagmask & DRAWTAGGRID) { 118 + drawtaggrid(m,&x,occ); 119 + } 120 w = blw = TEXTW(m->ltsymbol); 121 drw_setscheme(drw, scheme[SchemeNorm]); 122 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); 123 @@ -750,6 +768,48 @@ drawbars(void) 124 for (m = mons; m; m = m->next) 125 drawbar(m); 126 } 127 +void drawtaggrid(Monitor *m, int *x_pos, unsigned int occ) 128 +{ 129 + unsigned int x, y, h, max_x, columns; 130 + int invert, i,j, k; 131 + 132 + h = bh / tagrows; 133 + x = max_x = *x_pos; 134 + y = 0; 135 + columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); 136 + 137 + /* Firstly we will fill the borders of squares */ 138 + 139 + XSetForeground(drw->dpy, drw->gc, scheme[SchemeNorm][ColBorder].pixel); 140 + XFillRectangle(dpy, drw->drawable, drw->gc, x, y, h*columns + 1, bh); 141 + 142 + /* We will draw LENGTH(tags) squares in tagraws raws. */ 143 + for(j = 0, i= 0; j < tagrows; j++) { 144 + x = *x_pos; 145 + for (k = 0; k < columns && i < LENGTH(tags); k++, i++) { 146 + invert = m->tagset[m->seltags] & 1 << i ? 0 : 1; 147 + 148 + /* Select active color for current square */ 149 + XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeSel][ColBg].pixel : 150 + scheme[SchemeNorm][ColFg].pixel); 151 + XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h-1); 152 + 153 + /* Mark square if tag has client */ 154 + if (occ & 1 << i) { 155 + XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeSel][ColFg].pixel : 156 + scheme[SchemeNorm][ColBg].pixel); 157 + XFillRectangle(dpy, drw->drawable, drw->gc, x + 1, y + 1, 158 + h / 2, h / 2); 159 + } 160 + x += h; 161 + if (x > max_x) { 162 + max_x = x; 163 + } 164 + } 165 + y += h; 166 + } 167 + *x_pos = max_x + 1; 168 +} 169 170 void 171 enternotify(XEvent *e) 172 @@ -1627,6 +1687,81 @@ showhide(Client *c) 173 XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); 174 } 175 } 176 +void switchtag(const Arg *arg) 177 +{ 178 + unsigned int columns; 179 + unsigned int new_tagset = 0; 180 + unsigned int pos, i; 181 + int col, row; 182 + Arg new_arg; 183 + 184 + columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); 185 + 186 + for (i = 0; i < LENGTH(tags); ++i) { 187 + if (!(selmon->tagset[selmon->seltags] & 1 << i)) { 188 + continue; 189 + } 190 + pos = i; 191 + row = pos / columns; 192 + col = pos % columns; 193 + if (arg->ui & SWITCHTAG_UP) { /* UP */ 194 + row --; 195 + if (row < 0) { 196 + row = tagrows - 1; 197 + } 198 + do { 199 + pos = row * columns + col; 200 + row --; 201 + } while (pos >= LENGTH(tags)); 202 + } 203 + if (arg->ui & SWITCHTAG_DOWN) { /* DOWN */ 204 + row ++; 205 + if (row >= tagrows) { 206 + row = 0; 207 + } 208 + pos = row * columns + col; 209 + if (pos >= LENGTH(tags)) { 210 + row = 0; 211 + } 212 + pos = row * columns + col; 213 + } 214 + if (arg->ui & SWITCHTAG_LEFT) { /* LEFT */ 215 + col --; 216 + if (col < 0) { 217 + col = columns - 1; 218 + } 219 + do { 220 + pos = row * columns + col; 221 + col --; 222 + } while (pos >= LENGTH(tags)); 223 + } 224 + if (arg->ui & SWITCHTAG_RIGHT) { /* RIGHT */ 225 + col ++; 226 + if (col >= columns) { 227 + col = 0; 228 + } 229 + pos = row * columns + col; 230 + if (pos >= LENGTH(tags)) { 231 + col = 0; 232 + pos = row * columns + col; 233 + } 234 + } 235 + new_tagset |= 1 << pos; 236 + } 237 + new_arg.ui = new_tagset; 238 + if (arg->ui & SWITCHTAG_TOGGLETAG) { 239 + toggletag(&new_arg); 240 + } 241 + if (arg->ui & SWITCHTAG_TAG) { 242 + tag(&new_arg); 243 + } 244 + if (arg->ui & SWITCHTAG_VIEW) { 245 + view (&new_arg); 246 + } 247 + if (arg->ui & SWITCHTAG_TOGGLEVIEW) { 248 + toggleview (&new_arg); 249 + } 250 +} 251 252 void 253 sigchld(int unused)