pidgin: 27639110: Re-implement the embedding timeout, so t...
qulogic at pidgin.im
qulogic at pidgin.im
Tue Dec 14 01:20:51 EST 2010
----------------------------------------------------------------------
Revision: 27639110c18cc1d52b6bb784f844217c23a73562
Parent: d3204ab322b2b27d2f92277f31a5fd9452ad8fab
Author: qulogic at pidgin.im
Date: 12/14/10 01:14:35
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/27639110c18cc1d52b6bb784f844217c23a73562
Changelog:
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.
Changes against parent d3204ab322b2b27d2f92277f31a5fd9452ad8fab
patched pidgin/gtkdocklet-gtk.c
-------------- next part --------------
============================================================
--- pidgin/gtkdocklet-gtk.c cad88b2542a67d03d047f8e16cdb47c071665590
+++ pidgin/gtkdocklet-gtk.c 36447fe7775854c4db4bc35038f88cec4a28d091
@@ -26,10 +26,76 @@
#include "pidginstock.h"
#include "gtkdocklet.h"
+#define SHORT_EMBED_TIMEOUT 5
+#define LONG_EMBED_TIMEOUT 15
+
/* globals */
-GtkStatusIcon *docklet = NULL;
+static GtkStatusIcon *docklet = NULL;
+static guint embed_timeout = 0;
+/* protos */
+static void docklet_gtk_status_create(gboolean);
+
+static gboolean
+docklet_gtk_recreate_cb(gpointer data)
+{
+ docklet_gtk_status_create(TRUE);
+
+ return FALSE;
+}
+
+static gboolean
+docklet_gtk_embed_timeout_cb(gpointer data)
+{
+ /* The docklet was not embedded within the timeout.
+ * Remove it as a visibility manager, but leave the plugin
+ * loaded so that it can embed automatically if/when a notification
+ * area becomes available.
+ */
+ purple_debug_info("docklet", "failed to embed within timeout\n");
+ pidgin_docklet_remove();
+
+ embed_timeout = 0;
+ return FALSE;
+}
+
+static gboolean
+docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
+{
+ if (embed_timeout) {
+ purple_timeout_remove(embed_timeout);
+ embed_timeout = 0;
+ }
+
+ if (gtk_status_icon_is_embedded(docklet)) {
+ purple_debug_info("docklet", "embedded\n");
+
+ pidgin_docklet_embedded();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+ } else {
+ purple_debug_info("docklet", "detached\n");
+
+ pidgin_docklet_remove();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+ }
+
+ return TRUE;
+}
+
static void
+docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
+{
+ purple_debug_info("docklet", "destroyed\n");
+
+ pidgin_docklet_remove();
+
+ g_object_unref(G_OBJECT(docklet));
+ docklet = NULL;
+
+ g_idle_add(docklet_gtk_recreate_cb, NULL);
+}
+
+static void
docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
{
pidgin_docklet_clicked(1);
@@ -114,7 +180,13 @@ docklet_gtk_status_destroy(void)
pidgin_docklet_remove();
+ if (embed_timeout) {
+ purple_timeout_remove(embed_timeout);
+ embed_timeout = 0;
+ }
+
gtk_status_icon_set_visible(docklet, FALSE);
+ g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
g_object_unref(G_OBJECT(docklet));
docklet = NULL;
@@ -137,9 +209,33 @@ docklet_gtk_status_create(gboolean recre
g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
+ g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
+ g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
- pidgin_docklet_embedded();
gtk_status_icon_set_visible(docklet, TRUE);
+
+ /* This is a hack to avoid a race condition between the docklet getting
+ * embedded in the notification area and the gtkblist restoring its
+ * previous visibility state. If the docklet does not get embedded within
+ * the timeout, it will be removed as a visibility manager until it does
+ * get embedded. Ideally, we would only call docklet_embedded() when the
+ * icon was actually embedded. This only happens when the docklet is first
+ * created, not when being recreated.
+ *
+ * The gtk docklet tracks whether it successfully embedded in a pref and
+ * allows for a longer timeout period if it successfully embedded the last
+ * time it was run. This should hopefully solve problems with the buddy
+ * list not properly starting hidden when Pidgin is started on login.
+ */
+ if (!recreate) {
+ pidgin_docklet_embedded();
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
+ embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+ } else {
+ embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+ }
+ }
+
purple_debug_info("docklet", "GTK+ created\n");
}
More information about the Commits
mailing list