=== modified file 'debian/changelog' --- debian/changelog 2009-03-19 16:08:12 +0000 +++ debian/changelog 2009-03-27 22:20:13 +0000 @@ -1,3 +1,20 @@ +pidgin-libnotify (0.14-1ubuntu7) jaunty; urgency=low + + * /debian/patches/indicate.patch: + * Making it so that there is also a function watching for + destroyed conversations and destroying the indicators if + they're left on the conversations. This fixes LP: #340717 + * Adjusting the timeout to block new logins when an account + connects to be 15 seconds. This helps the flood on slow + connections. Also, made it so that logins raise indicators + that show up in the indicator applet. Both of these are + trying to resolve many of the issues in LP: #345494 + * Make it so that icons are scaled to 48x48 at aspect ratio + so that they don't get squashed. Patch from Cody Russell + on LP: #338483 + + -- Ted Gould Thu, 19 Mar 2009 22:39:59 -0500 + pidgin-libnotify (0.14-1ubuntu6) jaunty; urgency=low * /debian/patches/indicate.patch: === modified file 'debian/patches/indicate.patch' --- debian/patches/indicate.patch 2009-03-19 16:08:12 +0000 +++ debian/patches/indicate.patch 2009-03-27 22:20:57 +0000 @@ -41,7 +41,7 @@ === modified file 'src/pidgin-libnotify.c' --- old/src/pidgin-libnotify.c 2009-01-31 14:57:15 +0000 -+++ new/src/pidgin-libnotify.c 2009-03-19 01:50:59 +0000 ++++ new/src/pidgin-libnotify.c 2009-03-27 22:04:46 +0000 @@ -35,15 +35,31 @@ /* for pidgin_create_prpl_icon */ @@ -74,7 +74,98 @@ static PurplePluginPrefFrame * get_plugin_pref_frame (PurplePlugin *plugin) { -@@ -177,7 +193,7 @@ +@@ -127,7 +143,9 @@ + return; + + just_signed_on_accounts = g_list_prepend (just_signed_on_accounts, account); +- g_timeout_add (5000, event_connection_throttle_cb, (gpointer)account); ++ g_timeout_add_seconds (15, event_connection_throttle_cb, (gpointer)account); ++ ++ return; + } + + /* do NOT g_free() the string returned by this function */ +@@ -154,7 +172,6 @@ + data = purple_buddy_icon_get_data (buddy_icon, &len); + + loader = gdk_pixbuf_loader_new (); +- gdk_pixbuf_loader_set_size (loader, 48, 48); + gdk_pixbuf_loader_write (loader, data, len, NULL); + gdk_pixbuf_loader_close (loader, NULL); + +@@ -169,6 +186,71 @@ + return icon; + } + ++/* ++ * This takes a pixbuf that we want to send to the notify server, and ++ * transforms it to the desired dimensions suitable for a notification. ++ * We scale the pixbuf down to size * size (square), but preserve the ++ * original aspect ratio and fill in the edges with transparent pixels ++ * if the original pixbuf was not square. ++ */ ++static GdkPixbuf * ++normalize_icon (GdkPixbuf *icon, gint size) ++{ ++ gint w, h; ++ int dest_x, dest_y; ++ gdouble max_edge; ++ gint new_width, new_height; ++ GdkPixbuf *scaled_icon; ++ GdkPixbuf *new_icon; ++ ++ w = gdk_pixbuf_get_width (icon); ++ h = gdk_pixbuf_get_height (icon); ++ ++ dest_x = dest_y = 0; ++ ++ max_edge = MAX (w, h); ++ ++ new_width = size * (w / max_edge); ++ new_height = size * (h / max_edge); ++ ++ /* Scale the image down, preserving the aspect ratio */ ++ scaled_icon = gdk_pixbuf_scale_simple (icon, ++ new_width, ++ new_height, ++ GDK_INTERP_HYPER); ++ ++ g_object_unref (icon); ++ ++ /* Create a square pixbuf with an alpha channel, dimensions size * size */ ++ new_icon = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (scaled_icon), ++ TRUE, ++ gdk_pixbuf_get_bits_per_sample (scaled_icon), ++ size, size); ++ ++ /* Clear the pixbuf so it is transparent */ ++ gdk_pixbuf_fill (new_icon, 0x00000000); ++ ++ /* Center the aspect ratio preseved pixbuf in the square pixbuf */ ++ if (new_width > new_height) { ++ dest_y = (new_width - new_height) / 2; ++ } else if (new_height > new_width) { ++ dest_x = (new_height - new_width) / 2; ++ } ++ ++ /* Copy from the aspect ratio-preserved scaled pixbuf into the ++ * new pixbuf, at a centered position. */ ++ gdk_pixbuf_copy_area (scaled_icon, ++ 0, 0, ++ gdk_pixbuf_get_width (scaled_icon), ++ gdk_pixbuf_get_height (scaled_icon), ++ new_icon, ++ dest_x, dest_y); ++ ++ g_object_unref (scaled_icon); ++ ++ return new_icon; ++} ++ + static void + action_cb (NotifyNotification *notification, + gchar *action, gpointer user_data) +@@ -177,7 +259,7 @@ PurpleConversation *conv = NULL; purple_debug_info (PLUGIN_ID, "action_cb(), " @@ -83,7 +174,7 @@ buddy = (PurpleBuddy *)g_object_get_data (G_OBJECT(notification), "buddy"); -@@ -203,7 +219,7 @@ +@@ -203,7 +285,7 @@ { PurpleContact *contact; @@ -92,7 +183,7 @@ contact = (PurpleContact *)g_object_get_data (G_OBJECT(notification), "contact"); if (contact) -@@ -222,7 +238,7 @@ +@@ -222,7 +304,7 @@ { gchar *escaped_str; @@ -101,7 +192,7 @@ gchar *truncated_str; gchar *str2; -@@ -257,31 +273,47 @@ +@@ -257,31 +339,47 @@ static void notify (const gchar *title, const gchar *body, @@ -157,7 +248,7 @@ g_free (tr_body); return; -@@ -289,27 +321,42 @@ +@@ -289,27 +387,44 @@ notification = notify_notification_new (title, tr_body, NULL, NULL); purple_debug_info (PLUGIN_ID, "notify(), new: " "title: '%s', body: '%s', buddy: '%s'\n", @@ -193,6 +284,8 @@ } - if (icon) { ++ icon = normalize_icon (icon, 48); ++ + if (icon != NULL) { notify_notification_set_icon_from_pixbuf (notification, icon); g_object_unref (icon); @@ -207,7 +300,7 @@ g_object_set_data (G_OBJECT(notification), "contact", contact); -@@ -317,7 +364,9 @@ +@@ -317,7 +432,9 @@ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL); @@ -218,7 +311,7 @@ if (!notify_notification_show (notification, NULL)) { purple_debug_error (PLUGIN_ID, "notify(), failed to send notification\n"); -@@ -329,7 +378,7 @@ +@@ -329,7 +446,7 @@ notify_buddy_signon_cb (PurpleBuddy *buddy, gpointer data) { @@ -227,7 +320,7 @@ gboolean blocked; g_return_if_fail (buddy); -@@ -349,19 +398,16 @@ +@@ -349,19 +466,16 @@ tr_name = truncate_escape_string (best_name (buddy), 25); @@ -249,7 +342,7 @@ gboolean blocked; g_return_if_fail (buddy); -@@ -381,40 +427,56 @@ +@@ -381,40 +495,56 @@ tr_name = truncate_escape_string (best_name (buddy), 25); @@ -325,7 +418,7 @@ g_free (body); } -@@ -434,20 +496,39 @@ +@@ -434,20 +564,39 @@ #ifndef DEBUG /* in debug mode, always show notifications */ if (conv && purple_conversation_has_focus (conv)) { @@ -368,7 +461,7 @@ } static void -@@ -463,10 +544,285 @@ +@@ -463,10 +612,392 @@ if (nick && !strcmp (sender, nick)) return; @@ -464,7 +557,7 @@ + gtk_window_present (window); +} + -+void ++static void +indicate_show_cb (IndicateIndicator * indicator, PurpleConversation * conv) +{ + /* g_debug ("indicate_show_cb()"); */ @@ -486,6 +579,26 @@ +} + +static void ++conv_delete_cb (PurpleConversation * conv, void * data) ++{ ++ /* g_debug("Pidgin conv delete: %s", purple_conversation_get_name(conv)); */ ++ IndicateIndicator * indicator = INDICATE_INDICATOR(purple_conversation_get_data(conv, "indicate-indicator")); ++ if (indicator != NULL) { ++ indicate_indicator_hide(indicator); ++ g_object_unref(G_OBJECT(indicator)); ++ purple_conversation_set_data(conv, "indicate-indicator", NULL); ++ } ++ ++ PidginConversation * pconv = PIDGIN_CONVERSATION(conv); ++ if (pconv != NULL) { ++ g_signal_handlers_disconnect_by_func(G_OBJECT(pconv->entry), G_CALLBACK(indicate_focus_cb), conv); ++ g_signal_handlers_disconnect_by_func(G_OBJECT(pconv->imhtml), G_CALLBACK(indicate_focus_cb), conv); ++ } ++ ++ return; ++} ++ ++static void +indicate_chat_nick (PurpleAccount *account, + const gchar *sender, + const gchar *message, @@ -623,6 +736,93 @@ + pidgin_blist_toggle_visibility(); +} + ++static gboolean ++indicate_login_timeout (gpointer data) ++{ ++ IndicateIndicator * indicator = INDICATE_INDICATOR(data); ++ ++ indicate_indicator_hide(indicator); ++ g_object_unref(G_OBJECT(indicator)); ++ ++ return FALSE; ++} ++ ++static void ++indicate_login_cb (IndicateIndicator * indicator, gpointer data) ++{ ++ PurpleBuddy * buddy = (PurpleBuddy *)data; ++ ++ if (buddy == NULL) ++ return; ++ ++ PurpleAccount * account = purple_buddy_get_account(buddy); ++ const char * name = purple_buddy_get_name(buddy); ++ ++ PurpleConversation * conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, account); ++ if (conv == NULL) { ++ conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name); ++ } ++ ++ indicate_show_cb(NULL, conv); ++ ++ return; ++} ++ ++static void ++indicate_buddy_signon_cb (PurpleBuddy *buddy, ++ gpointer data) ++{ ++ GdkPixbuf *icon = NULL; ++ PurpleBuddyIcon * buddy_icon = NULL; ++ gchar *tr_name = NULL; ++ IndicateIndicator * indicator = NULL; ++ gboolean blocked; ++ ++ g_return_if_fail (buddy); ++ ++ if (!purple_prefs_get_bool ("/plugins/gtk/libnotify/signon")) ++ return; ++ ++ if (g_list_find (just_signed_on_accounts, buddy->account)) ++ return; ++ ++ blocked = purple_prefs_get_bool ("/plugins/gtk/libnotify/blocked"); ++ if (!purple_privacy_check (buddy->account, buddy->name) && blocked) ++ return; ++ ++ if (!should_notify_unavailable (purple_buddy_get_account (buddy))) ++ return; ++ ++ tr_name = truncate_escape_string (best_name (buddy), 25); ++ ++ buddy_icon = purple_buddy_get_icon(buddy); ++ ++ if (buddy_icon != NULL) { ++ icon = pixbuf_from_buddy_icon(buddy_icon); ++ } else { ++ if (buddy != NULL) { ++ icon = pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_LARGE); ++ } ++ } ++ ++ indicator = INDICATE_INDICATOR(indicate_indicator_message_new()); ++ ++ indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "subtype", "login"); ++ indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "sender", tr_name); ++ if (icon) { ++ indicate_indicator_set_property_icon(INDICATE_INDICATOR(indicator), "icon", icon); ++ g_object_unref(G_OBJECT(icon)); ++ } ++ GTimeVal time; g_get_current_time(&time); ++ indicate_indicator_set_property_time(INDICATE_INDICATOR(indicator), "time", &time); ++ indicate_indicator_show(INDICATE_INDICATOR(indicator)); ++ ++ g_timeout_add_seconds(15, indicate_login_timeout, indicator); ++ g_signal_connect(G_OBJECT(indicator), INDICATE_INDICATOR_SIGNAL_DISPLAY, G_CALLBACK(indicate_login_cb), buddy); ++ ++ g_free (tr_name); ++} ++ +static void +notify_check_caps_helper (gpointer data, gpointer user_data) +{ @@ -658,7 +858,7 @@ } static gboolean -@@ -479,6 +835,14 @@ +@@ -479,6 +1010,14 @@ return FALSE; } @@ -673,7 +873,7 @@ conv_handle = purple_conversations_get_handle (); blist_handle = purple_blist_get_handle (); conn_handle = purple_connections_get_handle(); -@@ -497,6 +861,12 @@ +@@ -497,6 +1036,18 @@ purple_signal_connect (conv_handle, "received-chat-msg", plugin, PURPLE_CALLBACK(notify_chat_nick), NULL); @@ -683,10 +883,16 @@ + purple_signal_connect (conv_handle, "received-chat-msg", plugin, + PURPLE_CALLBACK(indicate_chat_nick), NULL); + ++ purple_signal_connect (blist_handle, "buddy-signed-on", plugin, ++ PURPLE_CALLBACK(indicate_buddy_signon_cb), NULL); ++ ++ purple_signal_connect (conv_handle, "deleting-conversation", plugin, ++ PURPLE_CALLBACK(conv_delete_cb), NULL); ++ /* used just to not display the flood of guifications we'd get */ purple_signal_connect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle), NULL); -@@ -525,6 +895,12 @@ +@@ -525,6 +1076,18 @@ purple_signal_disconnect (conv_handle, "received-chat-msg", plugin, PURPLE_CALLBACK(notify_chat_nick)); @@ -696,10 +902,16 @@ + purple_signal_disconnect (conv_handle, "received-chat-msg", plugin, + PURPLE_CALLBACK(indicate_chat_nick)); + ++ purple_signal_disconnect (blist_handle, "buddy-signed-on", plugin, ++ PURPLE_CALLBACK(indicate_buddy_signon_cb)); ++ ++ purple_signal_disconnect (conv_handle, "deleting-conversation", plugin, ++ PURPLE_CALLBACK(conv_delete_cb)); ++ purple_signal_disconnect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle)); -@@ -532,6 +908,14 @@ +@@ -532,6 +1095,14 @@ notify_uninit ();