Mercurial > pidgin
changeset 4261:e252238f99df
[gaim-migrate @ 4512]
<Robot101> commit message:
<Robot101> wait
<Robot101> don't apply that
<Robot101> bloody gedit
<Robot101> there we go
<Robot101> fixed it
<Robot101> patch to fix docklet crash on unload, thanks to Nicol?s
Lichtmaier for identifying the problem and fix, and
Kristian Rietveld for implementing it
<Robot101> also implements a blinking icon when messages are pending &
credits people correctly in ChangeLog
<Robot101> and for the record, it was Nicol?s Lichtmaier who did the
icon factory stuff last night
* Robot101 hops up and down
<Robot101> patchy merge merge!
< ChipX86> fine.
<Robot101> yay =)
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Thu, 09 Jan 2003 01:48:04 +0000 |
parents | 43864b6a28a2 |
children | 7103653dd34e |
files | ChangeLog plugins/docklet/docklet.c plugins/docklet/eggtrayicon.c |
diffstat | 3 files changed, 112 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Jan 09 01:32:54 2003 +0000 +++ b/ChangeLog Thu Jan 09 01:48:04 2003 +0000 @@ -16,9 +16,11 @@ Robert McQueen) Plugins: - * Docklet plugin--replaces the old GNOME applet. You'll need the - Panel Notification Area applet for GNOME 2, or the kicker for - KDE 3.1. (Thanks, Robert McQueen, Ari Pollak, Patrick Aussems) + * Tray icon plugin--replaces the old GNOME applet. You'll need + the panel Notification Area applet (aka system-tray-applet) + for GNOME 2, or the Kicker for KDE 3.1. (Thanks, Robert + McQueen, Nicolás Lichtmaier, Kristian Rietveld, Ari Pollak & + Patrick Aussems) * Added GAIM::remove_event_handler and made set_info short circuitable in perl. (Thanks, Ryan McCabe) * event_del_conversation for plugins. (Thanks, Bill Tompkins)
--- a/plugins/docklet/docklet.c Thu Jan 09 01:32:54 2003 +0000 +++ b/plugins/docklet/docklet.c Thu Jan 09 01:48:04 2003 +0000 @@ -20,13 +20,12 @@ */ /* todo (in order of importance): - - don't crash when the plugin gets unloaded (may be a libegg bug, - see #101467 in gnome bugzilla) - - handle and update tooltips to show your current accounts ? + - check removing the icon factory actually frees the icons + - unify the queue so we can have a global away without the dialog + - handle and update tooltips to show your current accounts/queued messages? + - show a count of queued messages in the unified queue - dernyi's account status menu in the right click - - store icons in gtk2 stock icon thing (needs doing for the whole prog) - - optional pop up notices when GNOME2's system-tray-applet supports it - - support blinking the icon when messages are pending */ + - optional pop up notices when GNOME2's system-tray-applet supports it */ /* includes */ #include <gtk/gtk.h> @@ -55,10 +54,11 @@ /* globals */ static EggTrayIcon *docklet = NULL; -static GtkWidget *icon; +static GtkWidget *image = NULL; +static GtkIconFactory *icon_factory = NULL; static enum docklet_status status; -static GtkIconFactory *icon_factory = NULL; -static GtkIconSize icon_size; +static enum docklet_status icon; +static guint blinker = 0; static void docklet_toggle_mute(GtkWidget *toggle, void *data) { mute_sounds = GTK_CHECK_MENU_ITEM(toggle)->active; @@ -188,11 +188,10 @@ } } -static void docklet_update_icon() -{ +static void docklet_update_icon() { const gchar *icon_name = NULL; - switch (status) { + switch (icon) { case offline: icon_name = "gaim-docklet-offline"; break; @@ -214,9 +213,36 @@ break; } - gtk_image_set_from_stock(GTK_IMAGE(icon), icon_name, icon_size); + gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); + + debug_printf("Tray Icon: updated icon to '%s'\n", icon_name); +} - debug_printf("Tray Icon: updated icon to '%s'\n",icon_name); +static gboolean docklet_blink_icon() { + if (status == online_pending) { + if (status == icon) { + /* last icon was the right one... let's change it */ + icon = online; + } else { + /* last icon was the wrong one, change it back */ + icon = online_pending; + } + } else if (status == away_pending) { + if (status == icon) { + /* last icon was the right one... let's change it */ + icon = away; + } else { + /* last icon was the wrong one, change it back */ + icon = away_pending; + } + } else { + /* no messages, stop blinking */ + return FALSE; + } + + docklet_update_icon(); + + return TRUE; /* keep blinking */ } static gboolean docklet_update_status() { @@ -246,8 +272,15 @@ } } + /* update the icon if we changed status */ if (status != oldstatus) { + icon = status; docklet_update_icon(); + + /* and schedule the blinker function if messages are pending */ + if (status == online_pending || status == away_pending) { + blinker = g_timeout_add(500, docklet_blink_icon, NULL); + } } return FALSE; /* for when we're called by the glib idle handler */ @@ -265,6 +298,11 @@ docklet_flush_queue(); + if (blinker) { + g_source_remove(blinker); + blinker = 0; + } + g_object_unref(G_OBJECT(docklet)); docklet = NULL; @@ -284,13 +322,13 @@ docklet = egg_tray_icon_new("Gaim"); box = gtk_event_box_new(); - icon = gtk_image_new(); + image = gtk_image_new(); g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_embedded), NULL); g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_destroyed), NULL); g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_clicked), NULL); - gtk_container_add(GTK_CONTAINER(box), icon); + gtk_container_add(GTK_CONTAINER(box), image); gtk_container_add(GTK_CONTAINER(docklet), box); gtk_widget_show_all(GTK_WIDGET(docklet)); @@ -365,13 +403,9 @@ docklet_register_icon("gaim-docklet-msgpend", "msgpend.png"); gtk_icon_factory_add_default(icon_factory); - - icon_size = gtk_icon_size_register("gaim-docklet-size", 24, 24); } static void docklet_unregister_icon_factory() { - /* does this actually free anything? it's a moot point seeing as - unloading the docklet crashes gaim, but it needs to be checked */ gtk_icon_factory_remove_default(icon_factory); } @@ -401,6 +435,11 @@ docklet_flush_queue(); + if (blinker) { + g_source_remove(blinker); + blinker = 0; + } + g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_destroyed), NULL); gtk_widget_destroy(GTK_WIDGET(docklet));
--- a/plugins/docklet/eggtrayicon.c Thu Jan 09 01:32:54 2003 +0000 +++ b/plugins/docklet/eggtrayicon.c Thu Jan 09 01:48:04 2003 +0000 @@ -31,6 +31,8 @@ static void egg_tray_icon_init (EggTrayIcon *icon); static void egg_tray_icon_class_init (EggTrayIconClass *klass); +static void egg_tray_icon_unrealize (GtkWidget *widget); + static void egg_tray_icon_update_manager_window (EggTrayIcon *icon); GType @@ -57,6 +59,10 @@ our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0); } + else if (parent_class == NULL) { + /* we're reheating the old class from a previous instance - engage ugly hack =( */ + egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type)); + } return our_type; } @@ -72,7 +78,11 @@ static void egg_tray_icon_class_init (EggTrayIconClass *klass) { + GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; + parent_class = g_type_class_peek_parent (klass); + + widget_class->unrealize = egg_tray_icon_unrealize; } static GdkFilterReturn @@ -99,6 +109,38 @@ } static void +egg_tray_icon_unrealize (GtkWidget *widget) +{ + EggTrayIcon *icon = EGG_TRAY_ICON (widget); + GdkWindow *root_window; + + if (icon->manager_window != None) + { + GdkWindow *gdkwin; + +#if HAVE_GTK_MULTIHEAD + gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), + icon->manager_window); +#else + gdkwin = gdk_window_lookup (icon->manager_window); +#endif + + gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); + } + +#if HAVE_GTK_MULTIHEAD + root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); +#else + root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); +#endif + + gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon); + + if (GTK_WIDGET_CLASS (parent_class)->unrealize) + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); +} + +static void egg_tray_icon_send_manager_message (EggTrayIcon *icon, long message, Window window, @@ -158,7 +200,7 @@ GdkWindow *gdkwin; #if HAVE_GTK_MULTIHEAD - gdkwin = gdk_window_lookup_for_display (display, + gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), icon->manager_window); #else gdkwin = gdk_window_lookup (icon->manager_window); @@ -210,6 +252,10 @@ gtk_window_set_title (GTK_WINDOW (icon), name); #if HAVE_GTK_MULTIHEAD + /* FIXME: this code does not compile, screen is undefined. Now try + * getting the GdkScreen from xscreen (:. Dunno how to solve this + * (there is prolly some easy way I cant think of right now) + */ gtk_plug_construct_for_display (GTK_PLUG (icon), gdk_screen_get_display (screen), 0); #else @@ -235,7 +281,7 @@ egg_tray_icon_update_manager_window (icon); #if HAVE_GTK_MULTIHEAD - root_window = gdk_screen_get_root_window (screen); + root_window = gdk_screen_get_root_window (gtk_widget_get_screen (screen)); #else root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); #endif