Mercurial > aewl
comparison client.c @ 76:4bd49f404f10
proceeded with cleaning up, sorting functions, etc
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Sat, 15 Jul 2006 17:00:56 +0200 |
parents | f08271b7cb20 |
children | 38c8f7f7d401 |
comparison
equal
deleted
inserted
replaced
75:f08271b7cb20 | 76:4bd49f404f10 |
---|---|
1 /* | 1 /* |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
3 * See LICENSE file for license details. | 3 * See LICENSE file for license details. |
4 */ | 4 */ |
5 #include "dwm.h" | |
5 | 6 |
6 #include <stdlib.h> | 7 #include <stdlib.h> |
7 #include <stdio.h> | |
8 #include <string.h> | 8 #include <string.h> |
9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
10 #include <X11/Xutil.h> | 10 #include <X11/Xutil.h> |
11 | 11 |
12 #include "dwm.h" | 12 /* static functions */ |
13 | |
14 void | |
15 ban(Client *c) | |
16 { | |
17 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
18 XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); | |
19 } | |
20 | 13 |
21 static void | 14 static void |
22 resizetitle(Client *c) | 15 resizetitle(Client *c) |
23 { | 16 { |
24 int i; | 17 int i; |
33 c->tx = c->x + c->w - c->tw + 2; | 26 c->tx = c->x + c->w - c->tw + 2; |
34 c->ty = c->y; | 27 c->ty = c->y; |
35 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); | 28 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); |
36 } | 29 } |
37 | 30 |
38 void | 31 static int |
39 settitle(Client *c) | 32 xerrordummy(Display *dsply, XErrorEvent *ee) |
40 { | 33 { |
41 XTextProperty name; | 34 return 0; |
42 int n; | 35 } |
43 char **list = NULL; | 36 |
44 | 37 /* extern functions */ |
45 name.nitems = 0; | 38 |
46 c->name[0] = 0; | 39 void |
47 XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); | 40 ban(Client *c) |
48 if(!name.nitems) | 41 { |
49 XGetWMName(dpy, c->win, &name); | 42 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); |
50 if(!name.nitems) | 43 XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); |
51 return; | |
52 if(name.encoding == XA_STRING) | |
53 strncpy(c->name, (char *)name.value, sizeof(c->name)); | |
54 else { | |
55 if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success | |
56 && n > 0 && *list) | |
57 { | |
58 strncpy(c->name, *list, sizeof(c->name)); | |
59 XFreeStringList(list); | |
60 } | |
61 } | |
62 XFree(name.value); | |
63 resizetitle(c); | |
64 } | |
65 | |
66 void | |
67 setsize(Client *c) | |
68 { | |
69 XSizeHints size; | |
70 long msize; | |
71 if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) | |
72 size.flags = PSize; | |
73 c->flags = size.flags; | |
74 if(c->flags & PBaseSize) { | |
75 c->basew = size.base_width; | |
76 c->baseh = size.base_height; | |
77 } | |
78 else | |
79 c->basew = c->baseh = 0; | |
80 if(c->flags & PResizeInc) { | |
81 c->incw = size.width_inc; | |
82 c->inch = size.height_inc; | |
83 } | |
84 else | |
85 c->incw = c->inch = 0; | |
86 if(c->flags & PMaxSize) { | |
87 c->maxw = size.max_width; | |
88 c->maxh = size.max_height; | |
89 } | |
90 else | |
91 c->maxw = c->maxh = 0; | |
92 if(c->flags & PMinSize) { | |
93 c->minw = size.min_width; | |
94 c->minh = size.min_height; | |
95 } | |
96 else | |
97 c->minw = c->minh = 0; | |
98 if(c->flags & PWinGravity) | |
99 c->grav = size.win_gravity; | |
100 else | |
101 c->grav = NorthWestGravity; | |
102 } | |
103 | |
104 void | |
105 higher(Client *c) | |
106 { | |
107 XRaiseWindow(dpy, c->win); | |
108 XRaiseWindow(dpy, c->title); | |
109 } | |
110 | |
111 void | |
112 lower(Client *c) | |
113 { | |
114 XLowerWindow(dpy, c->title); | |
115 XLowerWindow(dpy, c->win); | |
116 } | 44 } |
117 | 45 |
118 void | 46 void |
119 focus(Client *c) | 47 focus(Client *c) |
120 { | 48 { |
127 drawtitle(old); | 55 drawtitle(old); |
128 drawtitle(c); | 56 drawtitle(c); |
129 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | 57 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
130 XFlush(dpy); | 58 XFlush(dpy); |
131 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | 59 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
60 } | |
61 | |
62 void | |
63 focusnext(Arg *arg) | |
64 { | |
65 Client *c; | |
66 | |
67 if(!sel) | |
68 return; | |
69 | |
70 if(!(c = getnext(sel->next))) | |
71 c = getnext(clients); | |
72 if(c) { | |
73 higher(c); | |
74 c->revert = sel; | |
75 focus(c); | |
76 } | |
77 } | |
78 | |
79 void | |
80 focusprev(Arg *arg) | |
81 { | |
82 Client *c; | |
83 | |
84 if(!sel) | |
85 return; | |
86 | |
87 if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
88 higher(c); | |
89 focus(c); | |
90 } | |
91 } | |
92 | |
93 Client * | |
94 getclient(Window w) | |
95 { | |
96 Client *c; | |
97 for(c = clients; c; c = c->next) | |
98 if(c->win == w) | |
99 return c; | |
100 return NULL; | |
101 } | |
102 | |
103 Client * | |
104 getctitle(Window w) | |
105 { | |
106 Client *c; | |
107 for(c = clients; c; c = c->next) | |
108 if(c->title == w) | |
109 return c; | |
110 return NULL; | |
111 } | |
112 | |
113 void | |
114 gravitate(Client *c, Bool invert) | |
115 { | |
116 int dx = 0, dy = 0; | |
117 | |
118 switch(c->grav) { | |
119 case StaticGravity: | |
120 case NorthWestGravity: | |
121 case NorthGravity: | |
122 case NorthEastGravity: | |
123 dy = c->border; | |
124 break; | |
125 case EastGravity: | |
126 case CenterGravity: | |
127 case WestGravity: | |
128 dy = -(c->h / 2) + c->border; | |
129 break; | |
130 case SouthEastGravity: | |
131 case SouthGravity: | |
132 case SouthWestGravity: | |
133 dy = -c->h; | |
134 break; | |
135 default: | |
136 break; | |
137 } | |
138 | |
139 switch (c->grav) { | |
140 case StaticGravity: | |
141 case NorthWestGravity: | |
142 case WestGravity: | |
143 case SouthWestGravity: | |
144 dx = c->border; | |
145 break; | |
146 case NorthGravity: | |
147 case CenterGravity: | |
148 case SouthGravity: | |
149 dx = -(c->w / 2) + c->border; | |
150 break; | |
151 case NorthEastGravity: | |
152 case EastGravity: | |
153 case SouthEastGravity: | |
154 dx = -(c->w + c->border); | |
155 break; | |
156 default: | |
157 break; | |
158 } | |
159 | |
160 if(invert) { | |
161 dx = -dx; | |
162 dy = -dy; | |
163 } | |
164 c->x += dx; | |
165 c->y += dy; | |
166 } | |
167 | |
168 void | |
169 higher(Client *c) | |
170 { | |
171 XRaiseWindow(dpy, c->win); | |
172 XRaiseWindow(dpy, c->title); | |
173 } | |
174 | |
175 void | |
176 killclient(Arg *arg) | |
177 { | |
178 if(!sel) | |
179 return; | |
180 if(sel->proto & WM_PROTOCOL_DELWIN) | |
181 sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
182 else | |
183 XKillClient(dpy, sel->win); | |
184 } | |
185 | |
186 void | |
187 lower(Client *c) | |
188 { | |
189 XLowerWindow(dpy, c->title); | |
190 XLowerWindow(dpy, c->win); | |
132 } | 191 } |
133 | 192 |
134 void | 193 void |
135 manage(Window w, XWindowAttributes *wa) | 194 manage(Window w, XWindowAttributes *wa) |
136 { | 195 { |
193 XMapRaised(dpy, c->title); | 252 XMapRaised(dpy, c->title); |
194 } | 253 } |
195 } | 254 } |
196 | 255 |
197 void | 256 void |
198 gravitate(Client *c, Bool invert) | 257 maximize(Arg *arg) |
199 { | 258 { |
200 int dx = 0, dy = 0; | 259 if(!sel) |
201 | 260 return; |
202 switch(c->grav) { | 261 sel->x = sx; |
203 case StaticGravity: | 262 sel->y = sy + bh; |
204 case NorthWestGravity: | 263 sel->w = sw - 2 * sel->border; |
205 case NorthGravity: | 264 sel->h = sh - 2 * sel->border - bh; |
206 case NorthEastGravity: | 265 higher(sel); |
207 dy = c->border; | 266 resize(sel, False); |
208 break; | 267 } |
209 case EastGravity: | |
210 case CenterGravity: | |
211 case WestGravity: | |
212 dy = -(c->h / 2) + c->border; | |
213 break; | |
214 case SouthEastGravity: | |
215 case SouthGravity: | |
216 case SouthWestGravity: | |
217 dy = -c->h; | |
218 break; | |
219 default: | |
220 break; | |
221 } | |
222 | |
223 switch (c->grav) { | |
224 case StaticGravity: | |
225 case NorthWestGravity: | |
226 case WestGravity: | |
227 case SouthWestGravity: | |
228 dx = c->border; | |
229 break; | |
230 case NorthGravity: | |
231 case CenterGravity: | |
232 case SouthGravity: | |
233 dx = -(c->w / 2) + c->border; | |
234 break; | |
235 case NorthEastGravity: | |
236 case EastGravity: | |
237 case SouthEastGravity: | |
238 dx = -(c->w + c->border); | |
239 break; | |
240 default: | |
241 break; | |
242 } | |
243 | |
244 if(invert) { | |
245 dx = -dx; | |
246 dy = -dy; | |
247 } | |
248 c->x += dx; | |
249 c->y += dy; | |
250 } | |
251 | |
252 | 268 |
253 void | 269 void |
254 resize(Client *c, Bool inc) | 270 resize(Client *c, Bool inc) |
255 { | 271 { |
256 XConfigureEvent e; | 272 XConfigureEvent e; |
288 e.override_redirect = False; | 304 e.override_redirect = False; |
289 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e); | 305 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e); |
290 XFlush(dpy); | 306 XFlush(dpy); |
291 } | 307 } |
292 | 308 |
293 static int | 309 void |
294 xerrordummy(Display *dsply, XErrorEvent *ee) | 310 setsize(Client *c) |
295 { | 311 { |
296 return 0; | 312 XSizeHints size; |
313 long msize; | |
314 if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) | |
315 size.flags = PSize; | |
316 c->flags = size.flags; | |
317 if(c->flags & PBaseSize) { | |
318 c->basew = size.base_width; | |
319 c->baseh = size.base_height; | |
320 } | |
321 else | |
322 c->basew = c->baseh = 0; | |
323 if(c->flags & PResizeInc) { | |
324 c->incw = size.width_inc; | |
325 c->inch = size.height_inc; | |
326 } | |
327 else | |
328 c->incw = c->inch = 0; | |
329 if(c->flags & PMaxSize) { | |
330 c->maxw = size.max_width; | |
331 c->maxh = size.max_height; | |
332 } | |
333 else | |
334 c->maxw = c->maxh = 0; | |
335 if(c->flags & PMinSize) { | |
336 c->minw = size.min_width; | |
337 c->minh = size.min_height; | |
338 } | |
339 else | |
340 c->minw = c->minh = 0; | |
341 if(c->flags & PWinGravity) | |
342 c->grav = size.win_gravity; | |
343 else | |
344 c->grav = NorthWestGravity; | |
345 } | |
346 | |
347 void | |
348 settitle(Client *c) | |
349 { | |
350 XTextProperty name; | |
351 int n; | |
352 char **list = NULL; | |
353 | |
354 name.nitems = 0; | |
355 c->name[0] = 0; | |
356 XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); | |
357 if(!name.nitems) | |
358 XGetWMName(dpy, c->win, &name); | |
359 if(!name.nitems) | |
360 return; | |
361 if(name.encoding == XA_STRING) | |
362 strncpy(c->name, (char *)name.value, sizeof(c->name)); | |
363 else { | |
364 if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success | |
365 && n > 0 && *list) | |
366 { | |
367 strncpy(c->name, *list, sizeof(c->name)); | |
368 XFreeStringList(list); | |
369 } | |
370 } | |
371 XFree(name.value); | |
372 resizetitle(c); | |
297 } | 373 } |
298 | 374 |
299 void | 375 void |
300 unmanage(Client *c) | 376 unmanage(Client *c) |
301 { | 377 { |
323 arrange(NULL); | 399 arrange(NULL); |
324 if(sel) | 400 if(sel) |
325 focus(sel); | 401 focus(sel); |
326 } | 402 } |
327 | 403 |
328 Client * | |
329 getctitle(Window w) | |
330 { | |
331 Client *c; | |
332 for(c = clients; c; c = c->next) | |
333 if(c->title == w) | |
334 return c; | |
335 return NULL; | |
336 } | |
337 | |
338 Client * | |
339 getclient(Window w) | |
340 { | |
341 Client *c; | |
342 for(c = clients; c; c = c->next) | |
343 if(c->win == w) | |
344 return c; | |
345 return NULL; | |
346 } | |
347 | |
348 void | 404 void |
349 zoom(Arg *arg) | 405 zoom(Arg *arg) |
350 { | 406 { |
351 Client **l, *c; | 407 Client **l, *c; |
352 | 408 |
364 sel->next = clients; /* pop */ | 420 sel->next = clients; /* pop */ |
365 clients = sel; | 421 clients = sel; |
366 arrange(NULL); | 422 arrange(NULL); |
367 focus(sel); | 423 focus(sel); |
368 } | 424 } |
369 | |
370 void | |
371 maximize(Arg *arg) | |
372 { | |
373 if(!sel) | |
374 return; | |
375 sel->x = sx; | |
376 sel->y = sy + bh; | |
377 sel->w = sw - 2 * sel->border; | |
378 sel->h = sh - 2 * sel->border - bh; | |
379 higher(sel); | |
380 resize(sel, False); | |
381 } | |
382 | |
383 void | |
384 focusprev(Arg *arg) | |
385 { | |
386 Client *c; | |
387 | |
388 if(!sel) | |
389 return; | |
390 | |
391 if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
392 higher(c); | |
393 focus(c); | |
394 } | |
395 } | |
396 | |
397 void | |
398 focusnext(Arg *arg) | |
399 { | |
400 Client *c; | |
401 | |
402 if(!sel) | |
403 return; | |
404 | |
405 if(!(c = getnext(sel->next))) | |
406 c = getnext(clients); | |
407 if(c) { | |
408 higher(c); | |
409 c->revert = sel; | |
410 focus(c); | |
411 } | |
412 } | |
413 | |
414 void | |
415 killclient(Arg *arg) | |
416 { | |
417 if(!sel) | |
418 return; | |
419 if(sel->proto & WM_PROTOCOL_DELWIN) | |
420 sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
421 else | |
422 XKillClient(dpy, sel->win); | |
423 } |