implemented restack behavior (floats are on top in tiled mode)
d4b7a9a3
6 file(s) · +81 −34
| 59 | 59 | drawtitle(old); |
|
| 60 | 60 | drawtitle(c); |
|
| 61 | 61 | XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
|
| 62 | - | XSync(dpy, False); |
|
| 63 | - | while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
|
| 64 | 62 | } |
|
| 65 | 63 | ||
| 66 | 64 | void |
|
| 77 | 75 | if(!(c = getnext(sel->next))) |
|
| 78 | 76 | c = getnext(clients); |
|
| 79 | 77 | if(c) { |
|
| 80 | - | higher(c); |
|
| 81 | 78 | focus(c); |
|
| 79 | + | restack(); |
|
| 82 | 80 | } |
|
| 83 | 81 | } |
|
| 84 | 82 | ||
| 98 | 96 | c = getprev(c); |
|
| 99 | 97 | } |
|
| 100 | 98 | if(c) { |
|
| 101 | - | higher(c); |
|
| 102 | 99 | focus(c); |
|
| 100 | + | restack(); |
|
| 103 | 101 | } |
|
| 104 | 102 | } |
|
| 105 | 103 | ||
| 178 | 176 | } |
|
| 179 | 177 | c->x += dx; |
|
| 180 | 178 | c->y += dy; |
|
| 181 | - | } |
|
| 182 | - | ||
| 183 | - | void |
|
| 184 | - | higher(Client *c) |
|
| 185 | - | { |
|
| 186 | - | XRaiseWindow(dpy, c->win); |
|
| 187 | - | XRaiseWindow(dpy, c->title); |
|
| 188 | 179 | } |
|
| 189 | 180 | ||
| 190 | 181 | void |
|
| 271 | 262 | || (c->maxw && c->minw && |
|
| 272 | 263 | c->maxw == c->minw && c->maxh == c->minh); |
|
| 273 | 264 | settitle(c); |
|
| 274 | - | arrange(NULL); |
|
| 275 | 265 | ||
| 276 | - | /* mapping the window now prevents flicker */ |
|
| 277 | - | XMapRaised(dpy, c->win); |
|
| 278 | - | XMapRaised(dpy, c->title); |
|
| 266 | + | XMapWindow(dpy, c->win); |
|
| 267 | + | XMapWindow(dpy, c->title); |
|
| 279 | 268 | if(isvisible(c)) |
|
| 280 | 269 | focus(c); |
|
| 270 | + | arrange(NULL); |
|
| 281 | 271 | } |
|
| 282 | 272 | ||
| 283 | 273 | void |
|
| 410 | 400 | sel->w = sw - 2; |
|
| 411 | 401 | sel->h = sh - 2 - bh; |
|
| 412 | 402 | ||
| 413 | - | higher(sel); |
|
| 403 | + | restack(); |
|
| 414 | 404 | resize(sel, arrange == dofloat, TopLeft); |
|
| 415 | 405 | ||
| 416 | 406 | sel->x = ox; |
|
| 446 | 436 | XSync(dpy, False); |
|
| 447 | 437 | XSetErrorHandler(xerror); |
|
| 448 | 438 | XUngrabServer(dpy); |
|
| 449 | - | arrange(NULL); |
|
| 450 | 439 | if(sel) |
|
| 451 | 440 | focus(sel); |
|
| 441 | + | arrange(NULL); |
|
| 452 | 442 | } |
|
| 453 | 443 | ||
| 454 | 444 | void |
|
| 474 | 464 | clients->prev = sel; |
|
| 475 | 465 | sel->next = clients; |
|
| 476 | 466 | clients = sel; |
|
| 477 | - | arrange(NULL); |
|
| 478 | 467 | focus(sel); |
|
| 468 | + | arrange(NULL); |
|
| 479 | 469 | } |
|
| 36 | 36 | .B Standard input |
|
| 37 | 37 | is read and displayed in the status text area. |
|
| 38 | 38 | .TP |
|
| 39 | - | .B Button[1,3] |
|
| 39 | + | .B Button[1,2] |
|
| 40 | 40 | click on a tag label focuses that |
|
| 41 | 41 | .B tag. |
|
| 42 | 42 | .TP |
|
| 43 | - | .B Button2 |
|
| 43 | + | .B Button3 |
|
| 44 | 44 | click on a tag label toggles that |
|
| 45 | 45 | .B tag. |
|
| 46 | 46 | .SS Keyboard commands |
| 89 | 89 | extern Client *getclient(Window w); |
|
| 90 | 90 | extern Client *getctitle(Window w); |
|
| 91 | 91 | extern void gravitate(Client *c, Bool invert); |
|
| 92 | - | extern void higher(Client *c); |
|
| 93 | 92 | extern void killclient(Arg *arg); |
|
| 94 | 93 | extern void manage(Window w, XWindowAttributes *wa); |
|
| 95 | 94 | extern void resize(Client *c, Bool sizehints, Corner sticky); |
|
| 125 | 124 | extern Client *getnext(Client *c); |
|
| 126 | 125 | extern Client *getprev(Client *c); |
|
| 127 | 126 | extern void replacetag(Arg *arg); |
|
| 127 | + | extern void restack(); |
|
| 128 | 128 | extern void settags(Client *c); |
|
| 129 | 129 | extern void togglemode(Arg *arg); |
|
| 130 | 130 | extern void view(Arg *arg); |
|
| 133 | 133 | /* util.c */ |
|
| 134 | 134 | extern void *emallocz(unsigned int size); |
|
| 135 | 135 | extern void eprint(const char *errstr, ...); |
|
| 136 | + | extern void *erealloc(void *ptr, unsigned int size); |
|
| 136 | 137 | extern void spawn(Arg *arg); |
|
| 118 | 118 | } |
|
| 119 | 119 | } |
|
| 120 | 120 | else if((c = getclient(ev->window))) { |
|
| 121 | - | higher(c); |
|
| 122 | 121 | focus(c); |
|
| 123 | 122 | switch(ev->button) { |
|
| 124 | 123 | default: |
|
| 125 | 124 | break; |
|
| 126 | 125 | case Button1: |
|
| 127 | - | if(!c->ismax && (arrange == dofloat || c->isfloat)) |
|
| 126 | + | if(!c->ismax && (arrange == dofloat || c->isfloat)) { |
|
| 127 | + | restack(c); |
|
| 128 | 128 | movemouse(c); |
|
| 129 | + | } |
|
| 129 | 130 | break; |
|
| 130 | 131 | case Button2: |
|
| 131 | 132 | zoom(NULL); |
|
| 132 | 133 | break; |
|
| 133 | 134 | case Button3: |
|
| 134 | - | if(!c->ismax && (arrange == dofloat || c->isfloat)) |
|
| 135 | + | if(!c->ismax && (arrange == dofloat || c->isfloat)) { |
|
| 136 | + | restack(c); |
|
| 135 | 137 | resizemouse(c); |
|
| 138 | + | } |
|
| 136 | 139 | break; |
|
| 137 | 140 | } |
|
| 138 | 141 | } |
| 58 | 58 | ban(c); |
|
| 59 | 59 | } |
|
| 60 | 60 | if((sel = getnext(clients))) { |
|
| 61 | - | higher(sel); |
|
| 62 | 61 | focus(sel); |
|
| 62 | + | restack(); |
|
| 63 | 63 | } |
|
| 64 | 64 | else |
|
| 65 | 65 | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
|
| 66 | - | drawall(); |
|
| 67 | 66 | } |
|
| 68 | 67 | ||
| 69 | 68 | void |
|
| 70 | 69 | dotile(Arg *arg) |
|
| 71 | 70 | { |
|
| 72 | - | int n, i, w, h; |
|
| 71 | + | int h, i, n, w; |
|
| 73 | 72 | Client *c; |
|
| 74 | 73 | ||
| 75 | 74 | w = sw - mw; |
|
| 86 | 85 | c->ismax = False; |
|
| 87 | 86 | if(isvisible(c)) { |
|
| 88 | 87 | if(c->isfloat) { |
|
| 89 | - | higher(c); |
|
| 90 | 88 | resize(c, True, TopLeft); |
|
| 91 | 89 | continue; |
|
| 92 | 90 | } |
|
| 123 | 121 | else |
|
| 124 | 122 | ban(c); |
|
| 125 | 123 | } |
|
| 126 | - | if((sel = getnext(clients))) { |
|
| 127 | - | higher(sel); |
|
| 124 | + | if((sel = getnext(clients))) |
|
| 128 | 125 | focus(sel); |
|
| 129 | - | } |
|
| 130 | 126 | else |
|
| 131 | 127 | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
|
| 132 | - | drawall(); |
|
| 128 | + | restack(); |
|
| 133 | 129 | } |
|
| 134 | 130 | ||
| 135 | 131 | Client * |
|
| 200 | 196 | } |
|
| 201 | 197 | ||
| 202 | 198 | void |
|
| 199 | + | restack() |
|
| 200 | + | { |
|
| 201 | + | static unsigned int nwins = 0; |
|
| 202 | + | static Window *wins = NULL; |
|
| 203 | + | unsigned int f, fi, m, mi, n; |
|
| 204 | + | Client *c; |
|
| 205 | + | XEvent ev; |
|
| 206 | + | ||
| 207 | + | for(f = 0, m = 0, c = clients; c; c = c->next) |
|
| 208 | + | if(isvisible(c)) { |
|
| 209 | + | if(c->isfloat || arrange == dofloat) |
|
| 210 | + | f++; |
|
| 211 | + | else |
|
| 212 | + | m++; |
|
| 213 | + | } |
|
| 214 | + | ||
| 215 | + | n = 2 * (f + m); |
|
| 216 | + | if(nwins < n) { |
|
| 217 | + | nwins = n; |
|
| 218 | + | wins = erealloc(wins, nwins * sizeof(Window)); |
|
| 219 | + | } |
|
| 220 | + | ||
| 221 | + | fi = 0; |
|
| 222 | + | mi = 2 * f; |
|
| 223 | + | if(sel->isfloat || arrange == dofloat) { |
|
| 224 | + | wins[fi++] = sel->title; |
|
| 225 | + | wins[fi++] = sel->win; |
|
| 226 | + | } |
|
| 227 | + | else { |
|
| 228 | + | wins[mi++] = sel->title; |
|
| 229 | + | wins[mi++] = sel->win; |
|
| 230 | + | } |
|
| 231 | + | for(c = clients; c; c = c->next) |
|
| 232 | + | if(isvisible(c) && c != sel) { |
|
| 233 | + | if(c->isfloat || arrange == dofloat) { |
|
| 234 | + | wins[fi++] = c->title; |
|
| 235 | + | wins[fi++] = c->win; |
|
| 236 | + | } |
|
| 237 | + | else { |
|
| 238 | + | wins[mi++] = c->title; |
|
| 239 | + | wins[mi++] = c->win; |
|
| 240 | + | } |
|
| 241 | + | } |
|
| 242 | + | XRestackWindows(dpy, wins, n); |
|
| 243 | + | drawall(); |
|
| 244 | + | XSync(dpy, False); |
|
| 245 | + | while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
|
| 246 | + | } |
|
| 247 | + | ||
| 248 | + | void |
|
| 203 | 249 | settags(Client *c) |
|
| 204 | 250 | { |
|
| 205 | 251 | char classinst[256]; |
|
| 248 | 294 | seltag[i] = False; |
|
| 249 | 295 | seltag[arg->i] = True; |
|
| 250 | 296 | arrange(NULL); |
|
| 251 | - | drawall(); |
|
| 252 | 297 | } |
|
| 253 | 298 | ||
| 254 | 299 | void |
|
| 261 | 306 | if(i == ntags) |
|
| 262 | 307 | seltag[arg->i] = True; /* cannot toggle last view */ |
|
| 263 | 308 | arrange(NULL); |
|
| 264 | - | drawall(); |
|
| 265 | 309 | } |
|
| 40 | 40 | exit(EXIT_FAILURE); |
|
| 41 | 41 | } |
|
| 42 | 42 | ||
| 43 | + | void * |
|
| 44 | + | erealloc(void *ptr, unsigned int size) |
|
| 45 | + | { |
|
| 46 | + | void *res = realloc(ptr, size); |
|
| 47 | + | if(!res) |
|
| 48 | + | bad_malloc(size); |
|
| 49 | + | return res; |
|
| 50 | + | } |
|
| 51 | + | ||
| 43 | 52 | void |
|
| 44 | 53 | spawn(Arg *arg) |
|
| 45 | 54 | { |