| 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 |
| 190 PurpleAccount *account = (PurpleAccount*)l->data; |
235 PurpleAccount *account = (PurpleAccount*)l->data; |
| 191 PurpleStatus *account_status; |
|
| 192 |
236 |
| 193 if (!purple_account_get_enabled(account, PIDGIN_UI)) |
237 if (!purple_account_get_enabled(account, PIDGIN_UI)) |
| 194 continue; |
238 continue; |
| 195 |
239 |
| 196 if (purple_account_is_disconnected(account)) |
240 if (purple_account_is_disconnected(account)) |
| 197 continue; |
241 continue; |
| 198 |
242 |
| 199 account_status = purple_account_get_active_status(account); |
|
| 200 if (purple_account_is_connecting(account)) |
243 if (purple_account_is_connecting(account)) |
| 201 newconnecting = TRUE; |
244 newconnecting = TRUE; |
| 202 } |
245 } |
| 203 |
246 |
| 204 newstatus = purple_savedstatus_get_type(saved_status); |
247 newstatus = purple_savedstatus_get_type(saved_status); |
| 286 docklet_show_pref_changed_cb(const char *name, PurplePrefType type, |
329 docklet_show_pref_changed_cb(const char *name, PurplePrefType type, |
| 287 gconstpointer value, gpointer data) |
330 gconstpointer value, gpointer data) |
| 288 { |
331 { |
| 289 const char *val = value; |
332 const char *val = value; |
| 290 if (!strcmp(val, "always")) { |
333 if (!strcmp(val, "always")) { |
| 291 if (ui_ops->create) { |
334 if (!visible) |
| 292 if (!visible) |
335 docklet_gtk_status_create(FALSE); |
| 293 ui_ops->create(); |
336 else if (!visibility_manager) { |
| 294 else if (!visibility_manager) { |
337 pidgin_blist_visibility_manager_add(); |
| 295 pidgin_blist_visibility_manager_add(); |
338 visibility_manager = TRUE; |
| 296 visibility_manager = TRUE; |
|
| 297 } |
|
| 298 } |
339 } |
| 299 } else if (!strcmp(val, "never")) { |
340 } else if (!strcmp(val, "never")) { |
| 300 if (visible && ui_ops->destroy) |
341 if (visible) |
| 301 ui_ops->destroy(); |
342 docklet_gtk_status_destroy(); |
| 302 } else { |
343 } else { |
| 303 if (visibility_manager) { |
344 if (visibility_manager) { |
| 304 pidgin_blist_visibility_manager_remove(); |
345 pidgin_blist_visibility_manager_remove(); |
| 305 visibility_manager = FALSE; |
346 visibility_manager = FALSE; |
| 306 } |
347 } |
| 747 pidgin_new_item_from_stock(menu, _("_Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL); |
789 pidgin_new_item_from_stock(menu, _("_Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL); |
| 748 |
790 |
| 749 #ifdef _WIN32 |
791 #ifdef _WIN32 |
| 750 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); |
792 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); |
| 751 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); |
793 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); |
| |
794 pos_func = NULL; |
| 752 #endif |
795 #endif |
| 753 gtk_widget_show_all(menu); |
796 gtk_widget_show_all(menu); |
| 754 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, |
797 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, |
| 755 ui_ops->position_menu, |
798 pos_func, |
| 756 NULL, 0, gtk_get_current_event_time()); |
799 docklet, 0, gtk_get_current_event_time()); |
| 757 } |
800 } |
| 758 |
801 |
| 759 /************************************************************************** |
802 static void |
| 760 * public api for ui_ops |
|
| 761 **************************************************************************/ |
|
| 762 void |
|
| 763 pidgin_docklet_update_icon() |
|
| 764 { |
|
| 765 if (ui_ops && ui_ops->update_icon) |
|
| 766 ui_ops->update_icon(status, connecting, pending); |
|
| 767 } |
|
| 768 |
|
| 769 void |
|
| 770 pidgin_docklet_clicked(int button_type) |
803 pidgin_docklet_clicked(int button_type) |
| 771 { |
804 { |
| 772 switch (button_type) { |
805 switch (button_type) { |
| 773 case 1: |
806 case 1: |
| 774 if (pending) { |
807 if (pending) { |
| 815 visible = FALSE; |
848 visible = FALSE; |
| 816 status = PURPLE_STATUS_OFFLINE; |
849 status = PURPLE_STATUS_OFFLINE; |
| 817 } |
850 } |
| 818 } |
851 } |
| 819 |
852 |
| 820 void |
853 static gboolean |
| 821 pidgin_docklet_set_ui_ops(struct docklet_ui_ops *ops) |
854 docklet_gtk_recreate_cb(gpointer data) |
| 822 { |
855 { |
| 823 ui_ops = ops; |
856 docklet_gtk_status_create(TRUE); |
| 824 } |
857 |
| 825 |
858 return FALSE; |
| |
859 } |
| |
860 |
| |
861 #ifndef _WIN32 |
| |
862 static gboolean |
| |
863 docklet_gtk_embed_timeout_cb(gpointer data) |
| |
864 { |
| |
865 #if !GTK_CHECK_VERSION(2,12,0) |
| |
866 if (gtk_status_icon_is_embedded(docklet)) { |
| |
867 /* Older GTK+ (<2.12) don't implement the embedded signal, but the |
| |
868 information is still accessible through the above function. */ |
| |
869 purple_debug_info("docklet", "embedded\n"); |
| |
870 |
| |
871 pidgin_docklet_embedded(); |
| |
872 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE); |
| |
873 } |
| |
874 else |
| |
875 #endif |
| |
876 { |
| |
877 /* The docklet was not embedded within the timeout. |
| |
878 * Remove it as a visibility manager, but leave the plugin |
| |
879 * loaded so that it can embed automatically if/when a notification |
| |
880 * area becomes available. |
| |
881 */ |
| |
882 purple_debug_info("docklet", "failed to embed within timeout\n"); |
| |
883 pidgin_docklet_remove(); |
| |
884 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); |
| |
885 } |
| |
886 |
| |
887 #if GTK_CHECK_VERSION(2,12,0) |
| |
888 embed_timeout = 0; |
| |
889 return FALSE; |
| |
890 #else |
| |
891 return TRUE; |
| |
892 #endif |
| |
893 } |
| |
894 #endif |
| |
895 |
| |
896 #if GTK_CHECK_VERSION(2,12,0) |
| |
897 static gboolean |
| |
898 docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data) |
| |
899 { |
| |
900 if (embed_timeout) { |
| |
901 purple_timeout_remove(embed_timeout); |
| |
902 embed_timeout = 0; |
| |
903 } |
| |
904 |
| |
905 if (gtk_status_icon_is_embedded(docklet)) { |
| |
906 purple_debug_info("docklet", "embedded\n"); |
| |
907 |
| |
908 pidgin_docklet_embedded(); |
| |
909 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE); |
| |
910 } else { |
| |
911 purple_debug_info("docklet", "detached\n"); |
| |
912 |
| |
913 pidgin_docklet_remove(); |
| |
914 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); |
| |
915 } |
| |
916 |
| |
917 return TRUE; |
| |
918 } |
| |
919 #endif |
| |
920 |
| |
921 static void |
| |
922 docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data) |
| |
923 { |
| |
924 purple_debug_info("docklet", "destroyed\n"); |
| |
925 |
| |
926 pidgin_docklet_remove(); |
| |
927 |
| |
928 g_object_unref(G_OBJECT(docklet)); |
| |
929 docklet = NULL; |
| |
930 |
| |
931 g_idle_add(docklet_gtk_recreate_cb, NULL); |
| |
932 } |
| |
933 |
| |
934 static void |
| |
935 docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data) |
| |
936 { |
| |
937 pidgin_docklet_clicked(1); |
| |
938 } |
| |
939 |
| |
940 static void |
| |
941 docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data) |
| |
942 { |
| |
943 purple_debug_info("docklet", "The button is %u\n", button); |
| |
944 #ifdef GDK_WINDOWING_QUARTZ |
| |
945 /* You can only click left mouse button on MacOSX native GTK. Let that be the menu */ |
| |
946 pidgin_docklet_clicked(3); |
| |
947 #else |
| |
948 pidgin_docklet_clicked(button); |
| |
949 #endif |
| |
950 } |
| |
951 |
| |
952 static void |
| |
953 docklet_gtk_status_destroy(void) |
| |
954 { |
| |
955 g_return_if_fail(docklet != NULL); |
| |
956 |
| |
957 pidgin_docklet_remove(); |
| |
958 |
| |
959 if (embed_timeout) { |
| |
960 purple_timeout_remove(embed_timeout); |
| |
961 embed_timeout = 0; |
| |
962 } |
| |
963 |
| |
964 gtk_status_icon_set_visible(docklet, FALSE); |
| |
965 g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL); |
| |
966 g_object_unref(G_OBJECT(docklet)); |
| |
967 docklet = NULL; |
| |
968 |
| |
969 purple_debug_info("docklet", "GTK+ destroyed\n"); |
| |
970 } |
| |
971 |
| |
972 static void |
| |
973 docklet_gtk_status_create(gboolean recreate) |
| |
974 { |
| |
975 if (docklet) { |
| |
976 /* if this is being called when a tray icon exists, it's because |
| |
977 something messed up. try destroying it before we proceed, |
| |
978 although docklet_refcount may be all hosed. hopefully won't happen. */ |
| |
979 purple_debug_warning("docklet", "trying to create icon but it already exists?\n"); |
| |
980 docklet_gtk_status_destroy(); |
| |
981 } |
| |
982 |
| |
983 docklet = gtk_status_icon_new(); |
| |
984 g_return_if_fail(docklet != NULL); |
| |
985 |
| |
986 g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL); |
| |
987 g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL); |
| |
988 #if GTK_CHECK_VERSION(2,12,0) |
| |
989 g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL); |
| |
990 #endif |
| |
991 g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL); |
| |
992 |
| |
993 gtk_status_icon_set_visible(docklet, TRUE); |
| |
994 |
| |
995 /* This is a hack to avoid a race condition between the docklet getting |
| |
996 * embedded in the notification area and the gtkblist restoring its |
| |
997 * previous visibility state. If the docklet does not get embedded within |
| |
998 * the timeout, it will be removed as a visibility manager until it does |
| |
999 * get embedded. Ideally, we would only call docklet_embedded() when the |
| |
1000 * icon was actually embedded. This only happens when the docklet is first |
| |
1001 * created, not when being recreated. |
| |
1002 * |
| |
1003 * The gtk docklet tracks whether it successfully embedded in a pref and |
| |
1004 * allows for a longer timeout period if it successfully embedded the last |
| |
1005 * time it was run. This should hopefully solve problems with the buddy |
| |
1006 * list not properly starting hidden when Pidgin is started on login. |
| |
1007 */ |
| |
1008 if (!recreate) { |
| |
1009 pidgin_docklet_embedded(); |
| |
1010 #ifndef _WIN32 |
| |
1011 #if GTK_CHECK_VERSION(2,12,0) |
| |
1012 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) { |
| |
1013 embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); |
| |
1014 } else { |
| |
1015 embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); |
| |
1016 } |
| |
1017 #else |
| |
1018 embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); |
| |
1019 #endif |
| |
1020 #endif |
| |
1021 } |
| |
1022 |
| |
1023 purple_debug_info("docklet", "GTK+ created\n"); |
| |
1024 } |
| |
1025 |
| |
1026 /************************************************************************** |
| |
1027 * public api |
| |
1028 **************************************************************************/ |
| |
1029 |
| 826 void* |
1030 void* |
| 827 pidgin_docklet_get_handle() |
1031 pidgin_docklet_get_handle() |
| 828 { |
1032 { |
| 829 static int i; |
1033 static int i; |
| 830 return &i; |
1034 return &i; |
| 836 void *conn_handle = purple_connections_get_handle(); |
1040 void *conn_handle = purple_connections_get_handle(); |
| 837 void *conv_handle = purple_conversations_get_handle(); |
1041 void *conv_handle = purple_conversations_get_handle(); |
| 838 void *accounts_handle = purple_accounts_get_handle(); |
1042 void *accounts_handle = purple_accounts_get_handle(); |
| 839 void *status_handle = purple_savedstatuses_get_handle(); |
1043 void *status_handle = purple_savedstatuses_get_handle(); |
| 840 void *docklet_handle = pidgin_docklet_get_handle(); |
1044 void *docklet_handle = pidgin_docklet_get_handle(); |
| |
1045 gchar *tmp; |
| 841 |
1046 |
| 842 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet"); |
1047 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet"); |
| 843 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE); |
1048 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE); |
| 844 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/docklet/show", "always"); |
1049 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/docklet/show", "always"); |
| 845 purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show", |
1050 purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show", |
| 846 docklet_show_pref_changed_cb, NULL); |
1051 docklet_show_pref_changed_cb, NULL); |
| 847 |
1052 |
| 848 docklet_ui_init(); |
1053 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk"); |
| 849 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always") && ui_ops && ui_ops->create) |
1054 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) { |
| 850 ui_ops->create(); |
1055 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE); |
| |
1056 purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded"); |
| |
1057 } else { |
| |
1058 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); |
| |
1059 } |
| |
1060 |
| |
1061 tmp = g_build_path(G_DIR_SEPARATOR_S, DATADIR, "pixmaps", "pidgin", "tray", NULL); |
| |
1062 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), tmp); |
| |
1063 g_free(tmp); |
| |
1064 |
| |
1065 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always")) |
| |
1066 docklet_gtk_status_create(FALSE); |
| 851 |
1067 |
| 852 purple_signal_connect(conn_handle, "signed-on", |
1068 purple_signal_connect(conn_handle, "signed-on", |
| 853 docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL); |
1069 docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL); |
| 854 purple_signal_connect(conn_handle, "signed-off", |
1070 purple_signal_connect(conn_handle, "signed-off", |
| 855 docklet_handle, PURPLE_CALLBACK(docklet_signed_off_cb), NULL); |
1071 docklet_handle, PURPLE_CALLBACK(docklet_signed_off_cb), NULL); |