| 17 |
17 |
|
* set the override_redirect flag. Clients are organized in a global |
| 18 |
18 |
|
* doubly-linked client list, the focus history is remembered through a global |
| 19 |
19 |
|
* stack list. Each client contains an array of Bools of the same size as the |
| 20 |
|
- |
* global tags array to indicate the tags of a client. |
|
20 |
+ |
* global tags array to indicate the tags of a client. |
| 21 |
21 |
|
* |
| 22 |
22 |
|
* Keys and tagging rules are organized as arrays and defined in config.h. |
| 23 |
23 |
|
* |
|
| 45 |
45 |
|
//#endif |
| 46 |
46 |
|
|
| 47 |
47 |
|
/* macros */ |
| 48 |
|
- |
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) |
| 49 |
|
- |
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) |
|
48 |
+ |
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) |
|
49 |
+ |
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask)) |
| 50 |
50 |
|
#define LENGTH(x) (sizeof x / sizeof x[0]) |
| 51 |
51 |
|
#define MAXTAGLEN 16 |
| 52 |
|
- |
#define MOUSEMASK (BUTTONMASK | PointerMotionMask) |
|
52 |
+ |
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) |
| 53 |
53 |
|
|
| 54 |
54 |
|
|
| 55 |
55 |
|
/* enums */ |
|
| 60 |
60 |
|
enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */ |
| 61 |
61 |
|
|
| 62 |
62 |
|
/* typedefs */ |
| 63 |
|
- |
typedef struct Monitor Monitor; |
|
63 |
+ |
typedef struct View View; |
| 64 |
64 |
|
typedef struct Client Client; |
| 65 |
65 |
|
struct Client { |
| 66 |
66 |
|
char name[256]; |
| 67 |
67 |
|
int x, y, w, h; |
| 68 |
68 |
|
int basew, baseh, incw, inch, maxw, maxh, minw, minh; |
| 69 |
69 |
|
int minax, maxax, minay, maxay; |
|
70 |
+ |
int *tags; |
| 70 |
71 |
|
long flags; |
| 71 |
72 |
|
unsigned int border, oldborder; |
| 72 |
73 |
|
Bool isbanned, isfixed, isfloating, isurgent; |
| 73 |
|
- |
Bool *tags; |
| 74 |
74 |
|
Client *next; |
| 75 |
75 |
|
Client *prev; |
| 76 |
76 |
|
Client *snext; |
| 77 |
77 |
|
Window win; |
| 78 |
|
- |
Monitor *monitor; |
| 79 |
78 |
|
}; |
| 80 |
79 |
|
|
| 81 |
80 |
|
typedef struct { |
|
| 102 |
101 |
|
|
| 103 |
102 |
|
typedef struct { |
| 104 |
103 |
|
const char *symbol; |
| 105 |
|
- |
void (*arrange)(Monitor *); |
|
104 |
+ |
void (*arrange)(View *); |
| 106 |
105 |
|
} Layout; |
| 107 |
106 |
|
|
| 108 |
107 |
|
typedef struct { |
| 109 |
108 |
|
const char *prop; |
| 110 |
109 |
|
const char *tags; |
| 111 |
110 |
|
Bool isfloating; |
| 112 |
|
- |
int monitor; |
| 113 |
111 |
|
} Rule; |
| 114 |
112 |
|
|
| 115 |
113 |
|
typedef struct { |
|
| 117 |
115 |
|
regex_t *tagregex; |
| 118 |
116 |
|
} Regs; |
| 119 |
117 |
|
|
| 120 |
|
- |
struct Monitor { |
| 121 |
|
- |
int sx, sy, sw, sh, wax, way, wah, waw; |
|
118 |
+ |
struct View { |
|
119 |
+ |
int id; |
|
120 |
+ |
int x, y, w, h, wax, way, wah, waw; |
| 122 |
121 |
|
double mwfact; |
| 123 |
|
- |
Bool *seltags; |
| 124 |
|
- |
Bool *prevtags; |
| 125 |
122 |
|
Layout *layout; |
| 126 |
123 |
|
Window barwin; |
| 127 |
124 |
|
}; |
| 128 |
|
- |
|
| 129 |
125 |
|
|
| 130 |
126 |
|
/* function declarations */ |
| 131 |
127 |
|
void applyrules(Client *c); |
| 132 |
|
- |
void arrange(Monitor *m); |
|
128 |
+ |
void arrange(void); |
| 133 |
129 |
|
void attach(Client *c); |
| 134 |
130 |
|
void attachstack(Client *c); |
| 135 |
131 |
|
void ban(Client *c); |
|
| 143 |
139 |
|
void destroynotify(XEvent *e); |
| 144 |
140 |
|
void detach(Client *c); |
| 145 |
141 |
|
void detachstack(Client *c); |
| 146 |
|
- |
void drawbar(Monitor *m); |
| 147 |
|
- |
void drawsquare(Monitor *m, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
| 148 |
|
- |
void drawtext(Monitor *m, const char *text, unsigned long col[ColLast], Bool invert); |
|
142 |
+ |
void drawbar(View *v); |
|
143 |
+ |
void drawsquare(View *v, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
|
144 |
+ |
void drawtext(View *v, const char *text, unsigned long col[ColLast], Bool invert); |
| 149 |
145 |
|
void *emallocz(unsigned int size); |
| 150 |
146 |
|
void enternotify(XEvent *e); |
| 151 |
147 |
|
void eprint(const char *errstr, ...); |
| 152 |
148 |
|
void expose(XEvent *e); |
| 153 |
|
- |
void floating(Monitor *m); /* default floating layout */ |
|
149 |
+ |
void floating(View *v); /* default floating layout */ |
| 154 |
150 |
|
void focus(Client *c); |
| 155 |
151 |
|
void focusin(XEvent *e); |
| 156 |
152 |
|
void focusnext(const char *arg); |
| 157 |
153 |
|
void focusprev(const char *arg); |
| 158 |
154 |
|
Client *getclient(Window w); |
| 159 |
155 |
|
unsigned long getcolor(const char *colstr); |
| 160 |
|
- |
Monitor *getmonitor(Window barwin); |
|
156 |
+ |
View *getviewbar(Window barwin); |
|
157 |
+ |
View *getview(Client *c); |
| 161 |
158 |
|
long getstate(Window w); |
| 162 |
159 |
|
Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
| 163 |
160 |
|
void grabbuttons(Client *c, Bool focused); |
| 164 |
161 |
|
void grabkeys(void); |
| 165 |
162 |
|
unsigned int idxoftag(const char *tag); |
| 166 |
163 |
|
void initfont(const char *fontstr); |
| 167 |
|
- |
Bool isoccupied(Monitor *monitor, unsigned int t); |
|
164 |
+ |
Bool isoccupied(unsigned int t); |
| 168 |
165 |
|
Bool isprotodel(Client *c); |
| 169 |
|
- |
Bool isurgent(Monitor *monitor, unsigned int t); |
| 170 |
|
- |
Bool isvisible(Client *c, Monitor *m); |
|
166 |
+ |
Bool isurgent(unsigned int t); |
|
167 |
+ |
Bool isvisible(Client *c); |
| 171 |
168 |
|
void keypress(XEvent *e); |
| 172 |
169 |
|
void killclient(const char *arg); |
| 173 |
170 |
|
void manage(Window w, XWindowAttributes *wa); |
| 174 |
171 |
|
void mappingnotify(XEvent *e); |
| 175 |
172 |
|
void maprequest(XEvent *e); |
| 176 |
|
- |
Monitor *monitorat(void); |
|
173 |
+ |
View *viewat(void); |
| 177 |
174 |
|
void movemouse(Client *c); |
| 178 |
|
- |
Client *nexttiled(Client *c, Monitor *monitor); |
|
175 |
+ |
Client *nexttiled(Client *c, View *v); |
| 179 |
176 |
|
void propertynotify(XEvent *e); |
| 180 |
177 |
|
void quit(const char *arg); |
| 181 |
178 |
|
void reapply(const char *arg); |
| 182 |
179 |
|
void resize(Client *c, int x, int y, int w, int h, Bool sizehints); |
| 183 |
180 |
|
void resizemouse(Client *c); |
| 184 |
|
- |
void restack(Monitor *m); |
|
181 |
+ |
void restack(View *v); |
| 185 |
182 |
|
void run(void); |
| 186 |
183 |
|
void scan(void); |
| 187 |
184 |
|
void setclientstate(Client *c, long state); |
|
| 192 |
189 |
|
void tag(const char *arg); |
| 193 |
190 |
|
unsigned int textnw(const char *text, unsigned int len); |
| 194 |
191 |
|
unsigned int textw(const char *text); |
| 195 |
|
- |
void tile(Monitor *m); |
|
192 |
+ |
void tile(View *v); |
| 196 |
193 |
|
void togglebar(const char *arg); |
| 197 |
194 |
|
void togglefloating(const char *arg); |
| 198 |
195 |
|
void toggletag(const char *arg); |
|
| 200 |
197 |
|
void unban(Client *c); |
| 201 |
198 |
|
void unmanage(Client *c); |
| 202 |
199 |
|
void unmapnotify(XEvent *e); |
| 203 |
|
- |
void updatebarpos(Monitor *m); |
|
200 |
+ |
void updatebarpos(View *v); |
| 204 |
201 |
|
void updatesizehints(Client *c); |
| 205 |
202 |
|
void updatetitle(Client *c); |
| 206 |
203 |
|
void updatewmhints(Client *c); |
| 207 |
204 |
|
void view(const char *arg); |
| 208 |
205 |
|
void viewprevtag(const char *arg); /* views previous selected tags */ |
| 209 |
206 |
|
int xerror(Display *dpy, XErrorEvent *ee); |
| 210 |
|
- |
int xerrordummy(Display *dsply, XErrorEvent *ee); |
| 211 |
|
- |
int xerrorstart(Display *dsply, XErrorEvent *ee); |
|
207 |
+ |
int xerrordummy(Display *dpy, XErrorEvent *ee); |
|
208 |
+ |
int xerrorstart(Display *dpy, XErrorEvent *ee); |
| 212 |
209 |
|
void zoom(const char *arg); |
| 213 |
|
- |
void movetomonitor(const char *arg); |
| 214 |
|
- |
void selectmonitor(const char *arg); |
|
210 |
+ |
void selectview(const char *arg); |
| 215 |
211 |
|
|
| 216 |
212 |
|
/* variables */ |
| 217 |
213 |
|
char stext[256]; |
| 218 |
|
- |
int mcount = 1; |
| 219 |
|
- |
Monitor *selmonitor; |
|
214 |
+ |
int nviews = 1; |
|
215 |
+ |
View *selview; |
| 220 |
216 |
|
int screen; |
|
217 |
+ |
int *seltags; |
|
218 |
+ |
int *prevtags; |
| 221 |
219 |
|
int (*xerrorxlib)(Display *, XErrorEvent *); |
| 222 |
220 |
|
unsigned int bh, bpos; |
| 223 |
221 |
|
unsigned int blw = 0; |
|
| 249 |
247 |
|
Display *dpy; |
| 250 |
248 |
|
DC dc = {0}; |
| 251 |
249 |
|
Regs *regs = NULL; |
| 252 |
|
- |
Monitor *monitors; |
|
250 |
+ |
View *views; |
| 253 |
251 |
|
Window root; |
| 254 |
252 |
|
|
| 255 |
253 |
|
/* configuration, allows nested code to access above variables */ |
| 256 |
254 |
|
#include "config.h" |
| 257 |
255 |
|
|
| 258 |
|
- |
//Bool prevtags[LENGTH(tags)]; |
| 259 |
|
- |
|
| 260 |
256 |
|
/* function implementations */ |
| 261 |
257 |
|
void |
| 262 |
258 |
|
applyrules(Client *c) { |
|
| 264 |
260 |
|
unsigned int i, j; |
| 265 |
261 |
|
regmatch_t tmp; |
| 266 |
262 |
|
Bool matched_tag = False; |
| 267 |
|
- |
Bool matched_monitor = False; |
| 268 |
263 |
|
XClassHint ch = { 0 }; |
| 269 |
264 |
|
|
| 270 |
265 |
|
/* rule matching */ |
|
| 274 |
269 |
|
ch.res_name ? ch.res_name : "", c->name); |
| 275 |
270 |
|
for(i = 0; i < LENGTH(rules); i++) |
| 276 |
271 |
|
if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) { |
| 277 |
|
- |
if (rules[i].monitor >= 0 && rules[i].monitor < mcount) { |
| 278 |
|
- |
matched_monitor = True; |
| 279 |
|
- |
c->monitor = &monitors[rules[i].monitor]; |
| 280 |
|
- |
} |
| 281 |
|
- |
|
| 282 |
272 |
|
c->isfloating = rules[i].isfloating; |
| 283 |
273 |
|
for(j = 0; regs[i].tagregex && j < LENGTH(tags); j++) { |
| 284 |
274 |
|
if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { |
| 285 |
275 |
|
matched_tag = True; |
| 286 |
|
- |
c->tags[j] = True; |
|
276 |
+ |
c->tags[j] = selview->id; |
| 287 |
277 |
|
} |
| 288 |
278 |
|
} |
| 289 |
279 |
|
} |
|
| 292 |
282 |
|
if(ch.res_name) |
| 293 |
283 |
|
XFree(ch.res_name); |
| 294 |
284 |
|
if(!matched_tag) |
| 295 |
|
- |
memcpy(c->tags, monitorat()->seltags, sizeof initags); |
| 296 |
|
- |
if (!matched_monitor) |
| 297 |
|
- |
c->monitor = monitorat(); |
|
285 |
+ |
memcpy(c->tags, seltags, sizeof initags); |
| 298 |
286 |
|
} |
| 299 |
287 |
|
|
|
288 |
+ |
|
|
289 |
+ |
|
| 300 |
290 |
|
void |
| 301 |
|
- |
arrange(Monitor *m) { |
|
291 |
+ |
arrange(void) { |
| 302 |
292 |
|
unsigned int i; |
| 303 |
293 |
|
Client *c; |
| 304 |
294 |
|
|
| 305 |
295 |
|
for(c = clients; c; c = c->next) |
| 306 |
|
- |
if(isvisible(c, c->monitor)) |
|
296 |
+ |
if(isvisible(c)) |
| 307 |
297 |
|
unban(c); |
| 308 |
298 |
|
else |
| 309 |
299 |
|
ban(c); |
| 310 |
300 |
|
|
| 311 |
|
- |
if(m) |
| 312 |
|
- |
m->layout->arrange(m); |
| 313 |
|
- |
else |
| 314 |
|
- |
for(i = 0; i < mcount; i++) |
| 315 |
|
- |
monitors[i].layout->arrange(&monitors[i]); |
|
301 |
+ |
for(i = 0; i < nviews; i++) { |
|
302 |
+ |
views[i].layout->arrange(&views[i]); |
|
303 |
+ |
restack(&views[i]); |
|
304 |
+ |
} |
| 316 |
305 |
|
focus(NULL); |
| 317 |
|
- |
restack(m); |
| 318 |
306 |
|
} |
| 319 |
307 |
|
|
| 320 |
308 |
|
void |
|
| 335 |
323 |
|
ban(Client *c) { |
| 336 |
324 |
|
if(c->isbanned) |
| 337 |
325 |
|
return; |
| 338 |
|
- |
XMoveWindow(dpy, c->win, c->x + 3 * c->monitor->sw, c->y); |
|
326 |
+ |
XMoveWindow(dpy, c->win, c->x + 3 * getview(c)->w, c->y); |
| 339 |
327 |
|
c->isbanned = True; |
| 340 |
328 |
|
} |
| 341 |
329 |
|
|
|
| 345 |
333 |
|
Client *c; |
| 346 |
334 |
|
XButtonPressedEvent *ev = &e->xbutton; |
| 347 |
335 |
|
|
| 348 |
|
- |
Monitor *m = monitorat(); |
|
336 |
+ |
View *v = selview; |
| 349 |
337 |
|
|
| 350 |
|
- |
if(ev->window == m->barwin) { |
|
338 |
+ |
if(ev->window == v->barwin) { |
| 351 |
339 |
|
x = 0; |
| 352 |
340 |
|
for(i = 0; i < LENGTH(tags); i++) { |
| 353 |
341 |
|
x += textw(tags[i]); |
|
| 375 |
363 |
|
if(CLEANMASK(ev->state) != MODKEY) |
| 376 |
364 |
|
return; |
| 377 |
365 |
|
if(ev->button == Button1) { |
| 378 |
|
- |
restack(c->monitor); |
|
366 |
+ |
restack(getview(c)); |
| 379 |
367 |
|
movemouse(c); |
| 380 |
368 |
|
} |
| 381 |
369 |
|
else if(ev->button == Button2) { |
| 382 |
|
- |
if((floating != m->layout->arrange) && c->isfloating) |
|
370 |
+ |
if((floating != v->layout->arrange) && c->isfloating) |
| 383 |
371 |
|
togglefloating(NULL); |
| 384 |
372 |
|
else |
| 385 |
373 |
|
zoom(NULL); |
| 386 |
374 |
|
} |
| 387 |
375 |
|
else if(ev->button == Button3 && !c->isfixed) { |
| 388 |
|
- |
restack(c->monitor); |
|
376 |
+ |
restack(getview(c)); |
| 389 |
377 |
|
resizemouse(c); |
| 390 |
378 |
|
} |
| 391 |
379 |
|
} |
|
| 426 |
414 |
|
XFreeCursor(dpy, cursor[CurNormal]); |
| 427 |
415 |
|
XFreeCursor(dpy, cursor[CurResize]); |
| 428 |
416 |
|
XFreeCursor(dpy, cursor[CurMove]); |
| 429 |
|
- |
for(i = 0; i < mcount; i++) |
| 430 |
|
- |
XDestroyWindow(dpy, monitors[i].barwin); |
|
417 |
+ |
for(i = 0; i < nviews; i++) |
|
418 |
+ |
XDestroyWindow(dpy, views[i].barwin); |
| 431 |
419 |
|
XSync(dpy, False); |
| 432 |
420 |
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
| 433 |
421 |
|
} |
|
| 479 |
467 |
|
void |
| 480 |
468 |
|
configurenotify(XEvent *e) { |
| 481 |
469 |
|
XConfigureEvent *ev = &e->xconfigure; |
| 482 |
|
- |
Monitor *m = selmonitor; |
|
470 |
+ |
View *v = selview; |
| 483 |
471 |
|
|
| 484 |
|
- |
if(ev->window == root && (ev->width != m->sw || ev->height != m->sh)) { |
|
472 |
+ |
if(ev->window == root && (ev->width != v->w || ev->height != v->h)) { |
| 485 |
473 |
|
/* TODO -- update Xinerama dimensions here */ |
| 486 |
|
- |
m->sw = ev->width; |
| 487 |
|
- |
m->sh = ev->height; |
|
474 |
+ |
v->w = ev->width; |
|
475 |
+ |
v->h = ev->height; |
| 488 |
476 |
|
XFreePixmap(dpy, dc.drawable); |
| 489 |
477 |
|
dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(root, screen), bh, DefaultDepth(dpy, screen)); |
| 490 |
|
- |
XResizeWindow(dpy, m->barwin, m->sw, bh); |
| 491 |
|
- |
updatebarpos(m); |
| 492 |
|
- |
arrange(m); |
|
478 |
+ |
XResizeWindow(dpy, v->barwin, v->w, bh); |
|
479 |
+ |
updatebarpos(v); |
|
480 |
+ |
arrange(); |
| 493 |
481 |
|
} |
| 494 |
482 |
|
} |
| 495 |
483 |
|
|
|
| 500 |
488 |
|
XWindowChanges wc; |
| 501 |
489 |
|
|
| 502 |
490 |
|
if((c = getclient(ev->window))) { |
| 503 |
|
- |
Monitor *m = c->monitor; |
|
491 |
+ |
View *v = getview(c); |
| 504 |
492 |
|
if(ev->value_mask & CWBorderWidth) |
| 505 |
493 |
|
c->border = ev->border_width; |
| 506 |
|
- |
if(c->isfixed || c->isfloating || (floating == m->layout->arrange)) { |
|
494 |
+ |
if(c->isfixed || c->isfloating || (floating == v->layout->arrange)) { |
| 507 |
495 |
|
if(ev->value_mask & CWX) |
| 508 |
|
- |
c->x = m->sx+ev->x; |
|
496 |
+ |
c->x = v->x + ev->x; |
| 509 |
497 |
|
if(ev->value_mask & CWY) |
| 510 |
|
- |
c->y = m->sy+ev->y; |
|
498 |
+ |
c->y = v->y + ev->y; |
| 511 |
499 |
|
if(ev->value_mask & CWWidth) |
| 512 |
500 |
|
c->w = ev->width; |
| 513 |
501 |
|
if(ev->value_mask & CWHeight) |
| 514 |
502 |
|
c->h = ev->height; |
| 515 |
|
- |
if((c->x - m->sx + c->w) > m->sw && c->isfloating) |
| 516 |
|
- |
c->x = m->sx + (m->sw / 2 - c->w / 2); /* center in x direction */ |
| 517 |
|
- |
if((c->y - m->sy + c->h) > m->sh && c->isfloating) |
| 518 |
|
- |
c->y = m->sy + (m->sh / 2 - c->h / 2); /* center in y direction */ |
| 519 |
|
- |
if((ev->value_mask & (CWX | CWY)) |
| 520 |
|
- |
&& !(ev->value_mask & (CWWidth | CWHeight))) |
|
503 |
+ |
if((c->x - v->x + c->w) > v->w && c->isfloating) |
|
504 |
+ |
c->x = v->x + (v->w / 2 - c->w / 2); /* center in x direction */ |
|
505 |
+ |
if((c->y - v->y + c->h) > v->h && c->isfloating) |
|
506 |
+ |
c->y = v->y + (v->h / 2 - c->h / 2); /* center in y direction */ |
|
507 |
+ |
if((ev->value_mask & (CWX|CWY)) |
|
508 |
+ |
&& !(ev->value_mask & (CWWidth|CWHeight))) |
| 521 |
509 |
|
configure(c); |
| 522 |
|
- |
if(isvisible(c, monitorat())) |
|
510 |
+ |
if(isvisible(c)) |
| 523 |
511 |
|
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); |
| 524 |
512 |
|
} |
| 525 |
513 |
|
else |
|
| 567 |
555 |
|
} |
| 568 |
556 |
|
|
| 569 |
557 |
|
void |
| 570 |
|
- |
drawbar(Monitor *m) { |
| 571 |
|
- |
int j, x; |
|
558 |
+ |
drawbar(View *v) { |
|
559 |
+ |
int i, x; |
| 572 |
560 |
|
Client *c; |
| 573 |
561 |
|
|
| 574 |
562 |
|
dc.x = 0; |
| 575 |
|
- |
for(c = stack; c && !isvisible(c, m); c = c->snext); |
| 576 |
|
- |
for(j = 0; j < LENGTH(tags); j++) { |
| 577 |
|
- |
dc.w = textw(tags[j]); |
| 578 |
|
- |
if(m->seltags[j]) { |
| 579 |
|
- |
drawtext(m, tags[j], dc.sel, isurgent(m, j)); |
| 580 |
|
- |
drawsquare(m, c && c->tags[j] && c->monitor == m, |
| 581 |
|
- |
isoccupied(m, j), isurgent(m, j), dc.sel); |
|
563 |
+ |
for(c = stack; c && !isvisible(c); c = c->snext); |
|
564 |
+ |
for(i = 0; i < LENGTH(tags); i++) { |
|
565 |
+ |
dc.w = textw(tags[i]); |
|
566 |
+ |
if(seltags[i]) { |
|
567 |
+ |
drawtext(v, tags[i], dc.sel, isurgent(i)); |
|
568 |
+ |
drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.sel); |
| 582 |
569 |
|
} |
| 583 |
570 |
|
else { |
| 584 |
|
- |
drawtext(m, tags[j], dc.norm, isurgent(m, j)); |
| 585 |
|
- |
drawsquare(m, c && c->tags[j] && c->monitor == m, |
| 586 |
|
- |
isoccupied(m, j), isurgent(m, j), dc.norm); |
|
571 |
+ |
drawtext(v, tags[i], dc.norm, isurgent(i)); |
|
572 |
+ |
drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.norm); |
| 587 |
573 |
|
} |
| 588 |
574 |
|
dc.x += dc.w; |
| 589 |
575 |
|
} |
| 590 |
576 |
|
dc.w = blw; |
| 591 |
|
- |
drawtext(m, m->layout->symbol, dc.norm, False); |
|
577 |
+ |
drawtext(v, v->layout->symbol, dc.norm, False); |
| 592 |
578 |
|
x = dc.x + dc.w; |
| 593 |
|
- |
if(m == selmonitor) { |
|
579 |
+ |
if(v == selview) { |
| 594 |
580 |
|
dc.w = textw(stext); |
| 595 |
|
- |
dc.x = m->sw - dc.w; |
|
581 |
+ |
dc.x = v->w - dc.w; |
| 596 |
582 |
|
if(dc.x < x) { |
| 597 |
583 |
|
dc.x = x; |
| 598 |
|
- |
dc.w = m->sw - x; |
|
584 |
+ |
dc.w = v->w - x; |
| 599 |
585 |
|
} |
| 600 |
|
- |
drawtext(m, stext, dc.norm, False); |
|
586 |
+ |
drawtext(v, stext, dc.norm, False); |
| 601 |
587 |
|
} |
| 602 |
588 |
|
else |
| 603 |
|
- |
dc.x = m->sw; |
|
589 |
+ |
dc.x = v->w; |
| 604 |
590 |
|
if((dc.w = dc.x - x) > bh) { |
| 605 |
591 |
|
dc.x = x; |
| 606 |
592 |
|
if(c) { |
| 607 |
|
- |
drawtext(m, c->name, dc.sel, False); |
| 608 |
|
- |
drawsquare(m, False, c->isfloating, False, dc.sel); |
|
593 |
+ |
drawtext(v, c->name, dc.sel, False); |
|
594 |
+ |
drawsquare(v, False, c->isfloating, False, dc.sel); |
| 609 |
595 |
|
} |
| 610 |
596 |
|
else |
| 611 |
|
- |
drawtext(m, NULL, dc.norm, False); |
|
597 |
+ |
drawtext(v, NULL, dc.norm, False); |
| 612 |
598 |
|
} |
| 613 |
|
- |
XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->sw, bh, 0, 0); |
|
599 |
+ |
XCopyArea(dpy, dc.drawable, v->barwin, dc.gc, 0, 0, v->w, bh, 0, 0); |
| 614 |
600 |
|
XSync(dpy, False); |
| 615 |
601 |
|
} |
| 616 |
602 |
|
|
| 617 |
603 |
|
void |
| 618 |
|
- |
drawsquare(Monitor *m, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { |
|
604 |
+ |
drawsquare(View *v, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { |
| 619 |
605 |
|
int x; |
| 620 |
606 |
|
XGCValues gcv; |
| 621 |
607 |
|
XRectangle r = { dc.x, dc.y, dc.w, dc.h }; |
|
| 636 |
622 |
|
} |
| 637 |
623 |
|
|
| 638 |
624 |
|
void |
| 639 |
|
- |
drawtext(Monitor *m, const char *text, unsigned long col[ColLast], Bool invert) { |
|
625 |
+ |
drawtext(View *v, const char *text, unsigned long col[ColLast], Bool invert) { |
| 640 |
626 |
|
int x, y, w, h; |
| 641 |
627 |
|
static char buf[256]; |
| 642 |
628 |
|
unsigned int len, olen; |
|
| 695 |
681 |
|
} |
| 696 |
682 |
|
if((c = getclient(ev->window))) |
| 697 |
683 |
|
focus(c); |
| 698 |
|
- |
else { |
| 699 |
|
- |
selmonitor = monitorat(); |
| 700 |
|
- |
fprintf(stderr, "updating selmonitor %d\n", selmonitor - monitors); |
|
684 |
+ |
else |
| 701 |
685 |
|
focus(NULL); |
| 702 |
|
- |
} |
| 703 |
686 |
|
} |
| 704 |
687 |
|
|
| 705 |
688 |
|
void |
|
| 714 |
697 |
|
|
| 715 |
698 |
|
void |
| 716 |
699 |
|
expose(XEvent *e) { |
| 717 |
|
- |
Monitor *m; |
|
700 |
+ |
View *v; |
| 718 |
701 |
|
XExposeEvent *ev = &e->xexpose; |
| 719 |
702 |
|
|
| 720 |
|
- |
if(ev->count == 0 && (m = getmonitor(ev->window))) |
| 721 |
|
- |
drawbar(m); |
|
703 |
+ |
if(ev->count == 0 && (v = getviewbar(ev->window))) |
|
704 |
+ |
drawbar(v); |
| 722 |
705 |
|
} |
| 723 |
706 |
|
|
| 724 |
707 |
|
void |
| 725 |
|
- |
floating(Monitor *m) { /* default floating layout */ |
|
708 |
+ |
floating(View *v) { /* default floating layout */ |
| 726 |
709 |
|
Client *c; |
| 727 |
710 |
|
|
| 728 |
711 |
|
domwfact = dozoom = False; |
| 729 |
712 |
|
for(c = clients; c; c = c->next) |
| 730 |
|
- |
if(isvisible(c, m)) |
|
713 |
+ |
if(isvisible(c)) |
| 731 |
714 |
|
resize(c, c->x, c->y, c->w, c->h, True); |
| 732 |
715 |
|
} |
| 733 |
716 |
|
|
| 734 |
717 |
|
void |
| 735 |
718 |
|
focus(Client *c) { |
|
719 |
+ |
View *v = selview; |
| 736 |
720 |
|
if(c) |
| 737 |
|
- |
selmonitor = c->monitor; |
| 738 |
|
- |
if(!c || (c && !isvisible(c, selmonitor))) |
| 739 |
|
- |
for(c = stack; c && !isvisible(c, c->monitor); c = c->snext); |
|
721 |
+ |
selview = getview(c); |
|
722 |
+ |
else |
|
723 |
+ |
selview = viewat(); |
|
724 |
+ |
if(selview != v) |
|
725 |
+ |
drawbar(v); |
|
726 |
+ |
if(!c || (c && !isvisible(c))) |
|
727 |
+ |
for(c = stack; c && !isvisible(c); c = c->snext); |
| 740 |
728 |
|
if(sel && sel != c) { |
| 741 |
729 |
|
grabbuttons(sel, False); |
| 742 |
730 |
|
XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]); |
|
| 750 |
738 |
|
if(c) { |
| 751 |
739 |
|
XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); |
| 752 |
740 |
|
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
| 753 |
|
- |
selmonitor = c->monitor; |
|
741 |
+ |
selview = getview(c); |
| 754 |
742 |
|
} |
| 755 |
743 |
|
else |
| 756 |
744 |
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
| 757 |
|
- |
drawbar(selmonitor); |
|
745 |
+ |
drawbar(selview); |
| 758 |
746 |
|
} |
| 759 |
747 |
|
|
| 760 |
748 |
|
void |
|
| 771 |
759 |
|
|
| 772 |
760 |
|
if(!sel) |
| 773 |
761 |
|
return; |
| 774 |
|
- |
for(c = sel->next; c && !isvisible(c, selmonitor); c = c->next); |
|
762 |
+ |
for(c = sel->next; c && !isvisible(c); c = c->next); |
| 775 |
763 |
|
if(!c) |
| 776 |
|
- |
for(c = clients; c && !isvisible(c, selmonitor); c = c->next); |
|
764 |
+ |
for(c = clients; c && !isvisible(c); c = c->next); |
| 777 |
765 |
|
if(c) { |
| 778 |
766 |
|
focus(c); |
| 779 |
|
- |
restack(c->monitor); |
|
767 |
+ |
restack(getview(c)); |
| 780 |
768 |
|
} |
| 781 |
769 |
|
} |
| 782 |
770 |
|
|
|
| 786 |
774 |
|
|
| 787 |
775 |
|
if(!sel) |
| 788 |
776 |
|
return; |
| 789 |
|
- |
for(c = sel->prev; c && !isvisible(c, selmonitor); c = c->prev); |
|
777 |
+ |
for(c = sel->prev; c && !isvisible(c); c = c->prev); |
| 790 |
778 |
|
if(!c) { |
| 791 |
779 |
|
for(c = clients; c && c->next; c = c->next); |
| 792 |
|
- |
for(; c && !isvisible(c, selmonitor); c = c->prev); |
|
780 |
+ |
for(; c && !isvisible(c); c = c->prev); |
| 793 |
781 |
|
} |
| 794 |
782 |
|
if(c) { |
| 795 |
783 |
|
focus(c); |
| 796 |
|
- |
restack(c->monitor); |
|
784 |
+ |
restack(getview(c)); |
| 797 |
785 |
|
} |
| 798 |
786 |
|
} |
| 799 |
787 |
|
|
|
| 815 |
803 |
|
return color.pixel; |
| 816 |
804 |
|
} |
| 817 |
805 |
|
|
| 818 |
|
- |
Monitor * |
| 819 |
|
- |
getmonitor(Window barwin) { |
|
806 |
+ |
View * |
|
807 |
+ |
getviewbar(Window barwin) { |
| 820 |
808 |
|
unsigned int i; |
| 821 |
809 |
|
|
| 822 |
|
- |
for(i = 0; i < mcount; i++) |
| 823 |
|
- |
if(monitors[i].barwin == barwin) |
| 824 |
|
- |
return &monitors[i]; |
|
810 |
+ |
for(i = 0; i < nviews; i++) |
|
811 |
+ |
if(views[i].barwin == barwin) |
|
812 |
+ |
return &views[i]; |
| 825 |
813 |
|
return NULL; |
|
814 |
+ |
} |
|
815 |
+ |
|
|
816 |
+ |
View * |
|
817 |
+ |
getview(Client *c) { |
|
818 |
+ |
unsigned int i; |
|
819 |
+ |
|
|
820 |
+ |
for(i = 0; i < LENGTH(tags); i++) |
|
821 |
+ |
if(c->tags[i]) |
|
822 |
+ |
return &views[c->tags[i] - 1]; |
|
823 |
+ |
return &views[0]; /* fallback */ |
| 826 |
824 |
|
} |
| 827 |
825 |
|
|
| 828 |
826 |
|
long |
|
| 876 |
874 |
|
if(focused) { |
| 877 |
875 |
|
XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK, |
| 878 |
876 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 879 |
|
- |
XGrabButton(dpy, Button1, MODKEY | LockMask, c->win, False, BUTTONMASK, |
|
877 |
+ |
XGrabButton(dpy, Button1, MODKEY|LockMask, c->win, False, BUTTONMASK, |
| 880 |
878 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 881 |
|
- |
XGrabButton(dpy, Button1, MODKEY | numlockmask, c->win, False, BUTTONMASK, |
|
879 |
+ |
XGrabButton(dpy, Button1, MODKEY|numlockmask, c->win, False, BUTTONMASK, |
| 882 |
880 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 883 |
|
- |
XGrabButton(dpy, Button1, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK, |
|
881 |
+ |
XGrabButton(dpy, Button1, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK, |
| 884 |
882 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 885 |
883 |
|
|
| 886 |
884 |
|
XGrabButton(dpy, Button2, MODKEY, c->win, False, BUTTONMASK, |
| 887 |
885 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 888 |
|
- |
XGrabButton(dpy, Button2, MODKEY | LockMask, c->win, False, BUTTONMASK, |
|
886 |
+ |
XGrabButton(dpy, Button2, MODKEY|LockMask, c->win, False, BUTTONMASK, |
| 889 |
887 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 890 |
|
- |
XGrabButton(dpy, Button2, MODKEY | numlockmask, c->win, False, BUTTONMASK, |
|
888 |
+ |
XGrabButton(dpy, Button2, MODKEY|numlockmask, c->win, False, BUTTONMASK, |
| 891 |
889 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 892 |
|
- |
XGrabButton(dpy, Button2, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK, |
|
890 |
+ |
XGrabButton(dpy, Button2, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK, |
| 893 |
891 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 894 |
892 |
|
|
| 895 |
893 |
|
XGrabButton(dpy, Button3, MODKEY, c->win, False, BUTTONMASK, |
| 896 |
894 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 897 |
|
- |
XGrabButton(dpy, Button3, MODKEY | LockMask, c->win, False, BUTTONMASK, |
|
895 |
+ |
XGrabButton(dpy, Button3, MODKEY|LockMask, c->win, False, BUTTONMASK, |
| 898 |
896 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 899 |
|
- |
XGrabButton(dpy, Button3, MODKEY | numlockmask, c->win, False, BUTTONMASK, |
|
897 |
+ |
XGrabButton(dpy, Button3, MODKEY|numlockmask, c->win, False, BUTTONMASK, |
| 900 |
898 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 901 |
|
- |
XGrabButton(dpy, Button3, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK, |
|
899 |
+ |
XGrabButton(dpy, Button3, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK, |
| 902 |
900 |
|
GrabModeAsync, GrabModeSync, None, None); |
| 903 |
901 |
|
} |
| 904 |
902 |
|
else |
|
| 926 |
924 |
|
code = XKeysymToKeycode(dpy, keys[i].keysym); |
| 927 |
925 |
|
XGrabKey(dpy, code, keys[i].mod, root, True, |
| 928 |
926 |
|
GrabModeAsync, GrabModeAsync); |
| 929 |
|
- |
XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, |
|
927 |
+ |
XGrabKey(dpy, code, keys[i].mod|LockMask, root, True, |
| 930 |
928 |
|
GrabModeAsync, GrabModeAsync); |
| 931 |
|
- |
XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True, |
|
929 |
+ |
XGrabKey(dpy, code, keys[i].mod|numlockmask, root, True, |
| 932 |
930 |
|
GrabModeAsync, GrabModeAsync); |
| 933 |
|
- |
XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True, |
|
931 |
+ |
XGrabKey(dpy, code, keys[i].mod|numlockmask|LockMask, root, True, |
| 934 |
932 |
|
GrabModeAsync, GrabModeAsync); |
| 935 |
933 |
|
} |
| 936 |
934 |
|
} |
|
| 986 |
984 |
|
} |
| 987 |
985 |
|
|
| 988 |
986 |
|
Bool |
| 989 |
|
- |
isoccupied(Monitor *monitor, unsigned int t) { |
|
987 |
+ |
isoccupied(unsigned int t) { |
| 990 |
988 |
|
Client *c; |
| 991 |
989 |
|
|
| 992 |
990 |
|
for(c = clients; c; c = c->next) |
| 993 |
|
- |
if(c->tags[t] && c->monitor == monitor) |
|
991 |
+ |
if(c->tags[t]) |
| 994 |
992 |
|
return True; |
| 995 |
993 |
|
return False; |
| 996 |
994 |
|
} |
|
| 1011 |
1009 |
|
} |
| 1012 |
1010 |
|
|
| 1013 |
1011 |
|
Bool |
| 1014 |
|
- |
isurgent(Monitor *monitor, unsigned int t) { |
|
1012 |
+ |
isurgent(unsigned int t) { |
| 1015 |
1013 |
|
Client *c; |
| 1016 |
1014 |
|
|
| 1017 |
1015 |
|
for(c = clients; c; c = c->next) |
| 1018 |
|
- |
if(c->monitor == monitor && c->isurgent && c->tags[t]) |
|
1016 |
+ |
if(c->isurgent && c->tags[t]) |
| 1019 |
1017 |
|
return True; |
| 1020 |
1018 |
|
return False; |
| 1021 |
1019 |
|
} |
| 1022 |
1020 |
|
|
| 1023 |
1021 |
|
Bool |
| 1024 |
|
- |
isvisible(Client *c, Monitor *m) { |
|
1022 |
+ |
isvisible(Client *c) { |
| 1025 |
1023 |
|
unsigned int i; |
| 1026 |
1024 |
|
|
| 1027 |
|
- |
if(c->monitor != m) |
| 1028 |
|
- |
return False; |
| 1029 |
1025 |
|
for(i = 0; i < LENGTH(tags); i++) |
| 1030 |
|
- |
if(c->tags[i] && c->monitor->seltags[i]) |
|
1026 |
+ |
if(c->tags[i] && seltags[i]) |
| 1031 |
1027 |
|
return True; |
| 1032 |
1028 |
|
return False; |
| 1033 |
1029 |
|
} |
|
| 1071 |
1067 |
|
void |
| 1072 |
1068 |
|
manage(Window w, XWindowAttributes *wa) { |
| 1073 |
1069 |
|
Client *c, *t = NULL; |
| 1074 |
|
- |
Monitor *m; |
|
1070 |
+ |
View *v; |
| 1075 |
1071 |
|
Status rettrans; |
| 1076 |
1072 |
|
Window trans; |
| 1077 |
1073 |
|
XWindowChanges wc; |
|
| 1082 |
1078 |
|
|
| 1083 |
1079 |
|
applyrules(c); |
| 1084 |
1080 |
|
|
| 1085 |
|
- |
m = c->monitor; |
|
1081 |
+ |
v = getview(c); |
| 1086 |
1082 |
|
|
| 1087 |
|
- |
c->x = wa->x + m->sx; |
| 1088 |
|
- |
c->y = wa->y + m->sy; |
|
1083 |
+ |
c->x = wa->x + v->x; |
|
1084 |
+ |
c->y = wa->y + v->y; |
| 1089 |
1085 |
|
c->w = wa->width; |
| 1090 |
1086 |
|
c->h = wa->height; |
| 1091 |
1087 |
|
c->oldborder = wa->border_width; |
| 1092 |
1088 |
|
|
| 1093 |
|
- |
if(c->w == m->sw && c->h == m->sh) { |
| 1094 |
|
- |
c->x = m->sx; |
| 1095 |
|
- |
c->y = m->sy; |
|
1089 |
+ |
if(c->w == v->w && c->h == v->h) { |
|
1090 |
+ |
c->x = v->x; |
|
1091 |
+ |
c->y = v->y; |
| 1096 |
1092 |
|
c->border = wa->border_width; |
| 1097 |
1093 |
|
} |
| 1098 |
1094 |
|
else { |
| 1099 |
|
- |
if(c->x + c->w + 2 * c->border > m->wax + m->waw) |
| 1100 |
|
- |
c->x = m->wax + m->waw - c->w - 2 * c->border; |
| 1101 |
|
- |
if(c->y + c->h + 2 * c->border > m->way + m->wah) |
| 1102 |
|
- |
c->y = m->way + m->wah - c->h - 2 * c->border; |
| 1103 |
|
- |
if(c->x < m->wax) |
| 1104 |
|
- |
c->x = m->wax; |
| 1105 |
|
- |
if(c->y < m->way) |
| 1106 |
|
- |
c->y = m->way; |
|
1095 |
+ |
if(c->x + c->w + 2 * c->border > v->wax + v->waw) |
|
1096 |
+ |
c->x = v->wax + v->waw - c->w - 2 * c->border; |
|
1097 |
+ |
if(c->y + c->h + 2 * c->border > v->way + v->wah) |
|
1098 |
+ |
c->y = v->way + v->wah - c->h - 2 * c->border; |
|
1099 |
+ |
if(c->x < v->wax) |
|
1100 |
+ |
c->x = v->wax; |
|
1101 |
+ |
if(c->y < v->way) |
|
1102 |
+ |
c->y = v->way; |
| 1107 |
1103 |
|
c->border = BORDERPX; |
| 1108 |
1104 |
|
} |
| 1109 |
1105 |
|
wc.border_width = c->border; |
|
| 1111 |
1107 |
|
XSetWindowBorder(dpy, w, dc.norm[ColBorder]); |
| 1112 |
1108 |
|
configure(c); /* propagates border_width, if size doesn't change */ |
| 1113 |
1109 |
|
updatesizehints(c); |
| 1114 |
|
- |
XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); |
|
1110 |
+ |
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); |
| 1115 |
1111 |
|
grabbuttons(c, False); |
| 1116 |
1112 |
|
updatetitle(c); |
| 1117 |
1113 |
|
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) |
|
| 1126 |
1122 |
|
ban(c); |
| 1127 |
1123 |
|
XMapWindow(dpy, c->win); |
| 1128 |
1124 |
|
setclientstate(c, NormalState); |
| 1129 |
|
- |
arrange(m); |
|
1125 |
+ |
arrange(); |
| 1130 |
1126 |
|
} |
| 1131 |
1127 |
|
|
| 1132 |
1128 |
|
void |
|
| 1151 |
1147 |
|
manage(ev->window, &wa); |
| 1152 |
1148 |
|
} |
| 1153 |
1149 |
|
|
| 1154 |
|
- |
Monitor * |
| 1155 |
|
- |
monitorat() { |
|
1150 |
+ |
View * |
|
1151 |
+ |
viewat() { |
| 1156 |
1152 |
|
int i, x, y; |
| 1157 |
1153 |
|
Window win; |
| 1158 |
1154 |
|
unsigned int mask; |
| 1159 |
1155 |
|
|
| 1160 |
1156 |
|
XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask); |
| 1161 |
|
- |
for(i = 0; i < mcount; i++) { |
| 1162 |
|
- |
if((x >= monitors[i].sx && x < monitors[i].sx + monitors[i].sw) |
| 1163 |
|
- |
&& (y >= monitors[i].sy && y < monitors[i].sy + monitors[i].sh)) { |
| 1164 |
|
- |
return &monitors[i]; |
|
1157 |
+ |
for(i = 0; i < nviews; i++) { |
|
1158 |
+ |
if((x >= views[i].x && x < views[i].x + views[i].w) |
|
1159 |
+ |
&& (y >= views[i].y && y < views[i].y + views[i].h)) { |
|
1160 |
+ |
return &views[i]; |
| 1165 |
1161 |
|
} |
| 1166 |
1162 |
|
} |
| 1167 |
1163 |
|
return NULL; |
|
| 1171 |
1167 |
|
movemouse(Client *c) { |
| 1172 |
1168 |
|
int x1, y1, ocx, ocy, di, nx, ny; |
| 1173 |
1169 |
|
unsigned int dui; |
| 1174 |
|
- |
Monitor *m; |
|
1170 |
+ |
View *v; |
| 1175 |
1171 |
|
Window dummy; |
| 1176 |
1172 |
|
XEvent ev; |
| 1177 |
1173 |
|
|
| 1178 |
1174 |
|
ocx = nx = c->x; |
| 1179 |
1175 |
|
ocy = ny = c->y; |
| 1180 |
|
- |
m = c->monitor; |
|
1176 |
+ |
v = getview(c); |
| 1181 |
1177 |
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
| 1182 |
1178 |
|
None, cursor[CurMove], CurrentTime) != GrabSuccess) |
| 1183 |
1179 |
|
return; |
| 1184 |
1180 |
|
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); |
| 1185 |
1181 |
|
for(;;) { |
| 1186 |
|
- |
XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); |
|
1182 |
+ |
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); |
| 1187 |
1183 |
|
switch (ev.type) { |
| 1188 |
1184 |
|
case ButtonRelease: |
| 1189 |
1185 |
|
XUngrabPointer(dpy, CurrentTime); |
|
| 1197 |
1193 |
|
XSync(dpy, False); |
| 1198 |
1194 |
|
nx = ocx + (ev.xmotion.x - x1); |
| 1199 |
1195 |
|
ny = ocy + (ev.xmotion.y - y1); |
| 1200 |
|
- |
if(abs(m->wax - nx) < SNAP) |
| 1201 |
|
- |
nx = m->wax; |
| 1202 |
|
- |
else if(abs((m->wax + m->waw) - (nx + c->w + 2 * c->border)) < SNAP) |
| 1203 |
|
- |
nx = m->wax + m->waw - c->w - 2 * c->border; |
| 1204 |
|
- |
if(abs(m->way - ny) < SNAP) |
| 1205 |
|
- |
ny = m->way; |
| 1206 |
|
- |
else if(abs((m->way + m->wah) - (ny + c->h + 2 * c->border)) < SNAP) |
| 1207 |
|
- |
ny = m->way + m->wah - c->h - 2 * c->border; |
| 1208 |
|
- |
if(!c->isfloating && (m->layout->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP)) |
|
1196 |
+ |
if(abs(v->wax - nx) < SNAP) |
|
1197 |
+ |
nx = v->wax; |
|
1198 |
+ |
else if(abs((v->wax + v->waw) - (nx + c->w + 2 * c->border)) < SNAP) |
|
1199 |
+ |
nx = v->wax + v->waw - c->w - 2 * c->border; |
|
1200 |
+ |
if(abs(v->way - ny) < SNAP) |
|
1201 |
+ |
ny = v->way; |
|
1202 |
+ |
else if(abs((v->way + v->wah) - (ny + c->h + 2 * c->border)) < SNAP) |
|
1203 |
+ |
ny = v->way + v->wah - c->h - 2 * c->border; |
|
1204 |
+ |
if(!c->isfloating && (v->layout->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP)) |
| 1209 |
1205 |
|
togglefloating(NULL); |
| 1210 |
|
- |
if((m->layout->arrange == floating) || c->isfloating) |
|
1206 |
+ |
if((v->layout->arrange == floating) || c->isfloating) |
| 1211 |
1207 |
|
resize(c, nx, ny, c->w, c->h, False); |
| 1212 |
1208 |
|
break; |
| 1213 |
1209 |
|
} |
|
| 1215 |
1211 |
|
} |
| 1216 |
1212 |
|
|
| 1217 |
1213 |
|
Client * |
| 1218 |
|
- |
nexttiled(Client *c, Monitor *monitor) { |
| 1219 |
|
- |
for(; c && (c->isfloating || !isvisible(c, monitor)); c = c->next); |
|
1214 |
+ |
nexttiled(Client *c, View *v) { |
|
1215 |
+ |
for(; c && (c->isfloating || getview(c) != v || !isvisible(c)); c = c->next); |
| 1220 |
1216 |
|
return c; |
| 1221 |
1217 |
|
} |
| 1222 |
1218 |
|
|
|
| 1234 |
1230 |
|
case XA_WM_TRANSIENT_FOR: |
| 1235 |
1231 |
|
XGetTransientForHint(dpy, c->win, &trans); |
| 1236 |
1232 |
|
if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL))) |
| 1237 |
|
- |
arrange(c->monitor); |
|
1233 |
+ |
arrange(); |
| 1238 |
1234 |
|
break; |
| 1239 |
1235 |
|
case XA_WM_NORMAL_HINTS: |
| 1240 |
1236 |
|
updatesizehints(c); |
| 1241 |
1237 |
|
break; |
| 1242 |
1238 |
|
case XA_WM_HINTS: |
| 1243 |
1239 |
|
updatewmhints(c); |
| 1244 |
|
- |
drawbar(c->monitor); |
|
1240 |
+ |
drawbar(getview(c)); |
| 1245 |
1241 |
|
break; |
| 1246 |
1242 |
|
} |
| 1247 |
1243 |
|
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { |
| 1248 |
1244 |
|
updatetitle(c); |
| 1249 |
1245 |
|
if(c == sel) |
| 1250 |
|
- |
drawbar(c->monitor); |
|
1246 |
+ |
drawbar(selview); |
| 1251 |
1247 |
|
} |
| 1252 |
1248 |
|
} |
| 1253 |
1249 |
|
} |
|
| 1266 |
1262 |
|
memcpy(c->tags, zerotags, sizeof zerotags); |
| 1267 |
1263 |
|
applyrules(c); |
| 1268 |
1264 |
|
} |
| 1269 |
|
- |
arrange(NULL); |
|
1265 |
+ |
arrange(); |
| 1270 |
1266 |
|
} |
| 1271 |
1267 |
|
|
| 1272 |
1268 |
|
void |
| 1273 |
1269 |
|
resize(Client *c, int x, int y, int w, int h, Bool sizehints) { |
| 1274 |
|
- |
Monitor *m; |
|
1270 |
+ |
View *v; |
| 1275 |
1271 |
|
XWindowChanges wc; |
| 1276 |
1272 |
|
|
| 1277 |
|
- |
m = c->monitor; |
|
1273 |
+ |
v = getview(c); |
| 1278 |
1274 |
|
if(sizehints) { |
| 1279 |
1275 |
|
/* set minimum possible */ |
| 1280 |
1276 |
|
if (w < 1) |
|
| 1315 |
1311 |
|
} |
| 1316 |
1312 |
|
if(w <= 0 || h <= 0) |
| 1317 |
1313 |
|
return; |
| 1318 |
|
- |
if(x > m->sw) |
| 1319 |
|
- |
x = m->sw - w - 2 * c->border; |
| 1320 |
|
- |
if(y > m->sh) |
| 1321 |
|
- |
y = m->sh - h - 2 * c->border; |
| 1322 |
|
- |
if(x + w + 2 * c->border < m->sx) |
| 1323 |
|
- |
x = m->sx; |
| 1324 |
|
- |
if(y + h + 2 * c->border < m->sy) |
| 1325 |
|
- |
y = m->sy; |
| 1326 |
|
- |
fprintf(stderr, "resize %d %d %d %d (%d %d %d %d)\n", x, y , w, h, m->sx, m->sy, m->sw, m->sh); |
|
1314 |
+ |
if(x > v->x + v->w) |
|
1315 |
+ |
x = v->w - w - 2 * c->border; |
|
1316 |
+ |
if(y > v->y + v->h) |
|
1317 |
+ |
y = v->h - h - 2 * c->border; |
|
1318 |
+ |
if(x + w + 2 * c->border < v->x) |
|
1319 |
+ |
x = v->x; |
|
1320 |
+ |
if(y + h + 2 * c->border < v->y) |
|
1321 |
+ |
y = v->y; |
| 1327 |
1322 |
|
if(c->x != x || c->y != y || c->w != w || c->h != h) { |
| 1328 |
1323 |
|
c->x = wc.x = x; |
| 1329 |
1324 |
|
c->y = wc.y = y; |
| 1330 |
1325 |
|
c->w = wc.width = w; |
| 1331 |
1326 |
|
c->h = wc.height = h; |
| 1332 |
1327 |
|
wc.border_width = c->border; |
| 1333 |
|
- |
XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); |
|
1328 |
+ |
XConfigureWindow(dpy, c->win, |
|
1329 |
+ |
CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); |
| 1334 |
1330 |
|
configure(c); |
| 1335 |
1331 |
|
XSync(dpy, False); |
| 1336 |
1332 |
|
} |
|
| 1340 |
1336 |
|
resizemouse(Client *c) { |
| 1341 |
1337 |
|
int ocx, ocy; |
| 1342 |
1338 |
|
int nw, nh; |
| 1343 |
|
- |
Monitor *m; |
|
1339 |
+ |
View *v; |
| 1344 |
1340 |
|
XEvent ev; |
| 1345 |
1341 |
|
|
| 1346 |
1342 |
|
ocx = c->x; |
| 1347 |
1343 |
|
ocy = c->y; |
| 1348 |
|
- |
m = c->monitor; |
|
1344 |
+ |
v = getview(c); |
| 1349 |
1345 |
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
| 1350 |
1346 |
|
None, cursor[CurResize], CurrentTime) != GrabSuccess) |
| 1351 |
1347 |
|
return; |
| 1352 |
1348 |
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); |
| 1353 |
1349 |
|
for(;;) { |
| 1354 |
|
- |
XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev); |
|
1350 |
+ |
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev); |
| 1355 |
1351 |
|
switch(ev.type) { |
| 1356 |
1352 |
|
case ButtonRelease: |
| 1357 |
1353 |
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, |
|
| 1370 |
1366 |
|
nw = 1; |
| 1371 |
1367 |
|
if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0) |
| 1372 |
1368 |
|
nh = 1; |
| 1373 |
|
- |
if(!c->isfloating && (m->layout->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) |
|
1369 |
+ |
if(!c->isfloating && (v->layout->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) |
| 1374 |
1370 |
|
togglefloating(NULL); |
| 1375 |
|
- |
if((m->layout->arrange == floating) || c->isfloating) |
|
1371 |
+ |
if((v->layout->arrange == floating) || c->isfloating) |
| 1376 |
1372 |
|
resize(c, c->x, c->y, nw, nh, True); |
| 1377 |
1373 |
|
break; |
| 1378 |
1374 |
|
} |
|
| 1380 |
1376 |
|
} |
| 1381 |
1377 |
|
|
| 1382 |
1378 |
|
void |
| 1383 |
|
- |
restack(Monitor *m) { |
|
1379 |
+ |
restack(View *v) { |
| 1384 |
1380 |
|
Client *c; |
| 1385 |
1381 |
|
XEvent ev; |
| 1386 |
1382 |
|
XWindowChanges wc; |
| 1387 |
1383 |
|
|
| 1388 |
|
- |
drawbar(m); |
|
1384 |
+ |
drawbar(v); |
| 1389 |
1385 |
|
if(!sel) |
| 1390 |
1386 |
|
return; |
| 1391 |
|
- |
if(sel->isfloating || (m->layout->arrange == floating)) |
|
1387 |
+ |
if(sel->isfloating || (v->layout->arrange == floating)) |
| 1392 |
1388 |
|
XRaiseWindow(dpy, sel->win); |
| 1393 |
|
- |
if(m->layout->arrange != floating) { |
|
1389 |
+ |
if(v->layout->arrange != floating) { |
| 1394 |
1390 |
|
wc.stack_mode = Below; |
| 1395 |
|
- |
wc.sibling = m->barwin; |
|
1391 |
+ |
wc.sibling = v->barwin; |
| 1396 |
1392 |
|
if(!sel->isfloating) { |
| 1397 |
|
- |
XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc); |
|
1393 |
+ |
XConfigureWindow(dpy, sel->win, CWSibling|CWStackMode, &wc); |
| 1398 |
1394 |
|
wc.sibling = sel->win; |
| 1399 |
1395 |
|
} |
| 1400 |
|
- |
for(c = nexttiled(clients, m); c; c = nexttiled(c->next, m)) { |
|
1396 |
+ |
for(c = nexttiled(clients, v); c; c = nexttiled(c->next, v)) { |
| 1401 |
1397 |
|
if(c == sel) |
| 1402 |
1398 |
|
continue; |
| 1403 |
|
- |
XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc); |
|
1399 |
+ |
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); |
| 1404 |
1400 |
|
wc.sibling = c->win; |
| 1405 |
1401 |
|
} |
| 1406 |
1402 |
|
} |
|
| 1458 |
1454 |
|
} |
| 1459 |
1455 |
|
break; |
| 1460 |
1456 |
|
} |
| 1461 |
|
- |
drawbar(selmonitor); |
|
1457 |
+ |
drawbar(selview); |
| 1462 |
1458 |
|
} |
| 1463 |
1459 |
|
while(XPending(dpy)) { |
| 1464 |
1460 |
|
XNextEvent(dpy, &ev); |
|
| 1506 |
1502 |
|
void |
| 1507 |
1503 |
|
setlayout(const char *arg) { |
| 1508 |
1504 |
|
unsigned int i; |
| 1509 |
|
- |
Monitor *m = monitorat(); |
|
1505 |
+ |
View *v = selview; |
| 1510 |
1506 |
|
|
| 1511 |
1507 |
|
if(!arg) { |
| 1512 |
|
- |
m->layout++; |
| 1513 |
|
- |
if(m->layout == &layouts[LENGTH(layouts)]) |
| 1514 |
|
- |
m->layout = &layouts[0]; |
|
1508 |
+ |
v->layout++; |
|
1509 |
+ |
if(v->layout == &layouts[LENGTH(layouts)]) |
|
1510 |
+ |
v->layout = &layouts[0]; |
| 1515 |
1511 |
|
} |
| 1516 |
1512 |
|
else { |
| 1517 |
1513 |
|
for(i = 0; i < LENGTH(layouts); i++) |
|
| 1519 |
1515 |
|
break; |
| 1520 |
1516 |
|
if(i == LENGTH(layouts)) |
| 1521 |
1517 |
|
return; |
| 1522 |
|
- |
m->layout = &layouts[i]; |
|
1518 |
+ |
v->layout = &layouts[i]; |
| 1523 |
1519 |
|
} |
| 1524 |
1520 |
|
if(sel) |
| 1525 |
|
- |
arrange(m); |
|
1521 |
+ |
arrange(); |
| 1526 |
1522 |
|
else |
| 1527 |
|
- |
drawbar(m); |
|
1523 |
+ |
drawbar(v); |
| 1528 |
1524 |
|
} |
| 1529 |
1525 |
|
|
| 1530 |
1526 |
|
void |
| 1531 |
1527 |
|
setmwfact(const char *arg) { |
| 1532 |
1528 |
|
double delta; |
| 1533 |
1529 |
|
|
| 1534 |
|
- |
Monitor *m = monitorat(); |
|
1530 |
+ |
View *v = selview; |
| 1535 |
1531 |
|
|
| 1536 |
1532 |
|
if(!domwfact) |
| 1537 |
1533 |
|
return; |
| 1538 |
1534 |
|
/* arg handling, manipulate mwfact */ |
| 1539 |
1535 |
|
if(arg == NULL) |
| 1540 |
|
- |
m->mwfact = MWFACT; |
|
1536 |
+ |
v->mwfact = MWFACT; |
| 1541 |
1537 |
|
else if(sscanf(arg, "%lf", &delta) == 1) { |
| 1542 |
1538 |
|
if(arg[0] == '+' || arg[0] == '-') |
| 1543 |
|
- |
m->mwfact += delta; |
|
1539 |
+ |
v->mwfact += delta; |
| 1544 |
1540 |
|
else |
| 1545 |
|
- |
m->mwfact = delta; |
| 1546 |
|
- |
if(m->mwfact < 0.1) |
| 1547 |
|
- |
m->mwfact = 0.1; |
| 1548 |
|
- |
else if(m->mwfact > 0.9) |
| 1549 |
|
- |
m->mwfact = 0.9; |
|
1541 |
+ |
v->mwfact = delta; |
|
1542 |
+ |
if(v->mwfact < 0.1) |
|
1543 |
+ |
v->mwfact = 0.1; |
|
1544 |
+ |
else if(v->mwfact > 0.9) |
|
1545 |
+ |
v->mwfact = 0.9; |
| 1550 |
1546 |
|
} |
| 1551 |
|
- |
arrange(m); |
|
1547 |
+ |
arrange(); |
| 1552 |
1548 |
|
} |
| 1553 |
1549 |
|
|
| 1554 |
1550 |
|
void |
| 1555 |
1551 |
|
setup(void) { |
| 1556 |
1552 |
|
unsigned int i; |
| 1557 |
|
- |
Monitor *m; |
|
1553 |
+ |
View *v; |
| 1558 |
1554 |
|
XSetWindowAttributes wa; |
| 1559 |
1555 |
|
XineramaScreenInfo *info = NULL; |
| 1560 |
1556 |
|
|
|
| 1571 |
1567 |
|
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); |
| 1572 |
1568 |
|
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); |
| 1573 |
1569 |
|
|
| 1574 |
|
- |
// init screens/monitors first |
| 1575 |
1570 |
|
if((isxinerama = XineramaIsActive(dpy))) |
| 1576 |
|
- |
info = XineramaQueryScreens(dpy, &mcount); |
| 1577 |
|
- |
selmonitor = monitors = emallocz(mcount * sizeof(Monitor)); |
|
1571 |
+ |
info = XineramaQueryScreens(dpy, &nviews); |
|
1572 |
+ |
#if defined(AIM_XINERAMA) |
|
1573 |
+ |
isxinerama = True; |
|
1574 |
+ |
nviews = 2; /* aim Xinerama */ |
|
1575 |
+ |
#endif |
|
1576 |
+ |
selview = views = emallocz(nviews * sizeof(View)); |
| 1578 |
1577 |
|
|
| 1579 |
1578 |
|
screen = DefaultScreen(dpy); |
| 1580 |
1579 |
|
root = RootWindow(dpy, screen); |
|
| 1599 |
1598 |
|
if(i > blw) |
| 1600 |
1599 |
|
blw = i; |
| 1601 |
1600 |
|
} |
| 1602 |
|
- |
for(i = 0; i < mcount; i++) { |
|
1601 |
+ |
|
|
1602 |
+ |
seltags = emallocz(sizeof initags); |
|
1603 |
+ |
prevtags = emallocz(sizeof initags); |
|
1604 |
+ |
memcpy(seltags, initags, sizeof initags); |
|
1605 |
+ |
memcpy(prevtags, initags, sizeof initags); |
|
1606 |
+ |
|
|
1607 |
+ |
for(i = 0; i < nviews; i++) { |
| 1603 |
1608 |
|
/* init geometry */ |
| 1604 |
|
- |
m = &monitors[i]; |
|
1609 |
+ |
v = &views[i]; |
|
1610 |
+ |
v->id = i + 1; |
|
1611 |
+ |
|
|
1612 |
+ |
if(nviews != 1 && isxinerama) { |
| 1605 |
1613 |
|
|
| 1606 |
|
- |
if(mcount != 1 && isxinerama) { |
| 1607 |
|
- |
m->sx = info[i].x_org; |
| 1608 |
|
- |
m->sy = info[i].y_org; |
| 1609 |
|
- |
m->sw = info[i].width; |
| 1610 |
|
- |
m->sh = info[i].height; |
| 1611 |
|
- |
fprintf(stderr, "monitor[%d]: %d,%d,%d,%d\n", i, m->sx, m->sy, m->sw, m->sh); |
|
1614 |
+ |
#if defined(AIM_XINERAMA) |
|
1615 |
+ |
v->w = DisplayWidth(dpy, screen) / 2; |
|
1616 |
+ |
v->x = (i == 0) ? 0 : v->w; |
|
1617 |
+ |
v->y = 0; |
|
1618 |
+ |
v->h = DisplayHeight(dpy, screen); |
|
1619 |
+ |
#else |
|
1620 |
+ |
v->x = info[i].x_org; |
|
1621 |
+ |
v->y = info[i].y_org; |
|
1622 |
+ |
v->w = info[i].width; |
|
1623 |
+ |
v->h = info[i].height; |
|
1624 |
+ |
#endif |
| 1612 |
1625 |
|
} |
| 1613 |
1626 |
|
else { |
| 1614 |
|
- |
m->sx = 0; |
| 1615 |
|
- |
m->sy = 0; |
| 1616 |
|
- |
m->sw = DisplayWidth(dpy, screen); |
| 1617 |
|
- |
m->sh = DisplayHeight(dpy, screen); |
|
1627 |
+ |
v->x = 0; |
|
1628 |
+ |
v->y = 0; |
|
1629 |
+ |
v->w = DisplayWidth(dpy, screen); |
|
1630 |
+ |
v->h = DisplayHeight(dpy, screen); |
| 1618 |
1631 |
|
} |
| 1619 |
1632 |
|
|
| 1620 |
|
- |
m->seltags = emallocz(sizeof initags); |
| 1621 |
|
- |
m->prevtags = emallocz(sizeof initags); |
| 1622 |
|
- |
|
| 1623 |
|
- |
memcpy(m->seltags, initags, sizeof initags); |
| 1624 |
|
- |
memcpy(m->prevtags, initags, sizeof initags); |
| 1625 |
|
- |
|
| 1626 |
1633 |
|
/* init layouts */ |
| 1627 |
|
- |
m->mwfact = MWFACT; |
| 1628 |
|
- |
m->layout = &layouts[0]; |
|
1634 |
+ |
v->mwfact = MWFACT; |
|
1635 |
+ |
v->layout = &layouts[0]; |
| 1629 |
1636 |
|
|
| 1630 |
1637 |
|
// TODO: bpos per screen? |
| 1631 |
1638 |
|
bpos = BARPOS; |
| 1632 |
1639 |
|
wa.override_redirect = 1; |
| 1633 |
1640 |
|
wa.background_pixmap = ParentRelative; |
| 1634 |
|
- |
wa.event_mask = ButtonPressMask | ExposureMask; |
|
1641 |
+ |
wa.event_mask = ButtonPressMask|ExposureMask; |
| 1635 |
1642 |
|
|
| 1636 |
1643 |
|
/* init bars */ |
| 1637 |
|
- |
m->barwin = XCreateWindow(dpy, root, m->sx, m->sy, m->sw, bh, 0, |
|
1644 |
+ |
v->barwin = XCreateWindow(dpy, root, v->x, v->y, v->w, bh, 0, |
| 1638 |
1645 |
|
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), |
| 1639 |
|
- |
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
| 1640 |
|
- |
XDefineCursor(dpy, m->barwin, cursor[CurNormal]); |
| 1641 |
|
- |
updatebarpos(m); |
| 1642 |
|
- |
XMapRaised(dpy, m->barwin); |
|
1646 |
+ |
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); |
|
1647 |
+ |
XDefineCursor(dpy, v->barwin, cursor[CurNormal]); |
|
1648 |
+ |
updatebarpos(v); |
|
1649 |
+ |
XMapRaised(dpy, v->barwin); |
| 1643 |
1650 |
|
strcpy(stext, "dwm-"VERSION); |
| 1644 |
1651 |
|
|
| 1645 |
|
- |
/* EWMH support per monitor */ |
|
1652 |
+ |
/* EWMH support per view */ |
| 1646 |
1653 |
|
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, |
| 1647 |
1654 |
|
PropModeReplace, (unsigned char *) netatom, NetLast); |
| 1648 |
1655 |
|
|
| 1649 |
1656 |
|
/* select for events */ |
| 1650 |
|
- |
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
| 1651 |
|
- |
| EnterWindowMask | LeaveWindowMask | StructureNotifyMask; |
| 1652 |
|
- |
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); |
|
1657 |
+ |
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask |
|
1658 |
+ |
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask; |
|
1659 |
+ |
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); |
| 1653 |
1660 |
|
XSelectInput(dpy, root, wa.event_mask); |
| 1654 |
1661 |
|
|
| 1655 |
|
- |
drawbar(m); |
|
1662 |
+ |
drawbar(v); |
| 1656 |
1663 |
|
} |
| 1657 |
1664 |
|
if(info) |
| 1658 |
1665 |
|
XFree(info); |
|
| 1663 |
1670 |
|
/* init tags */ |
| 1664 |
1671 |
|
compileregs(); |
| 1665 |
1672 |
|
|
| 1666 |
|
- |
selmonitor = monitorat(); |
| 1667 |
|
- |
fprintf(stderr, "selmonitor == %d\n", selmonitor - monitors); |
|
1673 |
+ |
selview = &views[0]; |
| 1668 |
1674 |
|
} |
| 1669 |
1675 |
|
|
| 1670 |
1676 |
|
void |
|
| 1698 |
1704 |
|
if(!sel) |
| 1699 |
1705 |
|
return; |
| 1700 |
1706 |
|
for(i = 0; i < LENGTH(tags); i++) |
| 1701 |
|
- |
sel->tags[i] = (NULL == arg); |
| 1702 |
|
- |
sel->tags[idxoftag(arg)] = True; |
| 1703 |
|
- |
arrange(sel->monitor); |
|
1707 |
+ |
sel->tags[i] = (NULL == arg) ? selview->id : 0; |
|
1708 |
+ |
sel->tags[idxoftag(arg)] = selview->id; |
|
1709 |
+ |
arrange(); |
| 1704 |
1710 |
|
} |
| 1705 |
1711 |
|
|
| 1706 |
1712 |
|
unsigned int |
|
| 1720 |
1726 |
|
} |
| 1721 |
1727 |
|
|
| 1722 |
1728 |
|
void |
| 1723 |
|
- |
tile(Monitor *m) { |
|
1729 |
+ |
tile(View *v) { |
| 1724 |
1730 |
|
unsigned int i, n, nx, ny, nw, nh, mw, th; |
| 1725 |
1731 |
|
Client *c, *mc; |
| 1726 |
1732 |
|
|
| 1727 |
1733 |
|
domwfact = dozoom = True; |
| 1728 |
|
- |
nx = m->wax; |
| 1729 |
|
- |
ny = m->way; |
|
1734 |
+ |
nx = v->wax; |
|
1735 |
+ |
ny = v->way; |
| 1730 |
1736 |
|
nw = 0; |
| 1731 |
|
- |
for(n = 0, c = nexttiled(clients, m); c; c = nexttiled(c->next, m)) |
|
1737 |
+ |
for(n = 0, c = nexttiled(clients, v); c; c = nexttiled(c->next, v)) |
| 1732 |
1738 |
|
n++; |
| 1733 |
1739 |
|
|
| 1734 |
1740 |
|
/* window geoms */ |
| 1735 |
|
- |
mw = (n == 1) ? m->waw : m->mwfact * m->waw; |
| 1736 |
|
- |
th = (n > 1) ? m->wah / (n - 1) : 0; |
|
1741 |
+ |
mw = (n == 1) ? v->waw : v->mwfact * v->waw; |
|
1742 |
+ |
th = (n > 1) ? v->wah / (n - 1) : 0; |
| 1737 |
1743 |
|
if(n > 1 && th < bh) |
| 1738 |
|
- |
th = m->wah; |
|
1744 |
+ |
th = v->wah; |
| 1739 |
1745 |
|
|
| 1740 |
|
- |
for(i = 0, c = mc = nexttiled(clients, m); c; c = nexttiled(c->next, m)) { |
|
1746 |
+ |
for(i = 0, c = mc = nexttiled(clients, v); c; c = nexttiled(c->next, v)) { |
| 1741 |
1747 |
|
if(i == 0) { /* master */ |
| 1742 |
|
- |
nx = m->wax; |
| 1743 |
|
- |
ny = m->way; |
|
1748 |
+ |
nx = v->wax; |
|
1749 |
+ |
ny = v->way; |
| 1744 |
1750 |
|
nw = mw - 2 * c->border; |
| 1745 |
|
- |
nh = m->wah - 2 * c->border; |
|
1751 |
+ |
nh = v->wah - 2 * c->border; |
| 1746 |
1752 |
|
} |
| 1747 |
1753 |
|
else { /* tile window */ |
| 1748 |
1754 |
|
if(i == 1) { |
| 1749 |
|
- |
ny = m->way; |
|
1755 |
+ |
ny = v->way; |
| 1750 |
1756 |
|
nx += mc->w + 2 * mc->border; |
| 1751 |
|
- |
nw = m->waw - mw - 2 * c->border; |
|
1757 |
+ |
nw = v->waw - mw - 2 * c->border; |
| 1752 |
1758 |
|
} |
| 1753 |
1759 |
|
if(i + 1 == n) /* remainder */ |
| 1754 |
|
- |
nh = (m->way + m->wah) - ny - 2 * c->border; |
|
1760 |
+ |
nh = (v->way + v->wah) - ny - 2 * c->border; |
| 1755 |
1761 |
|
else |
| 1756 |
1762 |
|
nh = th - 2 * c->border; |
| 1757 |
1763 |
|
} |
|
| 1760 |
1766 |
|
if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw))) |
| 1761 |
1767 |
|
/* client doesn't accept size constraints */ |
| 1762 |
1768 |
|
resize(c, nx, ny, nw, nh, False); |
| 1763 |
|
- |
if(n > 1 && th != m->wah) |
|
1769 |
+ |
if(n > 1 && th != v->wah) |
| 1764 |
1770 |
|
ny = c->y + c->h + 2 * c->border; |
| 1765 |
1771 |
|
i++; |
| 1766 |
1772 |
|
} |
|
| 1772 |
1778 |
|
bpos = (BARPOS == BarOff) ? BarTop : BARPOS; |
| 1773 |
1779 |
|
else |
| 1774 |
1780 |
|
bpos = BarOff; |
| 1775 |
|
- |
updatebarpos(monitorat()); |
| 1776 |
|
- |
arrange(monitorat()); |
|
1781 |
+ |
updatebarpos(selview); |
|
1782 |
+ |
arrange(); |
| 1777 |
1783 |
|
} |
| 1778 |
1784 |
|
|
| 1779 |
1785 |
|
void |
|
| 1783 |
1789 |
|
sel->isfloating = !sel->isfloating; |
| 1784 |
1790 |
|
if(sel->isfloating) |
| 1785 |
1791 |
|
resize(sel, sel->x, sel->y, sel->w, sel->h, True); |
| 1786 |
|
- |
arrange(sel->monitor); |
|
1792 |
+ |
arrange(); |
| 1787 |
1793 |
|
} |
| 1788 |
1794 |
|
|
| 1789 |
1795 |
|
void |
|
| 1796 |
1802 |
|
sel->tags[i] = !sel->tags[i]; |
| 1797 |
1803 |
|
for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++); |
| 1798 |
1804 |
|
if(j == LENGTH(tags)) |
| 1799 |
|
- |
sel->tags[i] = True; /* at least one tag must be enabled */ |
| 1800 |
|
- |
arrange(sel->monitor); |
|
1805 |
+ |
sel->tags[i] = selview->id; /* at least one tag must be enabled */ |
|
1806 |
+ |
arrange(); |
| 1801 |
1807 |
|
} |
| 1802 |
1808 |
|
|
| 1803 |
1809 |
|
void |
| 1804 |
1810 |
|
toggleview(const char *arg) { |
| 1805 |
1811 |
|
unsigned int i, j; |
| 1806 |
|
- |
Monitor *m = monitorat(); |
| 1807 |
1812 |
|
|
| 1808 |
1813 |
|
i = idxoftag(arg); |
| 1809 |
|
- |
m->seltags[i] = !m->seltags[i]; |
| 1810 |
|
- |
for(j = 0; j < LENGTH(tags) && !m->seltags[j]; j++); |
|
1814 |
+ |
seltags[i] = !seltags[i]; |
|
1815 |
+ |
for(j = 0; j < LENGTH(tags) && !seltags[j]; j++); |
| 1811 |
1816 |
|
if(j == LENGTH(tags)) |
| 1812 |
|
- |
m->seltags[i] = True; /* at least one tag must be viewed */ |
| 1813 |
|
- |
arrange(m); |
|
1817 |
+ |
seltags[i] = selview->id; /* at least one tag must be viewed */ |
|
1818 |
+ |
arrange(); |
| 1814 |
1819 |
|
} |
| 1815 |
1820 |
|
|
| 1816 |
1821 |
|
void |
|
| 1823 |
1828 |
|
|
| 1824 |
1829 |
|
void |
| 1825 |
1830 |
|
unmanage(Client *c) { |
| 1826 |
|
- |
Monitor *m = c->monitor; |
| 1827 |
1831 |
|
XWindowChanges wc; |
| 1828 |
1832 |
|
|
| 1829 |
1833 |
|
wc.border_width = c->oldborder; |
|
| 1842 |
1846 |
|
XSync(dpy, False); |
| 1843 |
1847 |
|
XSetErrorHandler(xerror); |
| 1844 |
1848 |
|
XUngrabServer(dpy); |
| 1845 |
|
- |
arrange(m); |
|
1849 |
+ |
arrange(); |
| 1846 |
1850 |
|
} |
| 1847 |
1851 |
|
|
| 1848 |
1852 |
|
void |
|
| 1855 |
1859 |
|
} |
| 1856 |
1860 |
|
|
| 1857 |
1861 |
|
void |
| 1858 |
|
- |
updatebarpos(Monitor *m) { |
|
1862 |
+ |
updatebarpos(View *v) { |
| 1859 |
1863 |
|
XEvent ev; |
| 1860 |
1864 |
|
|
| 1861 |
|
- |
m->wax = m->sx; |
| 1862 |
|
- |
m->way = m->sy; |
| 1863 |
|
- |
m->wah = m->sh; |
| 1864 |
|
- |
m->waw = m->sw; |
|
1865 |
+ |
v->wax = v->x; |
|
1866 |
+ |
v->way = v->y; |
|
1867 |
+ |
v->wah = v->h; |
|
1868 |
+ |
v->waw = v->w; |
| 1865 |
1869 |
|
switch(bpos) { |
| 1866 |
1870 |
|
default: |
| 1867 |
|
- |
m->wah -= bh; |
| 1868 |
|
- |
m->way += bh; |
| 1869 |
|
- |
XMoveWindow(dpy, m->barwin, m->sx, m->sy); |
|
1871 |
+ |
v->wah -= bh; |
|
1872 |
+ |
v->way += bh; |
|
1873 |
+ |
XMoveWindow(dpy, v->barwin, v->x, v->y); |
| 1870 |
1874 |
|
break; |
| 1871 |
1875 |
|
case BarBot: |
| 1872 |
|
- |
m->wah -= bh; |
| 1873 |
|
- |
XMoveWindow(dpy, m->barwin, m->sx, m->sy + m->wah); |
|
1876 |
+ |
v->wah -= bh; |
|
1877 |
+ |
XMoveWindow(dpy, v->barwin, v->x, v->y + v->wah); |
| 1874 |
1878 |
|
break; |
| 1875 |
1879 |
|
case BarOff: |
| 1876 |
|
- |
XMoveWindow(dpy, m->barwin, m->sx, m->sy - bh); |
|
1880 |
+ |
XMoveWindow(dpy, v->barwin, v->x, v->y - bh); |
| 1877 |
1881 |
|
break; |
| 1878 |
1882 |
|
} |
| 1879 |
1883 |
|
XSync(dpy, False); |
|
| 1968 |
1972 |
|
} |
| 1969 |
1973 |
|
|
| 1970 |
1974 |
|
int |
| 1971 |
|
- |
xerrordummy(Display *dsply, XErrorEvent *ee) { |
|
1975 |
+ |
xerrordummy(Display *dpy, XErrorEvent *ee) { |
| 1972 |
1976 |
|
return 0; |
| 1973 |
1977 |
|
} |
| 1974 |
1978 |
|
|
| 1975 |
1979 |
|
/* Startup Error handler to check if another window manager |
| 1976 |
1980 |
|
* is already running. */ |
| 1977 |
1981 |
|
int |
| 1978 |
|
- |
xerrorstart(Display *dsply, XErrorEvent *ee) { |
|
1982 |
+ |
xerrorstart(Display *dpy, XErrorEvent *ee) { |
| 1979 |
1983 |
|
otherwm = True; |
| 1980 |
1984 |
|
return -1; |
| 1981 |
1985 |
|
} |
|
| 1983 |
1987 |
|
void |
| 1984 |
1988 |
|
view(const char *arg) { |
| 1985 |
1989 |
|
unsigned int i; |
| 1986 |
|
- |
Bool tmp[LENGTH(tags)]; |
| 1987 |
|
- |
Monitor *m = monitorat(); |
|
1990 |
+ |
int tmp[LENGTH(tags)]; |
| 1988 |
1991 |
|
|
| 1989 |
1992 |
|
for(i = 0; i < LENGTH(tags); i++) |
| 1990 |
|
- |
tmp[i] = (NULL == arg); |
| 1991 |
|
- |
tmp[idxoftag(arg)] = True; |
| 1992 |
|
- |
if(memcmp(m->seltags, tmp, sizeof initags) != 0) { |
| 1993 |
|
- |
memcpy(m->prevtags, m->seltags, sizeof initags); |
| 1994 |
|
- |
memcpy(m->seltags, tmp, sizeof initags); |
| 1995 |
|
- |
arrange(m); |
|
1993 |
+ |
tmp[i] = (NULL == arg) ? selview->id : 0; |
|
1994 |
+ |
tmp[idxoftag(arg)] = selview->id; |
|
1995 |
+ |
if(memcmp(seltags, tmp, sizeof initags) != 0) { |
|
1996 |
+ |
memcpy(prevtags, seltags, sizeof initags); |
|
1997 |
+ |
memcpy(seltags, tmp, sizeof initags); |
|
1998 |
+ |
arrange(); |
| 1996 |
1999 |
|
} |
| 1997 |
2000 |
|
} |
| 1998 |
2001 |
|
|
|
| 2000 |
2003 |
|
viewprevtag(const char *arg) { |
| 2001 |
2004 |
|
static Bool tmp[LENGTH(tags)]; |
| 2002 |
2005 |
|
|
| 2003 |
|
- |
Monitor *m = monitorat(); |
| 2004 |
|
- |
|
| 2005 |
|
- |
memcpy(tmp, m->seltags, sizeof initags); |
| 2006 |
|
- |
memcpy(m->seltags, m->prevtags, sizeof initags); |
| 2007 |
|
- |
memcpy(m->prevtags, tmp, sizeof initags); |
| 2008 |
|
- |
arrange(m); |
|
2006 |
+ |
memcpy(tmp, seltags, sizeof initags); |
|
2007 |
+ |
memcpy(seltags, prevtags, sizeof initags); |
|
2008 |
+ |
memcpy(prevtags, tmp, sizeof initags); |
|
2009 |
+ |
arrange(); |
| 2009 |
2010 |
|
} |
| 2010 |
2011 |
|
|
| 2011 |
2012 |
|
void |
|
| 2014 |
2015 |
|
|
| 2015 |
2016 |
|
if(!sel || !dozoom || sel->isfloating) |
| 2016 |
2017 |
|
return; |
| 2017 |
|
- |
if(c == nexttiled(clients, c->monitor)) |
| 2018 |
|
- |
if(!(c = nexttiled(c->next, c->monitor))) |
|
2018 |
+ |
if(c == nexttiled(clients, getview(c))) |
|
2019 |
+ |
if(!(c = nexttiled(c->next, getview(c)))) |
| 2019 |
2020 |
|
return; |
| 2020 |
2021 |
|
detach(c); |
| 2021 |
2022 |
|
attach(c); |
| 2022 |
2023 |
|
focus(c); |
| 2023 |
|
- |
arrange(c->monitor); |
|
2024 |
+ |
arrange(); |
| 2024 |
2025 |
|
} |
| 2025 |
2026 |
|
|
| 2026 |
2027 |
|
void |
| 2027 |
|
- |
movetomonitor(const char *arg) { |
|
2028 |
+ |
selectview(const char *arg) { |
| 2028 |
2029 |
|
int i; |
|
2030 |
+ |
View *v; |
| 2029 |
2031 |
|
|
| 2030 |
|
- |
if (sel) |
|
2032 |
+ |
if(!arg) |
| 2031 |
2033 |
|
return; |
| 2032 |
2034 |
|
if(arg) |
| 2033 |
2035 |
|
i = atoi(arg); |
| 2034 |
|
- |
else { |
| 2035 |
|
- |
for(i = 0; &monitors[i] != sel->monitor && i < mcount; i++); |
| 2036 |
|
- |
i++; |
| 2037 |
|
- |
} |
| 2038 |
|
- |
sel->monitor = &monitors[i % mcount]; |
| 2039 |
|
- |
|
| 2040 |
|
- |
memcpy(sel->tags, sel->monitor->seltags, sizeof initags); |
| 2041 |
|
- |
resize(sel, sel->monitor->wax, sel->monitor->way, sel->w, sel->h, True); |
| 2042 |
|
- |
arrange(sel->monitor); |
| 2043 |
|
- |
} |
| 2044 |
|
- |
|
| 2045 |
|
- |
void |
| 2046 |
|
- |
selectmonitor(const char *arg) { |
| 2047 |
|
- |
int i; |
| 2048 |
|
- |
Monitor *m; |
| 2049 |
|
- |
|
| 2050 |
|
- |
if(arg) |
| 2051 |
|
- |
i = atoi(arg); |
| 2052 |
|
- |
else { |
| 2053 |
|
- |
for(i = 0; &monitors[i] != sel->monitor && i < mcount; i++); |
| 2054 |
|
- |
i++; |
| 2055 |
|
- |
} |
| 2056 |
|
- |
m = &monitors[i % mcount]; |
| 2057 |
|
- |
XWarpPointer(dpy, None, root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2); |
|
2036 |
+ |
v = &views[i % nviews]; |
|
2037 |
+ |
XWarpPointer(dpy, None, root, 0, 0, 0, 0, v->wax+v->waw/2, v->way+v->wah/2); |
| 2058 |
2038 |
|
focus(NULL); |
| 2059 |
2039 |
|
} |
| 2060 |
2040 |
|
|
| 2061 |
2041 |
|
|
| 2062 |
2042 |
|
int |
| 2063 |
2043 |
|
main(int argc, char *argv[]) { |
| 2064 |
|
- |
fprintf(stderr, "%u\n", sizeof("jsjsjsjsjssjsj")); |
| 2065 |
2044 |
|
if(argc == 2 && !strcmp("-v", argv[1])) |
| 2066 |
2045 |
|
eprint("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n"); |
| 2067 |
2046 |
|
else if(argc != 1) |