18
18
* Boston, MA 02111-1307, USA.
23
#include "uim/gettext.h"
21
24
#include <string.h>
26
#include "eggtrayicon.h"
28
#include <gdkconfig.h>
29
#if defined (GDK_WINDOWING_X11)
22
30
#include <gdk/gdkx.h>
23
#include "eggtrayicon.h"
31
#include <X11/Xatom.h>
32
#elif defined (GDK_WINDOWING_WIN32)
33
#include <gdk/gdkwin32.h>
25
36
#define SYSTEM_TRAY_REQUEST_DOCK 0
26
37
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
27
38
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
40
#define SYSTEM_TRAY_ORIENTATION_HORZ 0
41
#define SYSTEM_TRAY_ORIENTATION_VERT 1
29
48
static GtkPlugClass *parent_class = NULL;
31
50
static void egg_tray_icon_init (EggTrayIcon *icon);
32
51
static void egg_tray_icon_class_init (EggTrayIconClass *klass);
53
static void egg_tray_icon_get_property (GObject *object,
58
static void egg_tray_icon_realize (GtkWidget *widget);
34
59
static void egg_tray_icon_unrealize (GtkWidget *widget);
36
static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);
61
#ifdef GDK_WINDOWING_X11
62
static void egg_tray_icon_update_manager_window (EggTrayIcon *icon,
63
gboolean dock_if_realized);
64
static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon);
39
68
egg_tray_icon_get_type (void)
41
70
static GType our_type = 0;
43
our_type = g_type_from_name("EggTrayIcon");
47
74
static const GTypeInfo our_info =
71
94
egg_tray_icon_init (EggTrayIcon *icon)
97
icon->orientation = GTK_ORIENTATION_HORIZONTAL;
75
99
gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
79
103
egg_tray_icon_class_init (EggTrayIconClass *klass)
105
GObjectClass *gobject_class = (GObjectClass *)klass;
81
106
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
83
108
parent_class = g_type_class_peek_parent (klass);
110
gobject_class->get_property = egg_tray_icon_get_property;
112
widget_class->realize = egg_tray_icon_realize;
85
113
widget_class->unrealize = egg_tray_icon_unrealize;
115
g_object_class_install_property (gobject_class,
117
g_param_spec_enum ("orientation",
119
_("The orientation of the tray."),
120
GTK_TYPE_ORIENTATION,
121
GTK_ORIENTATION_HORIZONTAL,
124
#if defined (GDK_WINDOWING_X11)
126
#elif defined (GDK_WINDOWING_WIN32)
127
g_warning ("Port eggtrayicon to Win32");
129
g_warning ("Port eggtrayicon to this GTK+ backend");
134
egg_tray_icon_get_property (GObject *object,
139
EggTrayIcon *icon = EGG_TRAY_ICON (object);
143
case PROP_ORIENTATION:
144
g_value_set_enum (value, icon->orientation);
147
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
152
#ifdef GDK_WINDOWING_X11
155
egg_tray_icon_get_orientation_property (EggTrayIcon *icon)
168
g_assert (icon->manager_window != None);
170
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
172
gdk_error_trap_push ();
174
result = XGetWindowProperty (xdisplay,
175
icon->manager_window,
176
icon->orientation_atom,
179
&type, &format, &nitems,
180
&bytes_after, &(prop.prop_ch));
181
error = gdk_error_trap_pop ();
183
if (error || result != Success)
186
if (type == XA_CARDINAL)
188
GtkOrientation orientation;
190
orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
191
GTK_ORIENTATION_HORIZONTAL :
192
GTK_ORIENTATION_VERTICAL;
194
if (icon->orientation != orientation)
196
icon->orientation = orientation;
198
g_object_notify (G_OBJECT (icon), "orientation");
88
206
static GdkFilterReturn
188
egg_tray_icon_update_manager_window (EggTrayIcon *icon)
304
egg_tray_icon_update_manager_window (EggTrayIcon *icon,
305
gboolean dock_if_realized)
190
307
Display *xdisplay;
192
#if HAVE_GTK_MULTIHEAD
309
if (icon->manager_window != None)
193
312
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
195
xdisplay = gdk_display;
198
if (icon->manager_window != None)
202
#if HAVE_GTK_MULTIHEAD
203
gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
204
icon->manager_window);
206
gdkwin = gdk_window_lookup (icon->manager_window);
209
gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
212
314
XGrabServer (xdisplay);
214
316
icon->manager_window = XGetSelectionOwner (xdisplay,
215
317
icon->selection_atom);
217
319
if (icon->manager_window != None)
218
320
XSelectInput (xdisplay,
219
icon->manager_window, StructureNotifyMask);
321
icon->manager_window, StructureNotifyMask|PropertyChangeMask);
221
323
XUngrabServer (xdisplay);
222
324
XFlush (xdisplay);
224
326
if (icon->manager_window != None)
226
328
GdkWindow *gdkwin;
228
#if HAVE_GTK_MULTIHEAD
229
330
gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
230
331
icon->manager_window);
232
gdkwin = gdk_window_lookup (icon->manager_window);
235
333
gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
237
/* Send a request that we'd like to dock */
238
egg_tray_icon_send_dock_request (icon);
335
if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
336
egg_tray_icon_send_dock_request (icon);
338
egg_tray_icon_get_orientation_property (icon);
243
egg_tray_icon_new_for_xscreen (Screen *xscreen, const char *name)
343
egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon)
347
g_return_if_fail (icon->manager_window != None);
349
gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
350
icon->manager_window);
352
gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
354
icon->manager_window = None;
356
egg_tray_icon_update_manager_window (icon, TRUE);
362
egg_tray_icon_realize (GtkWidget *widget)
364
#ifdef GDK_WINDOWING_X11
365
EggTrayIcon *icon = EGG_TRAY_ICON (widget);
246
369
char buffer[256];
247
370
GdkWindow *root_window;
249
g_return_val_if_fail (xscreen != NULL, NULL);
251
icon = g_object_new (EGG_TYPE_TRAY_ICON, NULL);
252
gtk_window_set_title (GTK_WINDOW (icon), name);
372
if (GTK_WIDGET_CLASS (parent_class)->realize)
373
GTK_WIDGET_CLASS (parent_class)->realize (widget);
254
#if HAVE_GTK_MULTIHEAD
255
/* FIXME: this code does not compile, screen is undefined. Now try
256
* getting the GdkScreen from xscreen (:. Dunno how to solve this
257
* (there is prolly some easy way I cant think of right now)
259
gtk_plug_construct_for_display (GTK_PLUG (icon),
260
gdk_screen_get_display (screen), 0);
262
gtk_plug_construct (GTK_PLUG (icon), 0);
265
gtk_widget_realize (GTK_WIDGET (icon));
375
screen = gtk_widget_get_screen (widget);
376
display = gdk_screen_get_display (screen);
377
xdisplay = gdk_x11_display_get_xdisplay (display);
267
379
/* Now see if there's a manager window around */
268
380
g_snprintf (buffer, sizeof (buffer),
269
381
"_NET_SYSTEM_TRAY_S%d",
270
XScreenNumberOfScreen (xscreen));
272
icon->selection_atom = XInternAtom (DisplayOfScreen (xscreen),
275
icon->manager_atom = XInternAtom (DisplayOfScreen (xscreen),
278
icon->system_tray_opcode_atom = XInternAtom (DisplayOfScreen (xscreen),
279
"_NET_SYSTEM_TRAY_OPCODE", False);
281
egg_tray_icon_update_manager_window (icon);
283
#if HAVE_GTK_MULTIHEAD
284
root_window = gdk_screen_get_root_window (gtk_widget_get_screen (screen));
286
root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
382
gdk_screen_get_number (screen));
384
icon->selection_atom = XInternAtom (xdisplay, buffer, False);
386
icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
388
icon->system_tray_opcode_atom = XInternAtom (xdisplay,
389
"_NET_SYSTEM_TRAY_OPCODE",
392
icon->orientation_atom = XInternAtom (xdisplay,
393
"_NET_SYSTEM_TRAY_ORIENTATION",
396
egg_tray_icon_update_manager_window (icon, FALSE);
397
egg_tray_icon_send_dock_request (icon);
399
root_window = gdk_screen_get_root_window (screen);
289
401
/* Add a root window filter so that we get changes on MANAGER */
290
402
gdk_window_add_filter (root_window,
291
403
egg_tray_icon_manager_filter, icon);
296
#if HAVE_GTK_MULTIHEAD
298
408
egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
303
410
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
305
return egg_tray_icon_new_for_xscreen (GDK_SCREEN_XSCREEN (screen), name);
412
return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL);
310
416
egg_tray_icon_new (const gchar *name)
312
return egg_tray_icon_new_for_xscreen (DefaultScreenOfDisplay (gdk_display), name);
418
return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL);