]> Dogcows Code - chaz/tint2/blob - src/systray/icons.c
5c5b240d4cb6f7fa83b1dd3dd03030c0d7580295
[chaz/tint2] / src / systray / icons.c
1 #include "icons.h"
2 #include "net.h"
3 #include <assert.h>
4 #include <stdlib.h>
5
6 gboolean error;
7 int window_error_handler(Display *d, XErrorEvent *e)
8 {
9 d=d;e=e;
10 if (e->error_code == BadWindow) {
11 error = TRUE;
12 } else {
13 g_printerr("X ERROR NOT BAD WINDOW!\n");
14 abort();
15 }
16 return 0;
17 }
18
19
20 gboolean icon_swallow(TrayWindow *traywin)
21 {
22 XErrorHandler old;
23
24 error = FALSE;
25 old = XSetErrorHandler(window_error_handler);
26 XReparentWindow(display, traywin->id, win, 0, 0);
27 XSync(display, False);
28 XSetErrorHandler(old);
29
30 return !error;
31 }
32
33
34 /*
35 The traywin must have its id and type set.
36 */
37 gboolean icon_add(Window id, TrayWindowType type)
38 {
39 TrayWindow *traywin;
40
41 assert(id);
42 assert(type);
43
44 if (wmaker) {
45 /* do we have room in our window for another icon? */
46 unsigned int max = (width / icon_size) * (height / icon_size);
47 if (g_slist_length(icons) >= max)
48 return FALSE; /* no room, sorry! REJECTED! */
49 }
50
51 traywin = g_new0(TrayWindow, 1);
52 traywin->type = type;
53 traywin->id = id;
54
55 if (!icon_swallow(traywin)) {
56 g_free(traywin);
57 return FALSE;
58 }
59
60 /* find the positon for the systray app window */
61 if (!wmaker) {
62 traywin->x = border + (horizontal ? width : 0);
63 traywin->y = border + (horizontal ? 0 : height);
64 } else {
65 int count = g_slist_length(icons);
66 traywin->x = border + ((width % icon_size) / 2) +
67 (count % (width / icon_size)) * icon_size;
68 traywin->y = border + ((height % icon_size) / 2) +
69 (count / (height / icon_size)) * icon_size;
70 }
71
72 /* add the new icon to the list */
73 icons = g_slist_append(icons, traywin);
74
75 /* watch for the icon trying to resize itself! BAD ICON! BAD! */
76 XSelectInput(display, traywin->id, StructureNotifyMask);
77
78 /* position and size the icon window */
79 XMoveResizeWindow(display, traywin->id,
80 traywin->x, traywin->y, icon_size, icon_size);
81
82 /* resize our window so that the new window can fit in it */
83 fix_geometry();
84
85 /* flush before clearing, otherwise the clear isn't effective. */
86 XFlush(display);
87 /* make sure the new child will get the right stuff in its background
88 for ParentRelative. */
89 XClearWindow(display, win);
90
91 /* show the window */
92 XMapRaised(display, traywin->id);
93
94 return TRUE;
95 }
96
97
98 void icon_remove(GSList *node)
99 {
100 XErrorHandler old;
101 TrayWindow *traywin = node->data;
102 Window traywin_id = traywin->id;
103
104 if (traywin->type == NET)
105 net_icon_remove(traywin);
106
107 XSelectInput(display, traywin->id, NoEventMask);
108
109 /* remove it from our list */
110 g_free(node->data);
111 icons = g_slist_remove_link(icons, node);
112
113 /* reparent it to root */
114 error = FALSE;
115 old = XSetErrorHandler(window_error_handler);
116 XReparentWindow(display, traywin_id, root, 0, 0);
117 XSync(display, False);
118 XSetErrorHandler(old);
119
120 reposition_icons();
121 fix_geometry();
122 }
This page took 0.040129 seconds and 3 git commands to generate.