pidgin/gtkdocklet.c

changeset 32307
bef14ba3eda1
parent 32213
9df72c991fbc
child 32325
f6980ed6044a
equal deleted inserted replaced
32306:e702d19ea370 32307:bef14ba3eda1
28 #include "conversation.h" 28 #include "conversation.h"
29 #include "debug.h" 29 #include "debug.h"
30 #include "prefs.h" 30 #include "prefs.h"
31 #include "signals.h" 31 #include "signals.h"
32 #include "sound.h" 32 #include "sound.h"
33 #include "status.h"
33 34
34 #include "gtkaccount.h" 35 #include "gtkaccount.h"
35 #include "gtkblist.h" 36 #include "gtkblist.h"
36 #include "gtkconv.h" 37 #include "gtkconv.h"
37 #include "gtkplugin.h" 38 #include "gtkplugin.h"
46 47
47 #ifndef DOCKLET_TOOLTIP_LINE_LIMIT 48 #ifndef DOCKLET_TOOLTIP_LINE_LIMIT
48 #define DOCKLET_TOOLTIP_LINE_LIMIT 5 49 #define DOCKLET_TOOLTIP_LINE_LIMIT 5
49 #endif 50 #endif
50 51
52 #define SHORT_EMBED_TIMEOUT 5
53 #define LONG_EMBED_TIMEOUT 15
54
51 /* globals */ 55 /* globals */
52 static struct docklet_ui_ops *ui_ops = NULL; 56 static GtkStatusIcon *docklet = NULL;
57 static guint embed_timeout = 0;
53 static PurpleStatusPrimitive status = PURPLE_STATUS_OFFLINE; 58 static PurpleStatusPrimitive status = PURPLE_STATUS_OFFLINE;
54 static gboolean pending = FALSE; 59 static gboolean pending = FALSE;
55 static gboolean connecting = FALSE; 60 static gboolean connecting = FALSE;
56 static gboolean enable_join_chat = FALSE; 61 static gboolean enable_join_chat = FALSE;
57 static guint docklet_blinking_timer = 0; 62 static guint docklet_blinking_timer = 0;
58 static gboolean visible = FALSE; 63 static gboolean visible = FALSE;
59 static gboolean visibility_manager = FALSE; 64 static gboolean visibility_manager = FALSE;
60 65
66 /* protos */
67 static void docklet_gtk_status_create(gboolean);
68 static void docklet_gtk_status_destroy(void);
69
61 /************************************************************************** 70 /**************************************************************************
62 * docklet status and utility functions 71 * docklet status and utility functions
63 **************************************************************************/ 72 **************************************************************************/
73 static void
74 docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
75 {
76 const gchar *icon_name = NULL;
77
78 switch (status) {
79 case PURPLE_STATUS_OFFLINE:
80 icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
81 break;
82 case PURPLE_STATUS_AWAY:
83 icon_name = PIDGIN_STOCK_TRAY_AWAY;
84 break;
85 case PURPLE_STATUS_UNAVAILABLE:
86 icon_name = PIDGIN_STOCK_TRAY_BUSY;
87 break;
88 case PURPLE_STATUS_EXTENDED_AWAY:
89 icon_name = PIDGIN_STOCK_TRAY_XA;
90 break;
91 case PURPLE_STATUS_INVISIBLE:
92 icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
93 break;
94 default:
95 icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
96 break;
97 }
98
99 if (pending)
100 icon_name = PIDGIN_STOCK_TRAY_PENDING;
101 if (connecting)
102 icon_name = PIDGIN_STOCK_TRAY_CONNECT;
103
104 if (icon_name) {
105 gtk_status_icon_set_from_icon_name(docklet, icon_name);
106 }
107
108 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
109 gtk_status_icon_set_blinking(docklet, (pending && !connecting));
110 } else if (gtk_status_icon_get_blinking(docklet)) {
111 gtk_status_icon_set_blinking(docklet, FALSE);
112 }
113 }
114
64 static gboolean 115 static gboolean
65 docklet_blink_icon(gpointer data) 116 docklet_blink_icon(gpointer data)
66 { 117 {
67 static gboolean blinked = FALSE; 118 static gboolean blinked = FALSE;
68 gboolean ret = FALSE; /* by default, don't keep blinking */ 119 gboolean ret = FALSE; /* by default, don't keep blinking */
69 120
70 blinked = !blinked; 121 blinked = !blinked;
71 122
72 if(pending && !connecting) { 123 if(pending && !connecting) {
73 if (blinked) { 124 if (!blinked) {
74 if (ui_ops && ui_ops->blank_icon) 125 docklet_gtk_status_update_icon(status, connecting, pending);
75 ui_ops->blank_icon();
76 } else {
77 pidgin_docklet_update_icon();
78 } 126 }
79 ret = TRUE; /* keep blinking */ 127 ret = TRUE; /* keep blinking */
80 } else { 128 } else {
81 docklet_blinking_timer = 0; 129 docklet_blinking_timer = 0;
82 blinked = FALSE; 130 blinked = FALSE;
124 172
125 /* determine if any ims have unseen messages */ 173 /* determine if any ims have unseen messages */
126 convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT); 174 convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT);
127 175
128 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) { 176 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
129 if (convs && ui_ops->create && !visible) { 177 if (convs && !visible) {
130 g_list_free(convs); 178 g_list_free(convs);
131 ui_ops->create(); 179 docklet_gtk_status_create(FALSE);
132 return FALSE; 180 return FALSE;
133 } else if (!convs && ui_ops->destroy && visible) { 181 } else if (!convs && visible) {
134 ui_ops->destroy(); 182 docklet_gtk_status_destroy();
135 return FALSE; 183 return FALSE;
136 } 184 }
137 } 185 }
138 186
139 if (!visible) { 187 if (!visible) {
140 g_list_free(convs); 188 g_list_free(convs);
141 return FALSE; 189 return FALSE;
142 } 190 }
143 191
144 if (convs != NULL) { 192 if (convs != NULL) {
193 /* set tooltip if messages are pending */
194 GString *tooltip_text = g_string_new("");
145 newpending = TRUE; 195 newpending = TRUE;
146 196
147 /* set tooltip if messages are pending */ 197 for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
148 if (ui_ops->set_tooltip) { 198 PurpleConversation *conv = (PurpleConversation *)l->data;
149 GString *tooltip_text = g_string_new(""); 199 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
150 for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) { 200
151 PurpleConversation *conv = (PurpleConversation *)l->data; 201 if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
152 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 202 g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
153 203 } else if(gtkconv) {
154 if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) { 204 g_string_append_printf(tooltip_text,
155 g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); 205 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
156 } else if(gtkconv) { 206 gtkconv->unseen_count,
157 g_string_append_printf(tooltip_text, 207 purple_conversation_get_title(conv));
158 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), 208 } else {
159 gtkconv->unseen_count, 209 g_string_append_printf(tooltip_text,
160 purple_conversation_get_title(conv)); 210 ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
161 } else { 211 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
162 g_string_append_printf(tooltip_text, 212 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
163 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", 213 purple_conversation_get_title(conv));
164 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
165 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
166 purple_conversation_get_title(conv));
167 }
168 } 214 }
169 215 }
170 /* get rid of the last newline */ 216
171 if (tooltip_text->len > 0) 217 /* get rid of the last newline */
172 tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1); 218 if (tooltip_text->len > 0)
173 219 tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
174 ui_ops->set_tooltip(tooltip_text->str); 220
175 221 gtk_status_icon_set_tooltip(docklet, tooltip_text->str);
176 g_string_free(tooltip_text, TRUE); 222
177 } 223 g_string_free(tooltip_text, TRUE);
178
179 g_list_free(convs); 224 g_list_free(convs);
180 225
181 } else if (ui_ops->set_tooltip) { 226 } else {
182 char *tooltip_text = g_strconcat(PIDGIN_NAME, " - ", 227 char *tooltip_text = g_strconcat(PIDGIN_NAME, " - ",
183 purple_savedstatus_get_title(saved_status), NULL); 228 purple_savedstatus_get_title(saved_status), NULL);
184 ui_ops->set_tooltip(tooltip_text); 229 gtk_status_icon_set_tooltip(docklet, tooltip_text);
185 g_free(tooltip_text); 230 g_free(tooltip_text);
186 } 231 }
187 232
188 for(l = purple_accounts_get_all(); l != NULL; l = l->next) { 233 for(l = purple_accounts_get_all(); l != NULL; l = l->next) {
189 234
205 if (status != newstatus || pending!=newpending || connecting!=newconnecting) { 250 if (status != newstatus || pending!=newpending || connecting!=newconnecting) {
206 status = newstatus; 251 status = newstatus;
207 pending = newpending; 252 pending = newpending;
208 connecting = newconnecting; 253 connecting = newconnecting;
209 254
210 pidgin_docklet_update_icon(); 255 docklet_gtk_status_update_icon(status, connecting, pending);
211 256
212 /* and schedule the blinker function if messages are pending */ 257 /* and schedule the blinker function if messages are pending */
213 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink") 258 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
214 && pending && !connecting && docklet_blinking_timer == 0) { 259 && pending && !connecting && docklet_blinking_timer == 0) {
215 docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL); 260 docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL);
284 docklet_show_pref_changed_cb(const char *name, PurplePrefType type, 329 docklet_show_pref_changed_cb(const char *name, PurplePrefType type,
285 gconstpointer value, gpointer data) 330 gconstpointer value, gpointer data)
286 { 331 {
287 const char *val = value; 332 const char *val = value;
288 if (!strcmp(val, "always")) { 333 if (!strcmp(val, "always")) {
289 if (ui_ops->create) { 334 if (!visible)
290 if (!visible) 335 docklet_gtk_status_create(FALSE);
291 ui_ops->create(); 336 else if (!visibility_manager) {
292 else if (!visibility_manager) { 337 pidgin_blist_visibility_manager_add();
293 pidgin_blist_visibility_manager_add(); 338 visibility_manager = TRUE;
294 visibility_manager = TRUE;
295 }
296 } 339 }
297 } else if (!strcmp(val, "never")) { 340 } else if (!strcmp(val, "never")) {
298 if (visible && ui_ops->destroy) 341 if (visible)
299 ui_ops->destroy(); 342 docklet_gtk_status_destroy();
300 } else { 343 } else {
301 if (visibility_manager) { 344 if (visibility_manager) {
302 pidgin_blist_visibility_manager_remove(); 345 pidgin_blist_visibility_manager_remove();
303 visibility_manager = FALSE; 346 visibility_manager = FALSE;
304 } 347 }
748 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); 791 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL);
749 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); 792 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL);
750 #endif 793 #endif
751 gtk_widget_show_all(menu); 794 gtk_widget_show_all(menu);
752 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, 795 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
753 ui_ops->position_menu, 796 gtk_status_icon_position_menu,
754 NULL, 0, gtk_get_current_event_time()); 797 docklet, 0, gtk_get_current_event_time());
755 } 798 }
756 799
757 /************************************************************************** 800 static void
758 * public api for ui_ops
759 **************************************************************************/
760 void
761 pidgin_docklet_update_icon()
762 {
763 if (ui_ops && ui_ops->update_icon)
764 ui_ops->update_icon(status, connecting, pending);
765 }
766
767 void
768 pidgin_docklet_clicked(int button_type) 801 pidgin_docklet_clicked(int button_type)
769 { 802 {
770 switch (button_type) { 803 switch (button_type) {
771 case 1: 804 case 1:
772 if (pending) { 805 if (pending) {
783 docklet_menu(); 816 docklet_menu();
784 break; 817 break;
785 } 818 }
786 } 819 }
787 820
788 void 821 static void
789 pidgin_docklet_embedded() 822 pidgin_docklet_embedded(void)
790 { 823 {
791 if (!visibility_manager 824 if (!visibility_manager
792 && strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) { 825 && strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
793 pidgin_blist_visibility_manager_add(); 826 pidgin_blist_visibility_manager_add();
794 visibility_manager = TRUE; 827 visibility_manager = TRUE;
795 } 828 }
796 visible = TRUE; 829 visible = TRUE;
797 docklet_update_status(); 830 docklet_update_status();
798 pidgin_docklet_update_icon(); 831 docklet_gtk_status_update_icon(status, connecting, pending);
799 } 832 }
800 833
801 void 834 static void
802 pidgin_docklet_remove() 835 pidgin_docklet_remove(void)
803 { 836 {
804 if (visible) { 837 if (visible) {
805 if (visibility_manager) { 838 if (visibility_manager) {
806 pidgin_blist_visibility_manager_remove(); 839 pidgin_blist_visibility_manager_remove();
807 visibility_manager = FALSE; 840 visibility_manager = FALSE;
813 visible = FALSE; 846 visible = FALSE;
814 status = PURPLE_STATUS_OFFLINE; 847 status = PURPLE_STATUS_OFFLINE;
815 } 848 }
816 } 849 }
817 850
818 void 851 static gboolean
819 pidgin_docklet_set_ui_ops(struct docklet_ui_ops *ops) 852 docklet_gtk_recreate_cb(gpointer data)
820 { 853 {
821 ui_ops = ops; 854 docklet_gtk_status_create(TRUE);
822 } 855
823 856 return FALSE;
857 }
858
859 static gboolean
860 docklet_gtk_embed_timeout_cb(gpointer data)
861 {
862 #if !GTK_CHECK_VERSION(2,12,0)
863 if (gtk_status_icon_is_embedded(docklet)) {
864 /* Older GTK+ (<2.12) don't implement the embedded signal, but the
865 information is still accessible through the above function. */
866 purple_debug_info("docklet", "embedded\n");
867
868 pidgin_docklet_embedded();
869 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
870 }
871 else
872 #endif
873 {
874 /* The docklet was not embedded within the timeout.
875 * Remove it as a visibility manager, but leave the plugin
876 * loaded so that it can embed automatically if/when a notification
877 * area becomes available.
878 */
879 purple_debug_info("docklet", "failed to embed within timeout\n");
880 pidgin_docklet_remove();
881 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
882 }
883
884 #if GTK_CHECK_VERSION(2,12,0)
885 embed_timeout = 0;
886 return FALSE;
887 #else
888 return TRUE;
889 #endif
890 }
891
892 #if GTK_CHECK_VERSION(2,12,0)
893 static gboolean
894 docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
895 {
896 if (embed_timeout) {
897 purple_timeout_remove(embed_timeout);
898 embed_timeout = 0;
899 }
900
901 if (gtk_status_icon_is_embedded(docklet)) {
902 purple_debug_info("docklet", "embedded\n");
903
904 pidgin_docklet_embedded();
905 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
906 } else {
907 purple_debug_info("docklet", "detached\n");
908
909 pidgin_docklet_remove();
910 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
911 }
912
913 return TRUE;
914 }
915 #endif
916
917 static void
918 docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
919 {
920 purple_debug_info("docklet", "destroyed\n");
921
922 pidgin_docklet_remove();
923
924 g_object_unref(G_OBJECT(docklet));
925 docklet = NULL;
926
927 g_idle_add(docklet_gtk_recreate_cb, NULL);
928 }
929
930 static void
931 docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
932 {
933 pidgin_docklet_clicked(1);
934 }
935
936 static void
937 docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
938 {
939 purple_debug_info("docklet", "The button is %u\n", button);
940 #ifdef GDK_WINDOWING_QUARTZ
941 /* You can only click left mouse button on MacOSX native GTK. Let that be the menu */
942 pidgin_docklet_clicked(3);
943 #else
944 pidgin_docklet_clicked(button);
945 #endif
946 }
947
948 static void
949 docklet_gtk_status_destroy(void)
950 {
951 g_return_if_fail(docklet != NULL);
952
953 pidgin_docklet_remove();
954
955 if (embed_timeout) {
956 purple_timeout_remove(embed_timeout);
957 embed_timeout = 0;
958 }
959
960 gtk_status_icon_set_visible(docklet, FALSE);
961 g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
962 g_object_unref(G_OBJECT(docklet));
963 docklet = NULL;
964
965 purple_debug_info("docklet", "GTK+ destroyed\n");
966 }
967
968 static void
969 docklet_gtk_status_create(gboolean recreate)
970 {
971 if (docklet) {
972 /* if this is being called when a tray icon exists, it's because
973 something messed up. try destroying it before we proceed,
974 although docklet_refcount may be all hosed. hopefully won't happen. */
975 purple_debug_warning("docklet", "trying to create icon but it already exists?\n");
976 docklet_gtk_status_destroy();
977 }
978
979 docklet = gtk_status_icon_new();
980 g_return_if_fail(docklet != NULL);
981
982 g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
983 g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
984 #if GTK_CHECK_VERSION(2,12,0)
985 g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
986 #endif
987 g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
988
989 gtk_status_icon_set_visible(docklet, TRUE);
990
991 /* This is a hack to avoid a race condition between the docklet getting
992 * embedded in the notification area and the gtkblist restoring its
993 * previous visibility state. If the docklet does not get embedded within
994 * the timeout, it will be removed as a visibility manager until it does
995 * get embedded. Ideally, we would only call docklet_embedded() when the
996 * icon was actually embedded. This only happens when the docklet is first
997 * created, not when being recreated.
998 *
999 * The gtk docklet tracks whether it successfully embedded in a pref and
1000 * allows for a longer timeout period if it successfully embedded the last
1001 * time it was run. This should hopefully solve problems with the buddy
1002 * list not properly starting hidden when Pidgin is started on login.
1003 */
1004 if (!recreate) {
1005 pidgin_docklet_embedded();
1006 #if GTK_CHECK_VERSION(2,12,0)
1007 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
1008 embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
1009 } else {
1010 embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
1011 }
1012 #else
1013 embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
1014 #endif
1015 }
1016
1017 purple_debug_info("docklet", "GTK+ created\n");
1018 }
1019
1020 /**************************************************************************
1021 * public api
1022 **************************************************************************/
1023
824 void* 1024 void*
825 pidgin_docklet_get_handle() 1025 pidgin_docklet_get_handle()
826 { 1026 {
827 static int i; 1027 static int i;
828 return &i; 1028 return &i;
841 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE); 1041 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE);
842 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/docklet/show", "always"); 1042 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/docklet/show", "always");
843 purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show", 1043 purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show",
844 docklet_show_pref_changed_cb, NULL); 1044 docklet_show_pref_changed_cb, NULL);
845 1045
846 docklet_ui_init(); 1046 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk");
847 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always") && ui_ops && ui_ops->create) 1047 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) {
848 ui_ops->create(); 1048 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
1049 purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded");
1050 } else {
1051 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
1052 }
1053
1054 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
1055 DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "pidgin" G_DIR_SEPARATOR_S "tray");
1056
1057 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always"))
1058 docklet_gtk_status_create(FALSE);
849 1059
850 purple_signal_connect(conn_handle, "signed-on", 1060 purple_signal_connect(conn_handle, "signed-on",
851 docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL); 1061 docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL);
852 purple_signal_connect(conn_handle, "signed-off", 1062 purple_signal_connect(conn_handle, "signed-off",
853 docklet_handle, PURPLE_CALLBACK(docklet_signed_off_cb), NULL); 1063 docklet_handle, PURPLE_CALLBACK(docklet_signed_off_cb), NULL);
872 } 1082 }
873 1083
874 void 1084 void
875 pidgin_docklet_uninit() 1085 pidgin_docklet_uninit()
876 { 1086 {
877 if (visible && ui_ops && ui_ops->destroy) 1087 if (visible)
878 ui_ops->destroy(); 1088 docklet_gtk_status_destroy();
879 } 1089 }
1090

mercurial