Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 545 lines (455 sloc) 12.771 kB
3d12c94 Initial revision
bernd authored
1 /*
2 * calmwm - the calm window manager
3 *
4 * Copyright (c) 2004 Andy Adamson <dros@monkey.org>
5 * Copyright (c) 2004,2005 Marius Aamodt Eriksen <marius@monkey.org>
e5cabb0 - Remove the "all rights reserved" tag at the top of most of the source
oga authored
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3d12c94 Initial revision
bernd authored
18 *
19 * $Id$
20 */
21
22 #include "headers.h"
23 #include "calmwm.h"
24
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
25 static void group_add(struct group_ctx *, struct client_ctx *);
26 static void group_remove(struct client_ctx *);
134e777 finish unfucking the screen_ctx handling.
oga authored
27 static void group_hide(struct screen_ctx *, struct group_ctx *);
28 static void group_show(struct screen_ctx *, struct group_ctx *);
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
29 static void group_fix_hidden_state(struct group_ctx *);
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
30 static void group_setactive(struct screen_ctx *, long);
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
31 static void group_set_names(struct screen_ctx *);
49e218c - add missing prototypes.
okan authored
32
d1050af shortcut_to_name should not be defined as static in a header file. Put
oga authored
33 const char *shortcut_to_name[] = {
49e218c - add missing prototypes.
okan authored
34 "nogroup", "one", "two", "three", "four", "five", "six",
35 "seven", "eight", "nine"
d1050af shortcut_to_name should not be defined as static in a header file. Put
oga authored
36 };
37
3d12c94 Initial revision
bernd authored
38 static void
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
39 group_add(struct group_ctx *gc, struct client_ctx *cc)
3d12c94 Initial revision
bernd authored
40 {
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
41 long no;
3d12c94 Initial revision
bernd authored
42 if (cc == NULL || gc == NULL)
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
43 errx(1, "group_add: a ctx is NULL");
3d12c94 Initial revision
bernd authored
44
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
45 no = gc->shortcut - 1;
46
3d12c94 Initial revision
bernd authored
47 if (cc->group == gc)
48 return;
49
50 if (cc->group != NULL)
51 TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
52
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
53 XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING,
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
54 8, PropModeReplace, shortcut_to_name[gc->shortcut],
55 strlen(shortcut_to_name[gc->shortcut]));
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
56 XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL,
57 32, PropModeReplace, (unsigned char *)&no, 1);
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
58
3d12c94 Initial revision
bernd authored
59 TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
60 cc->group = gc;
61 }
62
63 static void
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
64 group_remove(struct client_ctx *cc)
3d12c94 Initial revision
bernd authored
65 {
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
66 long no = 0xffffffff;
67
3d12c94 Initial revision
bernd authored
68 if (cc == NULL || cc->group == NULL)
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
69 errx(1, "group_remove: a ctx is NULL");
3d12c94 Initial revision
bernd authored
70
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
71 XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING, 8,
72 PropModeReplace, shortcut_to_name[0],
73 strlen(shortcut_to_name[0]));
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
74 XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL,
75 32, PropModeReplace, (unsigned char *)&no, 1);
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
76
3d12c94 Initial revision
bernd authored
77 TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
78 cc->group = NULL;
79 }
80
81 static void
134e777 finish unfucking the screen_ctx handling.
oga authored
82 group_hide(struct screen_ctx *sc, struct group_ctx *gc)
3d12c94 Initial revision
bernd authored
83 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
84 struct client_ctx *cc;
3d12c94 Initial revision
bernd authored
85
134e777 finish unfucking the screen_ctx handling.
oga authored
86 screen_updatestackingorder(sc);
3d12c94 Initial revision
bernd authored
87
88 gc->nhidden = 0;
89 gc->highstack = 0;
90 TAILQ_FOREACH(cc, &gc->clients, group_entry) {
91 client_hide(cc);
92 gc->nhidden++;
93 if (cc->stackingorder > gc->highstack)
94 gc->highstack = cc->stackingorder;
95 }
96 gc->hidden = 1; /* XXX: equivalent to gc->nhidden > 0 */
97 }
98
99 static void
134e777 finish unfucking the screen_ctx handling.
oga authored
100 group_show(struct screen_ctx *sc, struct group_ctx *gc)
3d12c94 Initial revision
bernd authored
101 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
102 struct client_ctx *cc;
103 Window *winlist;
104 u_int i;
105 int lastempty = -1;
3d12c94 Initial revision
bernd authored
106
f473dc3 Replace a few leftover calls to strdup and calloc with xstrdup and xc…
oga authored
107 winlist = (Window *) xcalloc(sizeof(*winlist), (gc->highstack + 1));
3d12c94 Initial revision
bernd authored
108
109 /*
110 * Invert the stacking order as XRestackWindows() expects them
111 * top-to-bottom.
112 */
113 TAILQ_FOREACH(cc, &gc->clients, group_entry) {
ec8e605 remove pwin, bringing us to one client, one window. we no longer have
okan authored
114 winlist[gc->highstack - cc->stackingorder] = cc->win;
3d12c94 Initial revision
bernd authored
115 client_unhide(cc);
116 }
117
118 /* Un-sparseify */
119 for (i = 0; i <= gc->highstack; i++) {
120 if (!winlist[i] && lastempty == -1)
121 lastempty = i;
122 else if (winlist[i] && lastempty != -1) {
123 winlist[lastempty] = winlist[i];
124 if (++lastempty == i)
125 lastempty = -1;
126 }
127 }
128
9006bbf convert globals from G_foo to Foo, as per TODO.
jasper authored
129 XRestackWindows(X_Dpy, winlist, gc->nhidden);
3d12c94 Initial revision
bernd authored
130 xfree(winlist);
131
132 gc->hidden = 0;
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
133 group_setactive(sc, gc->shortcut - 1);
3d12c94 Initial revision
bernd authored
134 }
135
136 void
134e777 finish unfucking the screen_ctx handling.
oga authored
137 group_init(struct screen_ctx *sc)
3d12c94 Initial revision
bernd authored
138 {
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
139 int i;
140 long viewports[2] = {0, 0};
141 long ndesks = CALMWM_NGROUPS, zero = 0;
3d12c94 Initial revision
bernd authored
142
134e777 finish unfucking the screen_ctx handling.
oga authored
143 TAILQ_INIT(&sc->groupq);
144 sc->group_hideall = 0;
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
145 /* see if any group names have already been set and update the property
146 * with ours if they'll have changed.
147 */
148 group_update_names(sc);
3d12c94 Initial revision
bernd authored
149
150 for (i = 0; i < CALMWM_NGROUPS; i++) {
134e777 finish unfucking the screen_ctx handling.
oga authored
151 TAILQ_INIT(&sc->groups[i].clients);
152 sc->groups[i].hidden = 0;
153 sc->groups[i].shortcut = i + 1;
154 TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
3d12c94 Initial revision
bernd authored
155 }
156
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
157 /* we don't support large desktops, so this is always (0, 0) */
158 XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_VIEWPORT,
159 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
160 XChangeProperty(X_Dpy, sc->rootwin, _NET_NUMBER_OF_DESKTOPS,
161 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1);
9b04930 Implement _NET_VIRTUAL_ROOTS (just clear it, we don't use that techni…
oga authored
162 /*
163 * we don't use virtual roots, so make sure it's not there from a
164 * previous wm.
165 */
166 XDeleteProperty(X_Dpy, sc->rootwin, _NET_VIRTUAL_ROOTS);
167 /*
168 * We don't really have a ``showing desktop'' mode, so this is zero
169 * always. XXX Note that when we hide all groups, or when all groups
170 * are hidden we could technically set this later on.
171 */
172 XChangeProperty(X_Dpy, sc->rootwin, _NET_SHOWING_DESKTOP,
173 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1);
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
174 group_setactive(sc, 0);
175 }
176
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
177 void
178 group_make_autogroup(struct conf *conf, char *class, int no)
179 {
180 struct autogroupwin *aw;
181 char *p;
182
183 aw = xcalloc(1, sizeof(*aw));
184
185 if ((p = strchr(class, ',')) == NULL) {
186 aw->name = NULL;
187 aw->class = xstrdup(class);
188 } else {
189 *(p++) = '\0';
190 aw->name = xstrdup(class);
191 aw->class = xstrdup(p);
192 }
193 aw->num = no;
194
195 TAILQ_INSERT_TAIL(&conf->autogroupq, aw, entry);
196
197 }
198
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
199 static void
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
200 group_setactive(struct screen_ctx *sc, long idx)
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
201 {
202 sc->group_active = &sc->groups[idx];
203 XChangeProperty(X_Dpy, sc->rootwin, _NET_CURRENT_DESKTOP,
204 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1);
eb78032 add a "movetogroup" function, which hides the current window from
sthen authored
205 }
206
207 void
208 group_movetogroup(struct client_ctx *cc, int idx)
209 {
134e777 finish unfucking the screen_ctx handling.
oga authored
210 struct screen_ctx *sc = cc->sc;
211
eb78032 add a "movetogroup" function, which hides the current window from
sthen authored
212 if (idx < 0 || idx >= CALMWM_NGROUPS)
213 err(1, "group_movetogroup: index out of range (%d)", idx);
214
134e777 finish unfucking the screen_ctx handling.
oga authored
215 if(sc->group_active != &sc->groups[idx])
8bbc376 In movetogroup, check the window's current group and skip client_hide()
sthen authored
216 client_hide(cc);
134e777 finish unfucking the screen_ctx handling.
oga authored
217 group_add(&sc->groups[idx], cc);
3d12c94 Initial revision
bernd authored
218 }
219
36c1aac Rip out, burn, and dance around the grave of group-edit mode.
oga authored
220 /*
221 * Colouring for groups upon add/remove.
3d12c94 Initial revision
bernd authored
222 */
223 void
224 group_sticky_toggle_enter(struct client_ctx *cc)
225 {
134e777 finish unfucking the screen_ctx handling.
oga authored
226 struct screen_ctx *sc = cc->sc;
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
227 struct group_ctx *gc;
228
134e777 finish unfucking the screen_ctx handling.
oga authored
229 gc = sc->group_active;
3d12c94 Initial revision
bernd authored
230
231 if (gc == cc->group) {
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
232 group_remove(cc);
4d5dc5d a long time coming - re-work the way we deal with colors: since we're
okan authored
233 cc->highlight = CLIENT_HIGHLIGHT_UNGROUP;
3d12c94 Initial revision
bernd authored
234 } else {
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
235 group_add(gc, cc);
4d5dc5d a long time coming - re-work the way we deal with colors: since we're
okan authored
236 cc->highlight = CLIENT_HIGHLIGHT_GROUP;
3d12c94 Initial revision
bernd authored
237 }
238
239 client_draw_border(cc);
240 }
241
242 void
243 group_sticky_toggle_exit(struct client_ctx *cc)
244 {
245 cc->highlight = 0;
246 client_draw_border(cc);
247 }
248
249 /*
49e218c - add missing prototypes.
okan authored
250 * if group_hidetoggle would produce no effect, toggle the group's hidden state
3d12c94 Initial revision
bernd authored
251 */
49e218c - add missing prototypes.
okan authored
252 static void
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
253 group_fix_hidden_state(struct group_ctx *gc)
3d12c94 Initial revision
bernd authored
254 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
255 struct client_ctx *cc;
256 int same = 0;
3d12c94 Initial revision
bernd authored
257
258 TAILQ_FOREACH(cc, &gc->clients, group_entry) {
259 if (gc->hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0))
260 same++;
261 }
262
263 if (same == 0)
264 gc->hidden = !gc->hidden;
265 }
266
267 void
134e777 finish unfucking the screen_ctx handling.
oga authored
268 group_hidetoggle(struct screen_ctx *sc, int idx)
3d12c94 Initial revision
bernd authored
269 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
270 struct group_ctx *gc;
3d12c94 Initial revision
bernd authored
271
272 if (idx < 0 || idx >= CALMWM_NGROUPS)
273 err(1, "group_hidetoggle: index out of range (%d)", idx);
274
134e777 finish unfucking the screen_ctx handling.
oga authored
275 gc = &sc->groups[idx];
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
276 group_fix_hidden_state(gc);
3d12c94 Initial revision
bernd authored
277
278 if (gc->hidden)
134e777 finish unfucking the screen_ctx handling.
oga authored
279 group_show(sc, gc);
3d12c94 Initial revision
bernd authored
280 else {
134e777 finish unfucking the screen_ctx handling.
oga authored
281 group_hide(sc, gc);
282 /* XXX wtf? */
3d12c94 Initial revision
bernd authored
283 if (TAILQ_EMPTY(&gc->clients))
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
284 group_setactive(sc, idx);
3d12c94 Initial revision
bernd authored
285 }
286 }
287
3de90d4 Add a new command (currently no default keybindings for it), grouponl…
oga authored
288 void
134e777 finish unfucking the screen_ctx handling.
oga authored
289 group_only(struct screen_ctx *sc, int idx)
3de90d4 Add a new command (currently no default keybindings for it), grouponl…
oga authored
290 {
291 int i;
292
293 if (idx < 0 || idx >= CALMWM_NGROUPS)
294 err(1, "group_only: index out of range (%d)", idx);
295
296 for (i = 0; i < CALMWM_NGROUPS; i++) {
5d51c8e minor bit of knf, just to be consistent; oga@ doesn't mind that much
okan authored
297 if (i == idx)
134e777 finish unfucking the screen_ctx handling.
oga authored
298 group_show(sc, &sc->groups[i]);
5d51c8e minor bit of knf, just to be consistent; oga@ doesn't mind that much
okan authored
299 else
134e777 finish unfucking the screen_ctx handling.
oga authored
300 group_hide(sc, &sc->groups[i]);
3de90d4 Add a new command (currently no default keybindings for it), grouponl…
oga authored
301 }
302 }
303
3d12c94 Initial revision
bernd authored
304 /*
d347aa3 as done with cycle/rcycle, make prev/next group switching one kbfuncs
okan authored
305 * Cycle through active groups. If none exist, then just stay put.
3d12c94 Initial revision
bernd authored
306 */
307 void
134e777 finish unfucking the screen_ctx handling.
oga authored
308 group_cycle(struct screen_ctx *sc, int reverse)
3d12c94 Initial revision
bernd authored
309 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
310 struct group_ctx *gc, *showgroup = NULL;
3d12c94 Initial revision
bernd authored
311
134e777 finish unfucking the screen_ctx handling.
oga authored
312 assert(sc->group_active != NULL);
3d12c94 Initial revision
bernd authored
313
134e777 finish unfucking the screen_ctx handling.
oga authored
314 gc = sc->group_active;
3d12c94 Initial revision
bernd authored
315 for (;;) {
d347aa3 as done with cycle/rcycle, make prev/next group switching one kbfuncs
okan authored
316 gc = reverse ? TAILQ_PREV(gc, group_ctx_q, entry) :
317 TAILQ_NEXT(gc, entry);
3d12c94 Initial revision
bernd authored
318 if (gc == NULL)
134e777 finish unfucking the screen_ctx handling.
oga authored
319 gc = reverse ? TAILQ_LAST(&sc->groupq, group_ctx_q) :
320 TAILQ_FIRST(&sc->groupq);
321 if (gc == sc->group_active)
3d12c94 Initial revision
bernd authored
322 break;
323
324 if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL)
325 showgroup = gc;
326 else if (!gc->hidden)
134e777 finish unfucking the screen_ctx handling.
oga authored
327 group_hide(sc, gc);
3d12c94 Initial revision
bernd authored
328 }
329
330 if (showgroup == NULL)
331 return;
332
134e777 finish unfucking the screen_ctx handling.
oga authored
333 group_hide(sc, sc->group_active);
3d12c94 Initial revision
bernd authored
334
335 if (showgroup->hidden)
134e777 finish unfucking the screen_ctx handling.
oga authored
336 group_show(sc, showgroup);
3d12c94 Initial revision
bernd authored
337 else
a7c3a7c Implement _NET_CURRENT_DESKTOP, _NET_DESKTOP_VIEWPORT and
oga authored
338 group_setactive(sc, showgroup->shortcut - 1);
3d12c94 Initial revision
bernd authored
339 }
340
341 /* called when a client is deleted */
342 void
343 group_client_delete(struct client_ctx *cc)
344 {
345 if (cc->group == NULL)
75182c6 hit it with the knf stick.
oga authored
346 return;
3d12c94 Initial revision
bernd authored
347
348 TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
349 cc->group = NULL; /* he he */
350 }
351
352 void
353 group_menu(XButtonEvent *e)
354 {
134e777 finish unfucking the screen_ctx handling.
oga authored
355 struct screen_ctx *sc;
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
356 struct group_ctx *gc;
75182c6 hit it with the knf stick.
oga authored
357 struct menu *mi;
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
358 struct menu_q menuq;
75182c6 hit it with the knf stick.
oga authored
359 int i;
3d12c94 Initial revision
bernd authored
360
134e777 finish unfucking the screen_ctx handling.
oga authored
361 sc = screen_fromroot(e->root);
3d12c94 Initial revision
bernd authored
362 TAILQ_INIT(&menuq);
363
364 for (i = 0; i < CALMWM_NGROUPS; i++) {
134e777 finish unfucking the screen_ctx handling.
oga authored
365 gc = &sc->groups[i];
3d12c94 Initial revision
bernd authored
366
367 if (TAILQ_EMPTY(&gc->clients))
368 continue;
369
58d1213 unroll XCALLOC/XMALLOC macros; since we use xcalloc/xmalloc all over the
okan authored
370 mi = xcalloc(1, sizeof(*mi));
3d12c94 Initial revision
bernd authored
371 if (gc->hidden)
372 snprintf(mi->text, sizeof(mi->text), "%d: [%s]",
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
373 gc->shortcut, sc->group_names[i]);
3d12c94 Initial revision
bernd authored
374 else
375 snprintf(mi->text, sizeof(mi->text), "%d: %s",
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
376 gc->shortcut, sc->group_names[i]);
3d12c94 Initial revision
bernd authored
377 mi->ctx = gc;
378 TAILQ_INSERT_TAIL(&menuq, mi, entry);
379 }
380
381 if (TAILQ_EMPTY(&menuq))
382 return;
383
134e777 finish unfucking the screen_ctx handling.
oga authored
384 mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL);
3d12c94 Initial revision
bernd authored
385
386 if (mi == NULL || mi->ctx == NULL)
387 goto cleanup;
388
389 gc = (struct group_ctx *)mi->ctx;
390
134e777 finish unfucking the screen_ctx handling.
oga authored
391 (gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc);
3d12c94 Initial revision
bernd authored
392
5034a77 KNF, no binary change.
oga authored
393 cleanup:
3d12c94 Initial revision
bernd authored
394 while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
395 TAILQ_REMOVE(&menuq, mi, entry);
396 xfree(mi);
397 }
398 }
399
400 void
134e777 finish unfucking the screen_ctx handling.
oga authored
401 group_alltoggle(struct screen_ctx *sc)
3d12c94 Initial revision
bernd authored
402 {
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
403 int i;
3d12c94 Initial revision
bernd authored
404
75182c6 hit it with the knf stick.
oga authored
405 for (i = 0; i < CALMWM_NGROUPS; i++) {
134e777 finish unfucking the screen_ctx handling.
oga authored
406 if (sc->group_hideall)
407 group_show(sc, &sc->groups[i]);
3d12c94 Initial revision
bernd authored
408 else
134e777 finish unfucking the screen_ctx handling.
oga authored
409 group_hide(sc, &sc->groups[i]);
3d12c94 Initial revision
bernd authored
410 }
411
134e777 finish unfucking the screen_ctx handling.
oga authored
412 sc->group_hideall = (!sc->group_hideall);
3d12c94 Initial revision
bernd authored
413 }
414
415 void
416 group_autogroup(struct client_ctx *cc)
417 {
134e777 finish unfucking the screen_ctx handling.
oga authored
418 struct screen_ctx *sc = cc->sc;
b23fad3 spacing, declaration lineup to be consistent throughout cwm,
okan authored
419 struct autogroupwin *aw;
420 struct group_ctx *gc;
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
421 int no = -1, i;
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
422 long *grpno;
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
423 unsigned char *grpstr = NULL;
3d12c94 Initial revision
bernd authored
424
425 if (cc->app_class == NULL || cc->app_name == NULL)
426 return;
a0ec251 implement support for _NET_WM_DESKTOP properties on windows.
oga authored
427 if (xu_getprop(cc, _NET_WM_DESKTOP, XA_CARDINAL,
428 1, (unsigned char **)&grpno) > 0) {
429 if (*grpno == 0xffffffff)
430 no = 0;
431 else if (*grpno > CALMWM_NGROUPS || *grpno < 0)
432 no = CALMWM_NGROUPS - 1;
433 else
434 no = *grpno + 1;
435 XFree(grpno);
436 } else if (xu_getprop(cc, _CWM_GRP, XA_STRING,
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
437 (CALMWM_MAXNAMELEN - 1)/sizeof(long), &grpstr) > 0) {
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
438 for (i = 0; i < sizeof(shortcut_to_name) /
439 sizeof(shortcut_to_name[0]); i++) {
440 if (strcmp(shortcut_to_name[i], grpstr) == 0)
441 no = i;
442 }
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
443 XFree(grpstr);
444 } else {
445 TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
446 if (strcmp(aw->class, cc->app_class) == 0 &&
447 (aw->name == NULL ||
448 strcmp(aw->name, cc->app_name) == 0)) {
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
449 no = aw->num;
c750462 One of the most annoying things to do was restart cwm and lose all of
oga authored
450 break;
451 }
3d12c94 Initial revision
bernd authored
452 }
453 }
454
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
455 /* no group please */
456 if (no == 0)
71f99ab allow an autogroup value of 0 to mean no group. This means you can set
oga authored
457 return;
458
134e777 finish unfucking the screen_ctx handling.
oga authored
459 TAILQ_FOREACH(gc, &sc->groupq, entry) {
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
460 if (gc->shortcut == no) {
2c29a1d nuke the leading underscore notation for local static functions - there
okan authored
461 group_add(gc, cc);
38ff7a9 allow autogrouping and sticky mode to work together
okan authored
462 return;
463 }
3d12c94 Initial revision
bernd authored
464 }
465
38ff7a9 allow autogrouping and sticky mode to work together
okan authored
466 if (Conf.flags & CONF_STICKY_GROUPS)
134e777 finish unfucking the screen_ctx handling.
oga authored
467 group_add(sc->group_active, cc);
38ff7a9 allow autogrouping and sticky mode to work together
okan authored
468
3d12c94 Initial revision
bernd authored
469 }
b35cbf8 Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
oga authored
470
471 void
472 group_update_names(struct screen_ctx *sc)
473 {
474 char **strings, *p;
475 unsigned char *prop_ret;
476 Atom type_ret;
477 int format_ret, i = 0, nstrings = 0, n, setnames = 0;
478 unsigned long bytes_after, num_ret;
479
480 if (XGetWindowProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, 0,
481 0xffffff, False, UTF8_STRING, &type_ret, &format_ret,
482 &num_ret, &bytes_after, &prop_ret) == Success &&
483 prop_ret != NULL && format_ret == 8) {
484 /* failure, just set defaults */
485 prop_ret[num_ret - 1] = '\0'; /* paranoia */
486 while (i < num_ret) {
487 if (prop_ret[i++] == '\0')
488 nstrings++;
489 }
490 }
491
492 strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
493 nstrings) * sizeof(*strings));
494
495 i = n = 0;
496 p = prop_ret;
497 while (n < nstrings) {
498 strings[n++] = xstrdup(p);
499 p += strlen(p) + 1;
500 }
501 /*
502 * make sure we always set our defaults if nothing is there to
503 * replace them.
504 */
505 if (n < CALMWM_NGROUPS) {
506 setnames = 1;
507 i = 1;
508 while (n < CALMWM_NGROUPS)
509 strings[n++] = xstrdup(shortcut_to_name[i++]);
510 }
511
512 if (prop_ret != NULL)
513 XFree(prop_ret);
514 if (sc->group_nonames != 0)
515 free(sc->group_names);
516
517 sc->group_names = strings;
518 sc->group_nonames = n;
519 if (setnames)
520 group_set_names(sc);
521 }
522
523 static void
524 group_set_names(struct screen_ctx *sc)
525 {
526 unsigned char *p, *q;
527 size_t len = 0, tlen, slen;
528 int i;
529
530 for (i = 0; i < sc->group_nonames; i++)
531 len += strlen(sc->group_names[i]) + 1;
532 q = p = xcalloc(len, sizeof(*p));
533
534 tlen = len;
535 for (i = 0; i < sc->group_nonames; i++) {
536 slen = strlen(sc->group_names[i]) + 1;
537 strlcpy(q, sc->group_names[i], tlen);
538 tlen -= slen;
539 q += slen;
540 }
541
542 XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES,
543 UTF8_STRING, 8, PropModeReplace, p, len);
544 }
Something went wrong with that request. Please try again.