applied Sanders all5.patch (thanks for your weekend session, Sander!)
b2330898
5 file(s) · +63 −71
| 79 | 79 | ||
| 80 | 80 | void |
|
| 81 | 81 | focus(Client *c) { |
|
| 82 | - | Client *old; |
|
| 82 | + | Client *old = sel; |
|
| 83 | 83 | ||
| 84 | 84 | if(!issel || (c && !isvisible(c))) |
|
| 85 | 85 | return; |
|
| 86 | - | if(!sel) |
|
| 87 | - | sel = c; |
|
| 88 | - | else if(sel != c) { |
|
| 89 | - | old = sel; |
|
| 90 | - | sel = c; |
|
| 91 | - | if(old) { |
|
| 92 | - | grabbuttons(old, False); |
|
| 93 | - | XSetWindowBorder(dpy, old->win, dc.norm[ColBorder]); |
|
| 94 | - | } |
|
| 86 | + | ||
| 87 | + | if(old && old != c) { |
|
| 88 | + | grabbuttons(old, False); |
|
| 89 | + | XSetWindowBorder(dpy, old->win, dc.norm[ColBorder]); |
|
| 95 | 90 | } |
|
| 96 | 91 | if(c) { |
|
| 97 | 92 | detachstack(c); |
|
| 103 | 98 | } |
|
| 104 | 99 | else |
|
| 105 | 100 | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
|
| 101 | + | sel = c; |
|
| 106 | 102 | drawstatus(); |
|
| 107 | 103 | } |
|
| 108 | 104 | ||
| 134 | 130 | c = emallocz(sizeof(Client)); |
|
| 135 | 131 | c->tags = emallocz(ntags * sizeof(Bool)); |
|
| 136 | 132 | c->win = w; |
|
| 137 | - | c->border = 0; |
|
| 138 | 133 | c->x = wa->x; |
|
| 139 | 134 | c->y = wa->y; |
|
| 140 | 135 | c->w = wa->width; |
|
| 141 | 136 | c->h = wa->height; |
|
| 142 | - | updatesizehints(c); |
|
| 143 | - | if(c->x + c->w + 2 * BORDERPX > sw) |
|
| 144 | - | c->x = sw - c->w - 2 * BORDERPX; |
|
| 145 | - | if(c->x < sx) |
|
| 137 | + | if(c->w == sw && c->h == sh) { |
|
| 138 | + | c->border = 0; |
|
| 146 | 139 | c->x = sx; |
|
| 147 | - | if(c->y + c->h + 2 * BORDERPX > sh) |
|
| 148 | - | c->y = sh - c->h - 2 * BORDERPX; |
|
| 149 | - | if(c->h != sh && c->y < bh) |
|
| 150 | - | c->y = bh; |
|
| 140 | + | c->y = sy; |
|
| 141 | + | } |
|
| 142 | + | else { |
|
| 143 | + | c->border = BORDERPX; |
|
| 144 | + | if(c->x < wax) |
|
| 145 | + | c->x = wax; |
|
| 146 | + | if(c->y < way) |
|
| 147 | + | c->y = way; |
|
| 148 | + | if(c->x + c->w + 2 * c->border > wax + waw) |
|
| 149 | + | c->x = wax + waw - c->w - 2 * c->border; |
|
| 150 | + | if(c->y + c->h + 2 * c->border > way + wah) |
|
| 151 | + | c->y = way + wah - c->h - 2 * c->border; |
|
| 152 | + | } |
|
| 153 | + | updatesizehints(c); |
|
| 151 | 154 | c->proto = getproto(c->win); |
|
| 152 | 155 | XSelectInput(dpy, c->win, |
|
| 153 | 156 | StructureNotifyMask | PropertyChangeMask | EnterWindowMask); |
|
| 170 | 173 | } |
|
| 171 | 174 | ||
| 172 | 175 | void |
|
| 173 | - | resize(Client *c, Bool sizehints, Corner sticky) { |
|
| 174 | - | int bottom = c->y + c->h; |
|
| 175 | - | int right = c->x + c->w; |
|
| 176 | + | resize(Client *c, Bool sizehints) { |
|
| 176 | 177 | XWindowChanges wc; |
|
| 177 | 178 | ||
| 178 | 179 | if(sizehints) { |
|
| 189 | 190 | if(c->maxh && c->h > c->maxh) |
|
| 190 | 191 | c->h = c->maxh; |
|
| 191 | 192 | } |
|
| 192 | - | if(sticky == TopRight || sticky == BotRight) |
|
| 193 | - | c->x = right - c->w; |
|
| 194 | - | if(sticky == BotLeft || sticky == BotRight) |
|
| 195 | - | c->y = bottom - c->h; |
|
| 193 | + | if(c->w == sw && c->h == sh) |
|
| 194 | + | c->border = 0; |
|
| 195 | + | else |
|
| 196 | + | c->border = BORDERPX; |
|
| 196 | 197 | /* offscreen appearance fixes */ |
|
| 197 | - | if(c->x + c->w < sx) |
|
| 198 | + | if(c->x + c->w + 2 * c->border < sx) |
|
| 198 | 199 | c->x = sx; |
|
| 199 | - | if(c->y + c->h < bh) |
|
| 200 | - | c->y = bh; |
|
| 200 | + | if(c->y + c->h + 2 * c->border < sy) |
|
| 201 | + | c->y = sy; |
|
| 201 | 202 | if(c->x > sw) |
|
| 202 | - | c->x = sw - c->w; |
|
| 203 | + | c->x = sw - c->w - 2 * c->border; |
|
| 203 | 204 | if(c->y > sh) |
|
| 204 | - | c->y = sh - c->h; |
|
| 205 | + | c->y = sh - c->h - 2 * c->border; |
|
| 205 | 206 | wc.x = c->x; |
|
| 206 | 207 | wc.y = c->y; |
|
| 207 | 208 | wc.width = c->w; |
|
| 208 | 209 | wc.height = c->h; |
|
| 209 | - | if(c->w == sw && c->h == sh) |
|
| 210 | - | wc.border_width = 0; |
|
| 211 | - | else |
|
| 212 | - | wc.border_width = BORDERPX; |
|
| 210 | + | wc.border_width = c->border; |
|
| 213 | 211 | XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); |
|
| 214 | 212 | configure(c); |
|
| 215 | 213 | XSync(dpy, False); |
|
| 44 | 44 | enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
|
| 45 | 45 | enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ |
|
| 46 | 46 | ||
| 47 | - | typedef enum { |
|
| 48 | - | TopLeft, TopRight, BotLeft, BotRight |
|
| 49 | - | } Corner; /* window corners */ |
|
| 50 | - | ||
| 51 | 47 | typedef union { |
|
| 52 | 48 | const char *cmd; |
|
| 53 | 49 | int i; |
|
| 110 | 106 | extern Client *getclient(Window w); /* return client of w */ |
|
| 111 | 107 | extern void killclient(Arg *arg); /* kill c nicely */ |
|
| 112 | 108 | extern void manage(Window w, XWindowAttributes *wa); /* manage new client */ |
|
| 113 | - | extern void resize(Client *c, Bool sizehints, Corner sticky); /* resize c*/ |
|
| 109 | + | extern void resize(Client *c, Bool sizehints); /* resize c*/ |
|
| 114 | 110 | extern void updatesizehints(Client *c); /* update the size hint variables of c */ |
|
| 115 | 111 | extern void updatetitle(Client *c); /* update the name of c */ |
|
| 116 | 112 | extern void unmanage(Client *c); /* destroy c */ |
|
| 35 | 35 | c->ismax = False; |
|
| 36 | 36 | XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); |
|
| 37 | 37 | for(;;) { |
|
| 38 | - | XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev); |
|
| 38 | + | XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); |
|
| 39 | 39 | switch (ev.type) { |
|
| 40 | 40 | case ButtonRelease: |
|
| 41 | - | resize(c, True, TopLeft); |
|
| 41 | + | resize(c, True); |
|
| 42 | 42 | XUngrabPointer(dpy, CurrentTime); |
|
| 43 | 43 | return; |
|
| 44 | + | case ConfigureRequest: |
|
| 44 | 45 | case Expose: |
|
| 45 | - | handler[Expose](&ev); |
|
| 46 | + | case MapRequest: |
|
| 47 | + | handler[ev.type](&ev); |
|
| 46 | 48 | break; |
|
| 47 | 49 | case MotionNotify: |
|
| 48 | 50 | XSync(dpy, False); |
|
| 50 | 52 | c->y = ocy + (ev.xmotion.y - y1); |
|
| 51 | 53 | if(abs(wax + c->x) < SNAP) |
|
| 52 | 54 | c->x = wax; |
|
| 53 | - | else if(abs((wax + waw) - (c->x + c->w)) < SNAP) |
|
| 54 | - | c->x = wax + waw - c->w - 2 * BORDERPX; |
|
| 55 | + | else if(abs((wax + waw) - (c->x + c->w + 2 * c->border)) < SNAP) |
|
| 56 | + | c->x = wax + waw - c->w - 2 * c->border; |
|
| 55 | 57 | if(abs(way - c->y) < SNAP) |
|
| 56 | 58 | c->y = way; |
|
| 57 | - | else if(abs((way + wah) - (c->y + c->h)) < SNAP) |
|
| 58 | - | c->y = way + wah - c->h - 2 * BORDERPX; |
|
| 59 | - | resize(c, False, TopLeft); |
|
| 59 | + | else if(abs((way + wah) - (c->y + c->h + 2 * c->border)) < SNAP) |
|
| 60 | + | c->y = way + wah - c->h - 2 * c->border; |
|
| 61 | + | resize(c, False); |
|
| 60 | 62 | break; |
|
| 61 | 63 | } |
|
| 62 | 64 | } |
|
| 66 | 68 | resizemouse(Client *c) { |
|
| 67 | 69 | int ocx, ocy; |
|
| 68 | 70 | int nw, nh; |
|
| 69 | - | Corner sticky; |
|
| 70 | 71 | XEvent ev; |
|
| 71 | 72 | ||
| 72 | 73 | ocx = c->x; |
|
| 75 | 76 | None, cursor[CurResize], CurrentTime) != GrabSuccess) |
|
| 76 | 77 | return; |
|
| 77 | 78 | c->ismax = False; |
|
| 78 | - | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); |
|
| 79 | + | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); |
|
| 79 | 80 | for(;;) { |
|
| 80 | - | XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev); |
|
| 81 | + | XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev); |
|
| 81 | 82 | switch(ev.type) { |
|
| 82 | 83 | case ButtonRelease: |
|
| 83 | - | resize(c, True, TopLeft); |
|
| 84 | + | resize(c, True); |
|
| 84 | 85 | XUngrabPointer(dpy, CurrentTime); |
|
| 85 | 86 | return; |
|
| 87 | + | case ConfigureRequest: |
|
| 86 | 88 | case Expose: |
|
| 87 | - | handler[Expose](&ev); |
|
| 89 | + | case MapRequest: |
|
| 90 | + | handler[ev.type](&ev); |
|
| 88 | 91 | break; |
|
| 89 | 92 | case MotionNotify: |
|
| 90 | 93 | XSync(dpy, False); |
|
| 91 | - | if((nw = abs(ocx - ev.xmotion.x))) |
|
| 92 | - | c->w = nw; |
|
| 93 | - | if((nh = abs(ocy - ev.xmotion.y))) |
|
| 94 | - | c->h = nh; |
|
| 95 | - | c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; |
|
| 96 | - | c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; |
|
| 97 | - | if(ocx <= ev.xmotion.x) |
|
| 98 | - | sticky = (ocy <= ev.xmotion.y) ? TopLeft : BotLeft; |
|
| 99 | - | else |
|
| 100 | - | sticky = (ocy <= ev.xmotion.y) ? TopRight : BotRight; |
|
| 101 | - | resize(c, True, sticky); |
|
| 94 | + | nw = ev.xmotion.x - ocx - 2 * c->border + 1; |
|
| 95 | + | c->w = nw > 0 ? nw : 1; |
|
| 96 | + | nh = ev.xmotion.y - ocy - 2 * c->border + 1; |
|
| 97 | + | c->h = nh > 0 ? nh : 1; |
|
| 98 | + | resize(c, True); |
|
| 102 | 99 | break; |
|
| 103 | 100 | } |
|
| 104 | 101 | } |
|
| 194 | 191 | configure(c); |
|
| 195 | 192 | XSync(dpy, False); |
|
| 196 | 193 | if(c->isfloat) { |
|
| 197 | - | resize(c, False, TopLeft); |
|
| 194 | + | resize(c, False); |
|
| 198 | 195 | if(!isvisible(c)) |
|
| 199 | 196 | XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); |
|
| 200 | 197 | } |
|
| 234 | 231 | focus(c); |
|
| 235 | 232 | else if(ev->window == root) { |
|
| 236 | 233 | issel = True; |
|
| 237 | - | focus(sel); |
|
| 234 | + | for(c = stack; c && !isvisible(c); c = c->snext); |
|
| 235 | + | focus(c); |
|
| 238 | 236 | } |
|
| 239 | 237 | } |
|
| 240 | 238 | ||
| 41 | 41 | cleanup(void) { |
|
| 42 | 42 | close(STDIN_FILENO); |
|
| 43 | 43 | while(stack) { |
|
| 44 | - | resize(stack, True, TopLeft); |
|
| 44 | + | resize(stack, True); |
|
| 45 | 45 | unmanage(stack); |
|
| 46 | 46 | } |
|
| 47 | 47 | if(dc.font.set) |
| 31 | 31 | c->w = c->rw; |
|
| 32 | 32 | c->h = c->rh; |
|
| 33 | 33 | } |
|
| 34 | - | resize(c, True, TopLeft); |
|
| 34 | + | resize(c, True); |
|
| 35 | 35 | while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
|
| 36 | 36 | } |
|
| 37 | 37 | ||
| 56 | 56 | ||
| 57 | 57 | for(c = clients; c; c = c->next) { |
|
| 58 | 58 | if(isvisible(c)) { |
|
| 59 | - | resize(c, True, TopLeft); |
|
| 59 | + | resize(c, True); |
|
| 60 | 60 | } |
|
| 61 | 61 | else |
|
| 62 | 62 | XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); |
|
| 84 | 84 | for(i = 0, c = clients; c; c = c->next) |
|
| 85 | 85 | if(isvisible(c)) { |
|
| 86 | 86 | if(c->isfloat) { |
|
| 87 | - | resize(c, True, TopLeft); |
|
| 87 | + | resize(c, True); |
|
| 88 | 88 | continue; |
|
| 89 | 89 | } |
|
| 90 | 90 | c->ismax = False; |
|
| 105 | 105 | else /* fallback if th < bh */ |
|
| 106 | 106 | c->h = wah - 2 * BORDERPX; |
|
| 107 | 107 | } |
|
| 108 | - | resize(c, False, TopLeft); |
|
| 108 | + | resize(c, False); |
|
| 109 | 109 | i++; |
|
| 110 | 110 | } |
|
| 111 | 111 | else |
|