Mercurial > pidgin.yaz
comparison pidgin/gtkdocklet-gtk.c @ 31471:7fb5e60fd919
Re-implement the embedding timeout, so that the buddy list doesn't
seem to disappear on startup entirely if you don't have a notification
area.
Fixes #12129.
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Tue, 14 Dec 2010 06:14:35 +0000 |
parents | 26c1c5069c28 |
children | cd61b074103a |
comparison
equal
deleted
inserted
replaced
31470:fd43277108be | 31471:7fb5e60fd919 |
---|---|
24 #include "debug.h" | 24 #include "debug.h" |
25 #include "prefs.h" | 25 #include "prefs.h" |
26 #include "pidginstock.h" | 26 #include "pidginstock.h" |
27 #include "gtkdocklet.h" | 27 #include "gtkdocklet.h" |
28 | 28 |
29 #define SHORT_EMBED_TIMEOUT 5 | |
30 #define LONG_EMBED_TIMEOUT 15 | |
31 | |
29 /* globals */ | 32 /* globals */ |
30 GtkStatusIcon *docklet = NULL; | 33 static GtkStatusIcon *docklet = NULL; |
34 static guint embed_timeout = 0; | |
35 | |
36 /* protos */ | |
37 static void docklet_gtk_status_create(gboolean); | |
38 | |
39 static gboolean | |
40 docklet_gtk_recreate_cb(gpointer data) | |
41 { | |
42 docklet_gtk_status_create(TRUE); | |
43 | |
44 return FALSE; | |
45 } | |
46 | |
47 static gboolean | |
48 docklet_gtk_embed_timeout_cb(gpointer data) | |
49 { | |
50 /* The docklet was not embedded within the timeout. | |
51 * Remove it as a visibility manager, but leave the plugin | |
52 * loaded so that it can embed automatically if/when a notification | |
53 * area becomes available. | |
54 */ | |
55 purple_debug_info("docklet", "failed to embed within timeout\n"); | |
56 pidgin_docklet_remove(); | |
57 | |
58 embed_timeout = 0; | |
59 return FALSE; | |
60 } | |
61 | |
62 static gboolean | |
63 docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data) | |
64 { | |
65 if (embed_timeout) { | |
66 purple_timeout_remove(embed_timeout); | |
67 embed_timeout = 0; | |
68 } | |
69 | |
70 if (gtk_status_icon_is_embedded(docklet)) { | |
71 purple_debug_info("docklet", "embedded\n"); | |
72 | |
73 pidgin_docklet_embedded(); | |
74 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE); | |
75 } else { | |
76 purple_debug_info("docklet", "detached\n"); | |
77 | |
78 pidgin_docklet_remove(); | |
79 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); | |
80 } | |
81 | |
82 return TRUE; | |
83 } | |
84 | |
85 static void | |
86 docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data) | |
87 { | |
88 purple_debug_info("docklet", "destroyed\n"); | |
89 | |
90 pidgin_docklet_remove(); | |
91 | |
92 g_object_unref(G_OBJECT(docklet)); | |
93 docklet = NULL; | |
94 | |
95 g_idle_add(docklet_gtk_recreate_cb, NULL); | |
96 } | |
31 | 97 |
32 static void | 98 static void |
33 docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data) | 99 docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data) |
34 { | 100 { |
35 pidgin_docklet_clicked(1); | 101 pidgin_docklet_clicked(1); |
112 { | 178 { |
113 g_return_if_fail(docklet != NULL); | 179 g_return_if_fail(docklet != NULL); |
114 | 180 |
115 pidgin_docklet_remove(); | 181 pidgin_docklet_remove(); |
116 | 182 |
183 if (embed_timeout) { | |
184 purple_timeout_remove(embed_timeout); | |
185 embed_timeout = 0; | |
186 } | |
187 | |
117 gtk_status_icon_set_visible(docklet, FALSE); | 188 gtk_status_icon_set_visible(docklet, FALSE); |
189 g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL); | |
118 g_object_unref(G_OBJECT(docklet)); | 190 g_object_unref(G_OBJECT(docklet)); |
119 docklet = NULL; | 191 docklet = NULL; |
120 | 192 |
121 purple_debug_info("docklet", "GTK+ destroyed\n"); | 193 purple_debug_info("docklet", "GTK+ destroyed\n"); |
122 } | 194 } |
135 docklet = gtk_status_icon_new(); | 207 docklet = gtk_status_icon_new(); |
136 g_return_if_fail(docklet != NULL); | 208 g_return_if_fail(docklet != NULL); |
137 | 209 |
138 g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL); | 210 g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL); |
139 g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL); | 211 g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL); |
140 | 212 g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL); |
141 pidgin_docklet_embedded(); | 213 g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL); |
214 | |
142 gtk_status_icon_set_visible(docklet, TRUE); | 215 gtk_status_icon_set_visible(docklet, TRUE); |
216 | |
217 /* This is a hack to avoid a race condition between the docklet getting | |
218 * embedded in the notification area and the gtkblist restoring its | |
219 * previous visibility state. If the docklet does not get embedded within | |
220 * the timeout, it will be removed as a visibility manager until it does | |
221 * get embedded. Ideally, we would only call docklet_embedded() when the | |
222 * icon was actually embedded. This only happens when the docklet is first | |
223 * created, not when being recreated. | |
224 * | |
225 * The gtk docklet tracks whether it successfully embedded in a pref and | |
226 * allows for a longer timeout period if it successfully embedded the last | |
227 * time it was run. This should hopefully solve problems with the buddy | |
228 * list not properly starting hidden when Pidgin is started on login. | |
229 */ | |
230 if (!recreate) { | |
231 pidgin_docklet_embedded(); | |
232 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) { | |
233 embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); | |
234 } else { | |
235 embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); | |
236 } | |
237 } | |
238 | |
143 purple_debug_info("docklet", "GTK+ created\n"); | 239 purple_debug_info("docklet", "GTK+ created\n"); |
144 } | 240 } |
145 | 241 |
146 static void | 242 static void |
147 docklet_gtk_status_create_ui_op(void) | 243 docklet_gtk_status_create_ui_op(void) |