Mercurial > pidgin
annotate plugins/docklet/eggtrayicon.c @ 13968:6fc412e59214
[gaim-migrate @ 16525]
A bunch of little things
* Use GAIM_CONNECTION_IS_VALID(gc) in a lot of places where
we were doing g_list_find(gaim_connections_get_all(), gc)
* Get rid of a lot of places where we were doing
g_list_find(gaim_connections_get_all(), gc). The handle used
by the request API ensures that the ok and cancel callback
functions won't be called if the gc is destroyed. However,
GAIM_CONNECTION_IS_VALID(gc) is still very important for
callback functions where we can't cancel the request.
For example, gaim_proxy_connect() callback functions.
* "Added" a function to Yahoo! that should help us notice
when our buddies change their buddy icon/display picture
* Some comments in a few places
* Changed GAIM_CONNECTION_IS_VALID(gc) to only look through
the list of "all" connections and not the list of
"connecting" connections. Some time ago we changed how
this was done so that the list of "all" connections now
includes the "connection" connections.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Jul 2006 08:11:54 +0000 |
parents | e856f985a0b9 |
children | 4687f862a56b |
rev | line source |
---|---|
3510 | 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
2 /* eggtrayicon.c | |
3 * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org> | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the | |
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 * Boston, MA 02111-1307, USA. | |
19 */ | |
20 | |
10779 | 21 #include <config.h> |
3510 | 22 #include <string.h> |
10779 | 23 |
24 #include "eggtrayicon.h" | |
25 | |
3510 | 26 #include <gdk/gdkx.h> |
10779 | 27 #include <X11/Xatom.h> |
28 | |
29 #define _(x) x | |
30 #define N_(x) x | |
3510 | 31 |
32 #define SYSTEM_TRAY_REQUEST_DOCK 0 | |
33 #define SYSTEM_TRAY_BEGIN_MESSAGE 1 | |
34 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 | |
10779 | 35 |
36 #define SYSTEM_TRAY_ORIENTATION_HORZ 0 | |
37 #define SYSTEM_TRAY_ORIENTATION_VERT 1 | |
38 | |
39 enum { | |
40 PROP_0, | |
41 PROP_ORIENTATION | |
42 }; | |
3510 | 43 |
44 static GtkPlugClass *parent_class = NULL; | |
45 | |
46 static void egg_tray_icon_init (EggTrayIcon *icon); | |
47 static void egg_tray_icon_class_init (EggTrayIconClass *klass); | |
48 | |
10779 | 49 static void egg_tray_icon_get_property (GObject *object, |
50 guint prop_id, | |
51 GValue *value, | |
52 GParamSpec *pspec); | |
53 | |
54 static void egg_tray_icon_realize (GtkWidget *widget); | |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
55 static void egg_tray_icon_unrealize (GtkWidget *widget); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
56 |
10779 | 57 static void egg_tray_icon_update_manager_window (EggTrayIcon *icon, |
58 gboolean dock_if_realized); | |
59 static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon); | |
3510 | 60 |
61 GType | |
62 egg_tray_icon_get_type (void) | |
63 { | |
64 static GType our_type = 0; | |
65 | |
66 if (our_type == 0) | |
67 { | |
10779 | 68 our_type = g_type_from_name("EggTrayIcon"); |
69 | |
70 if (our_type == 0) | |
71 { | |
3510 | 72 static const GTypeInfo our_info = |
73 { | |
74 sizeof (EggTrayIconClass), | |
75 (GBaseInitFunc) NULL, | |
76 (GBaseFinalizeFunc) NULL, | |
77 (GClassInitFunc) egg_tray_icon_class_init, | |
78 NULL, /* class_finalize */ | |
79 NULL, /* class_data */ | |
80 sizeof (EggTrayIcon), | |
81 0, /* n_preallocs */ | |
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
11291
diff
changeset
|
82 (GInstanceInitFunc) egg_tray_icon_init, |
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
11291
diff
changeset
|
83 NULL /* value_table */ |
3510 | 84 }; |
85 | |
86 our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0); | |
10779 | 87 } |
88 else if (parent_class == NULL) | |
89 { | |
90 /* we're reheating the old class from a previous instance - engage ugly hack =( */ | |
91 egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type)); | |
92 } | |
3510 | 93 } |
94 | |
95 return our_type; | |
96 } | |
97 | |
98 static void | |
99 egg_tray_icon_init (EggTrayIcon *icon) | |
100 { | |
101 icon->stamp = 1; | |
10779 | 102 icon->orientation = GTK_ORIENTATION_HORIZONTAL; |
3510 | 103 |
104 gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); | |
105 } | |
106 | |
107 static void | |
108 egg_tray_icon_class_init (EggTrayIconClass *klass) | |
109 { | |
10779 | 110 GObjectClass *gobject_class = (GObjectClass *)klass; |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
111 GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
112 |
3510 | 113 parent_class = g_type_class_peek_parent (klass); |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
114 |
10779 | 115 gobject_class->get_property = egg_tray_icon_get_property; |
116 | |
117 widget_class->realize = egg_tray_icon_realize; | |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
118 widget_class->unrealize = egg_tray_icon_unrealize; |
10779 | 119 |
120 g_object_class_install_property (gobject_class, | |
121 PROP_ORIENTATION, | |
122 g_param_spec_enum ("orientation", | |
123 _("Orientation"), | |
124 _("The orientation of the tray."), | |
125 GTK_TYPE_ORIENTATION, | |
126 GTK_ORIENTATION_HORIZONTAL, | |
127 G_PARAM_READABLE)); | |
128 } | |
129 | |
130 static void | |
131 egg_tray_icon_get_property (GObject *object, | |
132 guint prop_id, | |
133 GValue *value, | |
134 GParamSpec *pspec) | |
135 { | |
136 EggTrayIcon *icon = EGG_TRAY_ICON (object); | |
137 | |
138 switch (prop_id) | |
139 { | |
140 case PROP_ORIENTATION: | |
141 g_value_set_enum (value, icon->orientation); | |
142 break; | |
143 default: | |
144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
145 break; | |
146 } | |
147 } | |
148 | |
149 static void | |
150 egg_tray_icon_get_orientation_property (EggTrayIcon *icon) | |
151 { | |
152 Display *xdisplay; | |
153 Atom type; | |
154 int format; | |
155 union { | |
156 gulong *prop; | |
157 guchar *prop_ch; | |
158 } prop = { NULL }; | |
159 gulong nitems; | |
160 gulong bytes_after; | |
161 int error, result; | |
162 | |
11291 | 163 g_return_if_fail(icon->manager_window != None); |
10779 | 164 |
165 #if GTK_CHECK_VERSION(2,1,0) | |
166 xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); | |
167 #else | |
168 xdisplay = gdk_display; | |
169 #endif | |
170 | |
171 gdk_error_trap_push (); | |
172 type = None; | |
173 result = XGetWindowProperty (xdisplay, | |
174 icon->manager_window, | |
175 icon->orientation_atom, | |
176 0, G_MAXLONG, FALSE, | |
177 XA_CARDINAL, | |
178 &type, &format, &nitems, | |
179 &bytes_after, &(prop.prop_ch)); | |
180 error = gdk_error_trap_pop (); | |
181 | |
182 if (error || result != Success) | |
183 return; | |
184 | |
185 if (type == XA_CARDINAL) | |
186 { | |
187 GtkOrientation orientation; | |
188 | |
189 orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ? | |
190 GTK_ORIENTATION_HORIZONTAL : | |
191 GTK_ORIENTATION_VERTICAL; | |
192 | |
193 if (icon->orientation != orientation) | |
194 { | |
195 icon->orientation = orientation; | |
196 | |
197 g_object_notify (G_OBJECT (icon), "orientation"); | |
198 } | |
199 } | |
200 | |
201 if (prop.prop) | |
202 XFree (prop.prop); | |
3510 | 203 } |
204 | |
205 static GdkFilterReturn | |
206 egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data) | |
207 { | |
208 EggTrayIcon *icon = user_data; | |
209 XEvent *xev = (XEvent *)xevent; | |
210 | |
211 if (xev->xany.type == ClientMessage && | |
212 xev->xclient.message_type == icon->manager_atom && | |
213 xev->xclient.data.l[1] == icon->selection_atom) | |
214 { | |
10779 | 215 egg_tray_icon_update_manager_window (icon, TRUE); |
3510 | 216 } |
217 else if (xev->xany.window == icon->manager_window) | |
218 { | |
10779 | 219 if (xev->xany.type == PropertyNotify && |
220 xev->xproperty.atom == icon->orientation_atom) | |
221 { | |
222 egg_tray_icon_get_orientation_property (icon); | |
223 } | |
3510 | 224 if (xev->xany.type == DestroyNotify) |
225 { | |
10779 | 226 egg_tray_icon_manager_window_destroyed (icon); |
3510 | 227 } |
228 } | |
229 | |
230 return GDK_FILTER_CONTINUE; | |
231 } | |
232 | |
233 static void | |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
234 egg_tray_icon_unrealize (GtkWidget *widget) |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
235 { |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
236 EggTrayIcon *icon = EGG_TRAY_ICON (widget); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
237 GdkWindow *root_window; |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
238 |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
239 if (icon->manager_window != None) |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
240 { |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
241 GdkWindow *gdkwin; |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
242 |
10779 | 243 #if GTK_CHECK_VERSION(2,1,0) |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
244 gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
245 icon->manager_window); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
246 #else |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
247 gdkwin = gdk_window_lookup (icon->manager_window); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
248 #endif |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
249 |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
250 gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
251 } |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
252 |
10779 | 253 #if GTK_CHECK_VERSION(2,1,0) |
4261
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
254 root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
255 #else |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
256 root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
257 #endif |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
258 |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
259 gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
260 |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
261 if (GTK_WIDGET_CLASS (parent_class)->unrealize) |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
262 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
263 } |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
264 |
e252238f99df
[gaim-migrate @ 4512]
Christian Hammond <chipx86@chipx86.com>
parents:
3510
diff
changeset
|
265 static void |
3510 | 266 egg_tray_icon_send_manager_message (EggTrayIcon *icon, |
267 long message, | |
268 Window window, | |
269 long data1, | |
270 long data2, | |
271 long data3) | |
272 { | |
273 XClientMessageEvent ev; | |
274 Display *display; | |
275 | |
276 ev.type = ClientMessage; | |
277 ev.window = window; | |
278 ev.message_type = icon->system_tray_opcode_atom; | |
279 ev.format = 32; | |
280 ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window); | |
281 ev.data.l[1] = message; | |
282 ev.data.l[2] = data1; | |
283 ev.data.l[3] = data2; | |
284 ev.data.l[4] = data3; | |
285 | |
10779 | 286 #if GTK_CHECK_VERSION(2,1,0) |
3510 | 287 display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); |
288 #else | |
289 display = gdk_display; | |
290 #endif | |
10779 | 291 |
3510 | 292 gdk_error_trap_push (); |
293 XSendEvent (display, | |
294 icon->manager_window, False, NoEventMask, (XEvent *)&ev); | |
295 XSync (display, False); | |
296 gdk_error_trap_pop (); | |
297 } | |
298 | |
299 static void | |
300 egg_tray_icon_send_dock_request (EggTrayIcon *icon) | |
301 { | |
302 egg_tray_icon_send_manager_message (icon, | |
303 SYSTEM_TRAY_REQUEST_DOCK, | |
304 icon->manager_window, | |
305 gtk_plug_get_id (GTK_PLUG (icon)), | |
306 0, 0); | |
307 } | |
308 | |
309 static void | |
10779 | 310 egg_tray_icon_update_manager_window (EggTrayIcon *icon, |
311 gboolean dock_if_realized) | |
3510 | 312 { |
313 Display *xdisplay; | |
314 | |
10779 | 315 if (icon->manager_window != None) |
316 return; | |
317 | |
318 #if GTK_CHECK_VERSION(2,1,0) | |
3510 | 319 xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); |
320 #else | |
321 xdisplay = gdk_display; | |
322 #endif | |
323 | |
324 XGrabServer (xdisplay); | |
325 | |
326 icon->manager_window = XGetSelectionOwner (xdisplay, | |
327 icon->selection_atom); | |
328 | |
329 if (icon->manager_window != None) | |
330 XSelectInput (xdisplay, | |
10779 | 331 icon->manager_window, StructureNotifyMask|PropertyChangeMask); |
3510 | 332 |
333 XUngrabServer (xdisplay); | |
334 XFlush (xdisplay); | |
335 | |
336 if (icon->manager_window != None) | |
337 { | |
338 GdkWindow *gdkwin; | |
339 | |
10779 | 340 #if GTK_CHECK_VERSION(2,1,0) |
3510 | 341 gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), |
342 icon->manager_window); | |
343 #else | |
344 gdkwin = gdk_window_lookup (icon->manager_window); | |
345 #endif | |
10779 | 346 |
3510 | 347 gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon); |
348 | |
10779 | 349 if (dock_if_realized && GTK_WIDGET_REALIZED (icon)) |
350 egg_tray_icon_send_dock_request (icon); | |
351 | |
352 egg_tray_icon_get_orientation_property (icon); | |
3510 | 353 } |
354 } | |
355 | |
10779 | 356 static void |
357 egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) | |
3510 | 358 { |
10779 | 359 GdkWindow *gdkwin; |
360 | |
361 g_return_if_fail (icon->manager_window != None); | |
362 | |
363 #if GTK_CHECK_VERSION(2,1,0) | |
364 gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), | |
365 icon->manager_window); | |
366 #else | |
367 gdkwin = gdk_window_lookup (icon->manager_window); | |
368 #endif | |
369 | |
370 gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); | |
371 | |
372 icon->manager_window = None; | |
373 | |
374 egg_tray_icon_update_manager_window (icon, TRUE); | |
375 } | |
376 | |
377 static void | |
378 egg_tray_icon_realize (GtkWidget *widget) | |
379 { | |
380 EggTrayIcon *icon = EGG_TRAY_ICON (widget); | |
381 gint screen; | |
382 Display *xdisplay; | |
3510 | 383 char buffer[256]; |
384 GdkWindow *root_window; | |
385 | |
10779 | 386 if (GTK_WIDGET_CLASS (parent_class)->realize) |
387 GTK_WIDGET_CLASS (parent_class)->realize (widget); | |
3510 | 388 |
10779 | 389 #if GTK_CHECK_VERSION(2,1,0) |
390 screen = gdk_screen_get_number (gtk_widget_get_screen (widget)); | |
391 xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)); | |
3510 | 392 #else |
10779 | 393 screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display)); |
394 xdisplay = gdk_display; | |
3510 | 395 #endif |
396 | |
397 /* Now see if there's a manager window around */ | |
398 g_snprintf (buffer, sizeof (buffer), | |
399 "_NET_SYSTEM_TRAY_S%d", | |
10779 | 400 screen); |
401 | |
402 icon->selection_atom = XInternAtom (xdisplay, buffer, False); | |
3510 | 403 |
10779 | 404 icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); |
3510 | 405 |
10779 | 406 icon->system_tray_opcode_atom = XInternAtom (xdisplay, |
407 "_NET_SYSTEM_TRAY_OPCODE", | |
408 False); | |
3510 | 409 |
10779 | 410 icon->orientation_atom = XInternAtom (xdisplay, |
411 "_NET_SYSTEM_TRAY_ORIENTATION", | |
412 False); | |
3510 | 413 |
10779 | 414 egg_tray_icon_update_manager_window (icon, FALSE); |
415 egg_tray_icon_send_dock_request (icon); | |
416 | |
417 #if GTK_CHECK_VERSION(2,1,0) | |
418 root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); | |
3510 | 419 #else |
420 root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); | |
421 #endif | |
10779 | 422 |
3510 | 423 /* Add a root window filter so that we get changes on MANAGER */ |
424 gdk_window_add_filter (root_window, | |
425 egg_tray_icon_manager_filter, icon); | |
426 } | |
427 | |
10779 | 428 #if GTK_CHECK_VERSION(2,1,0) |
3510 | 429 EggTrayIcon * |
430 egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name) | |
431 { | |
432 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); | |
433 | |
10779 | 434 return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL); |
3510 | 435 } |
436 #endif | |
437 | |
438 EggTrayIcon* | |
439 egg_tray_icon_new (const gchar *name) | |
440 { | |
10779 | 441 return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL); |
3510 | 442 } |
443 | |
444 guint | |
445 egg_tray_icon_send_message (EggTrayIcon *icon, | |
446 gint timeout, | |
447 const gchar *message, | |
448 gint len) | |
449 { | |
450 guint stamp; | |
451 | |
452 g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); | |
453 g_return_val_if_fail (timeout >= 0, 0); | |
454 g_return_val_if_fail (message != NULL, 0); | |
455 | |
456 if (icon->manager_window == None) | |
457 return 0; | |
458 | |
459 if (len < 0) | |
460 len = strlen (message); | |
461 | |
462 stamp = icon->stamp++; | |
463 | |
464 /* Get ready to send the message */ | |
465 egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, | |
466 (Window)gtk_plug_get_id (GTK_PLUG (icon)), | |
467 timeout, len, stamp); | |
468 | |
469 /* Now to send the actual message */ | |
470 gdk_error_trap_push (); | |
471 while (len > 0) | |
472 { | |
473 XClientMessageEvent ev; | |
474 Display *xdisplay; | |
475 | |
10779 | 476 #if GTK_CHECK_VERSION(2,1,0) |
3510 | 477 xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); |
478 #else | |
479 xdisplay = gdk_display; | |
480 #endif | |
10779 | 481 |
3510 | 482 ev.type = ClientMessage; |
483 ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); | |
484 ev.format = 8; | |
485 ev.message_type = XInternAtom (xdisplay, | |
486 "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); | |
487 if (len > 20) | |
488 { | |
489 memcpy (&ev.data, message, 20); | |
490 len -= 20; | |
491 message += 20; | |
492 } | |
493 else | |
494 { | |
495 memcpy (&ev.data, message, len); | |
496 len = 0; | |
497 } | |
498 | |
499 XSendEvent (xdisplay, | |
500 icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); | |
501 XSync (xdisplay, False); | |
502 } | |
503 gdk_error_trap_pop (); | |
504 | |
505 return stamp; | |
506 } | |
507 | |
508 void | |
509 egg_tray_icon_cancel_message (EggTrayIcon *icon, | |
510 guint id) | |
511 { | |
512 g_return_if_fail (EGG_IS_TRAY_ICON (icon)); | |
513 g_return_if_fail (id > 0); | |
514 | |
515 egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, | |
516 (Window)gtk_plug_get_id (GTK_PLUG (icon)), | |
517 id, 0, 0); | |
518 } | |
10779 | 519 |
520 GtkOrientation | |
521 egg_tray_icon_get_orientation (EggTrayIcon *icon) | |
522 { | |
523 g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL); | |
524 | |
525 return icon->orientation; | |
526 } |