Fri, 13 Mar 2009 03:04:07 +0000
Move 'Minutes before becoming idle' above 'Change status when idle'
Minutes before becoming idle has an effect even when we're not doing autoaway,
so it should not be disabled then.
| 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 | |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
18709
diff
changeset
|
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
18709
diff
changeset
|
18 | * Boston, MA 02111-1301, USA. |
| 3510 | 19 | */ |
| 20 | ||
| 10779 | 21 | #include <config.h> |
| 3510 | 22 | #include <string.h> |
| 10779 | 23 | |
| 24 | #include "eggtrayicon.h" | |
| 25 | ||
| 26 | #include <X11/Xatom.h> | |
| 27 | ||
| 28 | #define _(x) x | |
| 29 | #define N_(x) x | |
| 3510 | 30 | |
| 31 | #define SYSTEM_TRAY_REQUEST_DOCK 0 | |
| 32 | #define SYSTEM_TRAY_BEGIN_MESSAGE 1 | |
| 33 | #define SYSTEM_TRAY_CANCEL_MESSAGE 2 | |
| 10779 | 34 | |
| 35 | #define SYSTEM_TRAY_ORIENTATION_HORZ 0 | |
| 36 | #define SYSTEM_TRAY_ORIENTATION_VERT 1 | |
| 37 | ||
| 38 | enum { | |
| 39 | PROP_0, | |
| 40 | PROP_ORIENTATION | |
| 41 | }; | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
42 | |
| 3510 | 43 | static GtkPlugClass *parent_class = NULL; |
| 44 | ||
| 45 | static void egg_tray_icon_init (EggTrayIcon *icon); | |
| 46 | static void egg_tray_icon_class_init (EggTrayIconClass *klass); | |
| 47 | ||
| 10779 | 48 | static void egg_tray_icon_get_property (GObject *object, |
| 49 | guint prop_id, | |
| 50 | GValue *value, | |
| 51 | GParamSpec *pspec); | |
| 52 | ||
| 53 | static void egg_tray_icon_realize (GtkWidget *widget); | |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
54 | static void egg_tray_icon_unrealize (GtkWidget *widget); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
55 | |
| 14231 | 56 | static void egg_tray_icon_add (GtkContainer *container, |
| 57 | GtkWidget *widget); | |
| 58 | ||
| 10779 | 59 | static void egg_tray_icon_update_manager_window (EggTrayIcon *icon, |
| 60 | gboolean dock_if_realized); | |
| 61 | static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon); | |
| 3510 | 62 | |
| 63 | GType | |
| 64 | egg_tray_icon_get_type (void) | |
| 65 | { | |
| 66 | static GType our_type = 0; | |
| 67 | ||
| 68 | if (our_type == 0) | |
| 69 | { | |
| 10779 | 70 | our_type = g_type_from_name("EggTrayIcon"); |
| 71 | ||
| 72 | if (our_type == 0) | |
| 73 | { | |
| 3510 | 74 | static const GTypeInfo our_info = |
| 75 | { | |
| 76 | sizeof (EggTrayIconClass), | |
| 77 | (GBaseInitFunc) NULL, | |
| 78 | (GBaseFinalizeFunc) NULL, | |
| 79 | (GClassInitFunc) egg_tray_icon_class_init, | |
| 80 | NULL, /* class_finalize */ | |
| 81 | NULL, /* class_data */ | |
| 82 | sizeof (EggTrayIcon), | |
| 83 | 0, /* n_preallocs */ | |
|
12600
7ecd4441fdc7
[gaim-migrate @ 14934]
Richard Laager <rlaager@pidgin.im>
parents:
11291
diff
changeset
|
84 | (GInstanceInitFunc) egg_tray_icon_init, |
|
7ecd4441fdc7
[gaim-migrate @ 14934]
Richard Laager <rlaager@pidgin.im>
parents:
11291
diff
changeset
|
85 | NULL /* value_table */ |
| 3510 | 86 | }; |
| 87 | ||
| 88 | our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0); | |
| 10779 | 89 | } |
| 90 | else if (parent_class == NULL) | |
| 91 | { | |
| 92 | /* we're reheating the old class from a previous instance - engage ugly hack =( */ | |
| 93 | egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type)); | |
| 94 | } | |
| 3510 | 95 | } |
| 96 | ||
| 97 | return our_type; | |
| 98 | } | |
| 99 | ||
| 100 | static void | |
| 101 | egg_tray_icon_init (EggTrayIcon *icon) | |
| 102 | { | |
| 103 | icon->stamp = 1; | |
| 10779 | 104 | icon->orientation = GTK_ORIENTATION_HORIZONTAL; |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
105 | |
| 3510 | 106 | gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); |
| 107 | } | |
| 108 | ||
| 109 | static void | |
| 110 | egg_tray_icon_class_init (EggTrayIconClass *klass) | |
| 111 | { | |
| 10779 | 112 | GObjectClass *gobject_class = (GObjectClass *)klass; |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
113 | GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; |
| 14231 | 114 | GtkContainerClass *container_class = (GtkContainerClass *)klass; |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
115 | |
| 3510 | 116 | parent_class = g_type_class_peek_parent (klass); |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
117 | |
| 10779 | 118 | gobject_class->get_property = egg_tray_icon_get_property; |
| 119 | ||
| 120 | widget_class->realize = egg_tray_icon_realize; | |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
121 | widget_class->unrealize = egg_tray_icon_unrealize; |
| 10779 | 122 | |
| 14231 | 123 | container_class->add = egg_tray_icon_add; |
| 124 | ||
| 10779 | 125 | g_object_class_install_property (gobject_class, |
| 126 | PROP_ORIENTATION, | |
| 127 | g_param_spec_enum ("orientation", | |
| 128 | _("Orientation"), | |
| 129 | _("The orientation of the tray."), | |
| 130 | GTK_TYPE_ORIENTATION, | |
| 131 | GTK_ORIENTATION_HORIZONTAL, | |
| 132 | G_PARAM_READABLE)); | |
| 133 | } | |
| 134 | ||
| 135 | static void | |
| 136 | egg_tray_icon_get_property (GObject *object, | |
| 137 | guint prop_id, | |
| 138 | GValue *value, | |
| 139 | GParamSpec *pspec) | |
| 140 | { | |
| 141 | EggTrayIcon *icon = EGG_TRAY_ICON (object); | |
| 142 | ||
| 143 | switch (prop_id) | |
| 144 | { | |
| 145 | case PROP_ORIENTATION: | |
| 146 | g_value_set_enum (value, icon->orientation); | |
| 147 | break; | |
| 148 | default: | |
| 149 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
| 150 | break; | |
| 151 | } | |
| 152 | } | |
| 153 | ||
|
18346
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
154 | static Display * |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
155 | egg_tray_icon_get_x_display(EggTrayIcon *icon) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
156 | { |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
157 | Display *xdisplay = NULL; |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
158 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
159 | #if GTK_CHECK_VERSION(2,1,0) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
160 | { |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
161 | GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon)); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
162 | if (!GDK_IS_DISPLAY (display)) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
163 | display = gdk_display_get_default (); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
164 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
165 | xdisplay = GDK_DISPLAY_XDISPLAY (display); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
166 | } |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
167 | #else |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
168 | xdisplay = gdk_display; |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
169 | #endif |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
170 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
171 | return xdisplay; |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
172 | } |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
173 | |
| 10779 | 174 | static void |
| 175 | egg_tray_icon_get_orientation_property (EggTrayIcon *icon) | |
| 176 | { | |
| 177 | Display *xdisplay; | |
| 178 | Atom type; | |
| 179 | int format; | |
| 180 | union { | |
| 181 | gulong *prop; | |
| 182 | guchar *prop_ch; | |
| 183 | } prop = { NULL }; | |
| 184 | gulong nitems; | |
| 185 | gulong bytes_after; | |
| 186 | int error, result; | |
| 187 | ||
|
11291
5441d2419942
[gaim-migrate @ 13491]
Mark Doliner <markdoliner@pidgin.im>
parents:
10779
diff
changeset
|
188 | g_return_if_fail(icon->manager_window != None); |
| 10779 | 189 | |
|
18346
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
190 | xdisplay = egg_tray_icon_get_x_display(icon); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
191 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
192 | if (xdisplay == NULL) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
193 | return; |
| 10779 | 194 | |
| 195 | gdk_error_trap_push (); | |
| 196 | type = None; | |
| 197 | result = XGetWindowProperty (xdisplay, | |
| 198 | icon->manager_window, | |
| 199 | icon->orientation_atom, | |
| 200 | 0, G_MAXLONG, FALSE, | |
| 201 | XA_CARDINAL, | |
| 202 | &type, &format, &nitems, | |
| 203 | &bytes_after, &(prop.prop_ch)); | |
| 204 | error = gdk_error_trap_pop (); | |
| 205 | ||
| 206 | if (error || result != Success) | |
| 207 | return; | |
| 208 | ||
| 209 | if (type == XA_CARDINAL) | |
| 210 | { | |
| 211 | GtkOrientation orientation; | |
| 212 | ||
| 213 | orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ? | |
| 214 | GTK_ORIENTATION_HORIZONTAL : | |
| 215 | GTK_ORIENTATION_VERTICAL; | |
| 216 | ||
| 217 | if (icon->orientation != orientation) | |
| 218 | { | |
| 219 | icon->orientation = orientation; | |
| 220 | ||
| 221 | g_object_notify (G_OBJECT (icon), "orientation"); | |
| 222 | } | |
| 223 | } | |
| 224 | ||
| 225 | if (prop.prop) | |
| 226 | XFree (prop.prop); | |
| 3510 | 227 | } |
| 228 | ||
| 229 | static GdkFilterReturn | |
| 230 | egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data) | |
| 231 | { | |
| 232 | EggTrayIcon *icon = user_data; | |
| 233 | XEvent *xev = (XEvent *)xevent; | |
| 234 | ||
| 235 | if (xev->xany.type == ClientMessage && | |
| 236 | xev->xclient.message_type == icon->manager_atom && | |
| 237 | xev->xclient.data.l[1] == icon->selection_atom) | |
| 238 | { | |
| 10779 | 239 | egg_tray_icon_update_manager_window (icon, TRUE); |
| 3510 | 240 | } |
| 241 | else if (xev->xany.window == icon->manager_window) | |
| 242 | { | |
| 10779 | 243 | if (xev->xany.type == PropertyNotify && |
| 244 | xev->xproperty.atom == icon->orientation_atom) | |
| 245 | { | |
| 246 | egg_tray_icon_get_orientation_property (icon); | |
| 247 | } | |
| 3510 | 248 | if (xev->xany.type == DestroyNotify) |
| 249 | { | |
| 10779 | 250 | egg_tray_icon_manager_window_destroyed (icon); |
| 3510 | 251 | } |
| 252 | } | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
253 | |
| 3510 | 254 | return GDK_FILTER_CONTINUE; |
| 255 | } | |
| 256 | ||
| 257 | static void | |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
258 | egg_tray_icon_unrealize (GtkWidget *widget) |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
259 | { |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
260 | EggTrayIcon *icon = EGG_TRAY_ICON (widget); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
261 | GdkWindow *root_window; |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
262 | |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
263 | if (icon->manager_window != None) |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
264 | { |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
265 | GdkWindow *gdkwin; |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
266 | |
| 10779 | 267 | #if GTK_CHECK_VERSION(2,1,0) |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
268 | gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
269 | icon->manager_window); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
270 | #else |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
271 | gdkwin = gdk_window_lookup (icon->manager_window); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
272 | #endif |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
273 | |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
274 | gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
275 | } |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
276 | |
| 10779 | 277 | #if GTK_CHECK_VERSION(2,1,0) |
|
4261
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
278 | root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
279 | #else |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
280 | root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
281 | #endif |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
282 | |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
283 | gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
284 | |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
285 | if (GTK_WIDGET_CLASS (parent_class)->unrealize) |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
286 | (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
287 | } |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
288 | |
|
cc35d7c0582f
<Robot101> commit message:
Robert McQueen <robot101@debian.org>
parents:
3510
diff
changeset
|
289 | static void |
| 3510 | 290 | egg_tray_icon_send_manager_message (EggTrayIcon *icon, |
| 291 | long message, | |
| 292 | Window window, | |
| 293 | long data1, | |
| 294 | long data2, | |
| 295 | long data3) | |
| 296 | { | |
| 297 | XClientMessageEvent ev; | |
| 298 | Display *display; | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
299 | |
| 3510 | 300 | ev.type = ClientMessage; |
| 301 | ev.window = window; | |
| 302 | ev.message_type = icon->system_tray_opcode_atom; | |
| 303 | ev.format = 32; | |
| 304 | ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window); | |
| 305 | ev.data.l[1] = message; | |
| 306 | ev.data.l[2] = data1; | |
| 307 | ev.data.l[3] = data2; | |
| 308 | ev.data.l[4] = data3; | |
| 309 | ||
| 10779 | 310 | #if GTK_CHECK_VERSION(2,1,0) |
| 3510 | 311 | display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); |
| 312 | #else | |
| 313 | display = gdk_display; | |
| 314 | #endif | |
| 10779 | 315 | |
| 3510 | 316 | gdk_error_trap_push (); |
| 317 | XSendEvent (display, | |
| 318 | icon->manager_window, False, NoEventMask, (XEvent *)&ev); | |
| 319 | XSync (display, False); | |
| 320 | gdk_error_trap_pop (); | |
| 321 | } | |
| 322 | ||
| 323 | static void | |
| 324 | egg_tray_icon_send_dock_request (EggTrayIcon *icon) | |
| 325 | { | |
| 326 | egg_tray_icon_send_manager_message (icon, | |
| 327 | SYSTEM_TRAY_REQUEST_DOCK, | |
| 328 | icon->manager_window, | |
| 329 | gtk_plug_get_id (GTK_PLUG (icon)), | |
| 330 | 0, 0); | |
| 331 | } | |
| 332 | ||
| 333 | static void | |
| 10779 | 334 | egg_tray_icon_update_manager_window (EggTrayIcon *icon, |
| 335 | gboolean dock_if_realized) | |
| 3510 | 336 | { |
| 337 | Display *xdisplay; | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
338 | |
| 10779 | 339 | if (icon->manager_window != None) |
| 340 | return; | |
| 341 | ||
|
18346
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
342 | xdisplay = egg_tray_icon_get_x_display(icon); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
343 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
344 | if (xdisplay == NULL) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
345 | return; |
| 3510 | 346 | |
| 347 | XGrabServer (xdisplay); | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
348 | |
| 3510 | 349 | icon->manager_window = XGetSelectionOwner (xdisplay, |
| 350 | icon->selection_atom); | |
| 351 | ||
| 352 | if (icon->manager_window != None) | |
| 353 | XSelectInput (xdisplay, | |
| 10779 | 354 | icon->manager_window, StructureNotifyMask|PropertyChangeMask); |
| 3510 | 355 | |
| 356 | XUngrabServer (xdisplay); | |
| 357 | XFlush (xdisplay); | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
358 | |
| 3510 | 359 | if (icon->manager_window != None) |
| 360 | { | |
| 361 | GdkWindow *gdkwin; | |
| 362 | ||
| 10779 | 363 | #if GTK_CHECK_VERSION(2,1,0) |
| 3510 | 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 | |
| 10779 | 369 | |
| 3510 | 370 | gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon); |
| 371 | ||
| 10779 | 372 | if (dock_if_realized && GTK_WIDGET_REALIZED (icon)) |
| 373 | egg_tray_icon_send_dock_request (icon); | |
| 374 | ||
| 375 | egg_tray_icon_get_orientation_property (icon); | |
| 3510 | 376 | } |
| 377 | } | |
| 378 | ||
| 10779 | 379 | static void |
| 380 | egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) | |
| 3510 | 381 | { |
| 10779 | 382 | GdkWindow *gdkwin; |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
383 | |
| 10779 | 384 | g_return_if_fail (icon->manager_window != None); |
| 385 | ||
| 386 | #if GTK_CHECK_VERSION(2,1,0) | |
| 387 | gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), | |
| 388 | icon->manager_window); | |
| 389 | #else | |
| 390 | gdkwin = gdk_window_lookup (icon->manager_window); | |
| 391 | #endif | |
| 392 | ||
| 393 | gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); | |
| 394 | ||
| 395 | icon->manager_window = None; | |
| 396 | ||
| 397 | egg_tray_icon_update_manager_window (icon, TRUE); | |
| 398 | } | |
| 399 | ||
| 14231 | 400 | static gboolean |
| 401 | transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) | |
| 402 | { | |
| 403 | gdk_window_clear_area (widget->window, event->area.x, event->area.y, | |
| 404 | event->area.width, event->area.height); | |
| 405 | return FALSE; | |
| 406 | } | |
| 407 | ||
| 408 | static void | |
| 409 | make_transparent_again (GtkWidget *widget, GtkStyle *previous_style, | |
| 410 | gpointer user_data) | |
| 411 | { | |
| 412 | gdk_window_set_back_pixmap(widget->window, NULL, TRUE); | |
| 413 | } | |
| 414 | ||
| 415 | static void | |
| 416 | make_transparent (GtkWidget *widget, gpointer user_data) | |
| 417 | { | |
| 418 | if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget)) | |
| 419 | return; | |
| 420 | ||
| 421 | gtk_widget_set_app_paintable (widget, TRUE); | |
| 422 | gtk_widget_set_double_buffered (widget, FALSE); | |
| 423 | gdk_window_set_back_pixmap (widget->window, NULL, TRUE); | |
| 424 | g_signal_connect (widget, "expose_event", | |
| 425 | G_CALLBACK (transparent_expose_event), NULL); | |
| 426 | g_signal_connect_after (widget, "style_set", | |
| 427 | G_CALLBACK (make_transparent_again), NULL); | |
| 428 | } | |
| 429 | ||
| 10779 | 430 | static void |
| 431 | egg_tray_icon_realize (GtkWidget *widget) | |
| 432 | { | |
| 433 | EggTrayIcon *icon = EGG_TRAY_ICON (widget); | |
| 434 | gint screen; | |
| 435 | Display *xdisplay; | |
| 3510 | 436 | char buffer[256]; |
| 437 | GdkWindow *root_window; | |
| 438 | ||
| 10779 | 439 | if (GTK_WIDGET_CLASS (parent_class)->realize) |
| 440 | GTK_WIDGET_CLASS (parent_class)->realize (widget); | |
| 3510 | 441 | |
| 14231 | 442 | make_transparent (widget, NULL); |
| 443 | ||
|
18346
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
444 | xdisplay = egg_tray_icon_get_x_display(icon); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
445 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
446 | if (xdisplay == NULL) |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
447 | return; |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
448 | |
| 10779 | 449 | #if GTK_CHECK_VERSION(2,1,0) |
| 450 | screen = gdk_screen_get_number (gtk_widget_get_screen (widget)); | |
| 3510 | 451 | #else |
| 10779 | 452 | screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display)); |
| 3510 | 453 | #endif |
| 454 | ||
| 455 | /* Now see if there's a manager window around */ | |
| 456 | g_snprintf (buffer, sizeof (buffer), | |
| 457 | "_NET_SYSTEM_TRAY_S%d", | |
| 10779 | 458 | screen); |
| 459 | ||
| 460 | icon->selection_atom = XInternAtom (xdisplay, buffer, False); | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
461 | |
| 10779 | 462 | icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
463 | |
| 10779 | 464 | icon->system_tray_opcode_atom = XInternAtom (xdisplay, |
| 465 | "_NET_SYSTEM_TRAY_OPCODE", | |
| 466 | False); | |
| 3510 | 467 | |
| 10779 | 468 | icon->orientation_atom = XInternAtom (xdisplay, |
| 469 | "_NET_SYSTEM_TRAY_ORIENTATION", | |
| 470 | False); | |
| 3510 | 471 | |
| 10779 | 472 | egg_tray_icon_update_manager_window (icon, FALSE); |
| 473 | egg_tray_icon_send_dock_request (icon); | |
| 474 | ||
| 475 | #if GTK_CHECK_VERSION(2,1,0) | |
| 476 | root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); | |
| 3510 | 477 | #else |
| 478 | root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); | |
| 479 | #endif | |
| 10779 | 480 | |
| 3510 | 481 | /* Add a root window filter so that we get changes on MANAGER */ |
| 482 | gdk_window_add_filter (root_window, | |
| 483 | egg_tray_icon_manager_filter, icon); | |
| 484 | } | |
| 485 | ||
| 14231 | 486 | static void |
| 487 | egg_tray_icon_add (GtkContainer *container, GtkWidget *widget) | |
| 488 | { | |
| 489 | g_signal_connect (widget, "realize", | |
| 490 | G_CALLBACK (make_transparent), NULL); | |
| 491 | GTK_CONTAINER_CLASS (parent_class)->add (container, widget); | |
| 492 | } | |
| 493 | ||
| 10779 | 494 | #if GTK_CHECK_VERSION(2,1,0) |
| 3510 | 495 | EggTrayIcon * |
| 496 | egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name) | |
| 497 | { | |
| 498 | g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); | |
| 499 | ||
| 10779 | 500 | return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL); |
| 3510 | 501 | } |
| 502 | #endif | |
| 503 | ||
| 504 | EggTrayIcon* | |
| 505 | egg_tray_icon_new (const gchar *name) | |
| 506 | { | |
| 10779 | 507 | return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL); |
| 3510 | 508 | } |
| 509 | ||
| 510 | guint | |
| 511 | egg_tray_icon_send_message (EggTrayIcon *icon, | |
| 512 | gint timeout, | |
| 513 | const gchar *message, | |
| 514 | gint len) | |
| 515 | { | |
| 516 | guint stamp; | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
517 | |
| 3510 | 518 | g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); |
| 519 | g_return_val_if_fail (timeout >= 0, 0); | |
| 520 | g_return_val_if_fail (message != NULL, 0); | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
521 | |
| 3510 | 522 | if (icon->manager_window == None) |
| 523 | return 0; | |
| 524 | ||
| 525 | if (len < 0) | |
| 526 | len = strlen (message); | |
| 527 | ||
| 528 | stamp = icon->stamp++; | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
529 | |
| 3510 | 530 | /* Get ready to send the message */ |
| 531 | egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, | |
| 532 | (Window)gtk_plug_get_id (GTK_PLUG (icon)), | |
| 533 | timeout, len, stamp); | |
| 534 | ||
| 535 | /* Now to send the actual message */ | |
| 536 | gdk_error_trap_push (); | |
| 537 | while (len > 0) | |
| 538 | { | |
| 539 | XClientMessageEvent ev; | |
| 540 | Display *xdisplay; | |
| 541 | ||
|
18346
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
542 | xdisplay = egg_tray_icon_get_x_display(icon); |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
543 | |
|
8a6dfdd516d4
Guard against passing NULL to GDK_DISPLAY_XDISPLAY. This resolves a crash
Casey Harkins <charkins@pidgin.im>
parents:
15435
diff
changeset
|
544 | if (xdisplay == NULL) |
|
18709
e93e7776283e
Return 0 to silence the following warning
Mark Doliner <markdoliner@pidgin.im>
parents:
18346
diff
changeset
|
545 | return 0; |
| 10779 | 546 | |
| 3510 | 547 | ev.type = ClientMessage; |
| 548 | ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); | |
| 549 | ev.format = 8; | |
| 550 | ev.message_type = XInternAtom (xdisplay, | |
| 551 | "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); | |
| 552 | if (len > 20) | |
| 553 | { | |
| 554 | memcpy (&ev.data, message, 20); | |
| 555 | len -= 20; | |
| 556 | message += 20; | |
| 557 | } | |
| 558 | else | |
| 559 | { | |
| 560 | memcpy (&ev.data, message, len); | |
| 561 | len = 0; | |
| 562 | } | |
| 563 | ||
| 564 | XSendEvent (xdisplay, | |
| 565 | icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); | |
| 566 | XSync (xdisplay, False); | |
| 567 | } | |
| 568 | gdk_error_trap_pop (); | |
| 569 | ||
| 570 | return stamp; | |
| 571 | } | |
| 572 | ||
| 573 | void | |
| 574 | egg_tray_icon_cancel_message (EggTrayIcon *icon, | |
| 575 | guint id) | |
| 576 | { | |
| 577 | g_return_if_fail (EGG_IS_TRAY_ICON (icon)); | |
| 578 | g_return_if_fail (id > 0); | |
|
25888
d0fdd378a635
Remove trailing whitespace
Mark Doliner <markdoliner@pidgin.im>
parents:
20796
diff
changeset
|
579 | |
| 3510 | 580 | egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, |
| 581 | (Window)gtk_plug_get_id (GTK_PLUG (icon)), | |
| 582 | id, 0, 0); | |
| 583 | } | |
| 10779 | 584 | |
| 585 | GtkOrientation | |
| 586 | egg_tray_icon_get_orientation (EggTrayIcon *icon) | |
| 587 | { | |
| 588 | g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL); | |
| 589 | ||
| 590 | return icon->orientation; | |
| 591 | } |