diff options
author | Diego Escalante Urrelo <descalante@igalia.com> | 2010-03-03 08:15:12 +0800 |
---|---|---|
committer | Diego Escalante Urrelo <descalante@igalia.com> | 2010-03-16 07:29:58 +0800 |
commit | 5d2c310ba6e13fbfa3cb41c40c9b4b9e387df04e (patch) | |
tree | 543df8d4f7a9d687610eeecef32fc3431e1cdf55 /embed | |
parent | 355994be201180a7d695844114fb465d0a5b9b39 (diff) | |
download | gsoc2013-epiphany-5d2c310ba6e13fbfa3cb41c40c9b4b9e387df04e.tar.gz gsoc2013-epiphany-5d2c310ba6e13fbfa3cb41c40c9b4b9e387df04e.tar.zst gsoc2013-epiphany-5d2c310ba6e13fbfa3cb41c40c9b4b9e387df04e.zip |
downloader-view: stay alive until notifications are gone
When using notifications for downloads we usually hit the ugly case where the
notification pops but there is no GtkStatusIcon for it so it will pop in the
default location (usually bottom right). This is inconsistent with the behavior
when the GtkStatusIcon is present, which is to show it attached to it.
To fix this we hold a reference to the DownloaderView when showing the
notification and release it when such notification has been closed.
Bug #611779
Diffstat (limited to 'embed')
-rw-r--r-- | embed/downloader-view.c | 134 |
1 files changed, 69 insertions, 65 deletions
diff --git a/embed/downloader-view.c b/embed/downloader-view.c index db4e8eec9..c5ec5c4ad 100644 --- a/embed/downloader-view.c +++ b/embed/downloader-view.c @@ -71,10 +71,6 @@ struct _DownloaderViewPrivate GtkStatusIcon *status_icon; gboolean ownref; -#ifdef HAVE_LIBNOTIFY - NotifyNotification *notification; -#endif - guint source_id; }; @@ -120,11 +116,6 @@ download_dialog_delete_event_cb (GtkWidget *window, GdkEventAny *event, DownloaderView *dv); -#ifdef HAVE_LIBNOTIFY -static void -show_notification_window (DownloaderView *dv); -#endif - static void download_progress_cb (WebKitDownload *download, GParamSpec *pspec, @@ -193,10 +184,6 @@ show_status_icon (DownloaderView *dv) priv->status_icon = gtk_status_icon_new_from_stock (STOCK_DOWNLOAD); -#ifdef HAVE_LIBNOTIFY - notify_notification_attach_to_status_icon (priv->notification, priv->status_icon); -#endif - g_signal_connect_swapped (priv->status_icon, "activate", G_CALLBACK (show_downloader_cb), dv); g_signal_connect (priv->status_icon, "popup-menu", @@ -309,6 +296,65 @@ downloader_view_new (void) NULL)); } +#ifdef HAVE_LIBNOTIFY +static void +notification_closed_cb (NotifyNotification *notification, + DownloaderView *dv) +{ + g_object_unref (dv); +} + +static gboolean +show_notification_cb (NotifyNotification *notification) +{ + DownloaderView *dv; + GError *error = NULL; + + dv = g_object_get_data (G_OBJECT (notification), "dv"); + notify_notification_show (notification, &error); + + if (error) + { + /* notification_closed_cb () will never be called. */ + g_warning ("Error showing download notification: %s", + error->message); + g_object_unref (dv); + g_error_free (error); + } + + return FALSE; +} + +static void +show_notification (DownloaderView *dv, const char *title, const char *msg) +{ + NotifyNotification *notification; + GtkStatusIcon *status_icon; + + status_icon = dv->priv->status_icon; + + /* We keep the DownloaderView alive until the notification is gone. */ + g_object_ref (dv); + + notification = notify_notification_new (title, msg, + GTK_STOCK_INFO, NULL); + + g_signal_connect_after (notification, "closed", + G_CALLBACK (notification_closed_cb), dv); + g_object_set_data (G_OBJECT (notification), "dv", dv); + + notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT); + notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW); + + notify_notification_attach_to_status_icon (notification, status_icon); + + /* There are some visual glitches when the notification is shown and + * the GtkStatusIcon is still not visible. To avoid that, we delay the + * popup a bit. */ + g_timeout_add (500, (GSourceFunc) show_notification_cb, notification); +} +#endif + static char * format_interval (gdouble interval) { @@ -528,15 +574,8 @@ update_download_row (DownloaderView *dv, WebKitDownload *download) } #ifdef HAVE_LIBNOTIFY - downloaded = g_strdup_printf (_("The file “%s” has been downloaded."), - name); - notify_notification_update (dv->priv->notification, - _("Download finished"), - downloaded, - GTK_STOCK_INFO); - - show_notification_window (dv); - + downloaded = g_strdup_printf (_("The file “%s” has been downloaded."), name); + show_notification (dv, _("Download finished"), downloaded); g_free (downloaded); #endif downloader_view_remove_download (dv, download); @@ -645,27 +684,6 @@ update_buttons_timeout_cb (DownloaderView *dv) return FALSE; } -#ifdef HAVE_LIBNOTIFY -static void -show_notification_window (DownloaderView *dv) -{ - if (gtk_status_icon_is_embedded (dv->priv->status_icon)) - { - notify_notification_attach_to_status_icon - (dv->priv->notification, - dv->priv->status_icon); - } - else - { - notify_notification_attach_to_status_icon - (dv->priv->notification, - NULL); - } - - notify_notification_show (dv->priv->notification, NULL); -} -#endif - void downloader_view_add_download (DownloaderView *dv, WebKitDownload *download) @@ -683,13 +701,9 @@ downloader_view_add_download (DownloaderView *dv, #endif gboolean visible = FALSE; -#ifdef HAVE_LIBNOTIFY - char *downloading; -#endif - /* dv may be unrefed inside update_download_row if the file * downloaded completely while the user was choosing where to - * put it, so we need to protect it + * put it, so we need to protect it. */ g_object_ref (dv); g_object_ref (download); @@ -740,19 +754,16 @@ downloader_view_add_download (DownloaderView *dv, if (eel_gconf_get_boolean (CONF_DOWNLOADS_HIDDEN) && !visible) { - #ifdef HAVE_LIBNOTIFY - char *name = ephy_download_get_name (download); - downloading = g_strdup_printf(_("The file “%s” has been added to the downloads queue."), - name); - g_free (name); - notify_notification_update (dv->priv->notification, - _("Download started"), - downloading, - GTK_STOCK_INFO); + char *name; + char *downloading; + + name = ephy_download_get_name (download); + downloading = g_strdup_printf(_("The file “%s” has been added to the downloads queue."), name); - show_notification_window (dv); + show_notification (dv, _("Download started"), downloading); + g_free (name); g_free (downloading); #endif @@ -941,13 +952,6 @@ downloader_view_build_ui (DownloaderView *dv) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); g_signal_connect (selection, "changed", G_CALLBACK (selection_changed), dv); - -#ifdef HAVE_LIBNOTIFY - priv->notification = notify_notification_new (" ", " ", GTK_STOCK_INFO, NULL); - notify_notification_set_timeout (priv->notification, NOTIFY_EXPIRES_DEFAULT); - notify_notification_set_urgency (priv->notification, NOTIFY_URGENCY_LOW); -#endif - } static void |