Make a best attempt at clearing away notifications that require actions or that exist until clicked when the calling application exits. This doesn't always work.

This commit is contained in:
Christian Hammond 2006-01-23 09:10:55 +00:00
parent df803f9d01
commit 18d8f305d0
5 changed files with 84 additions and 16 deletions

View File

@ -1,3 +1,13 @@
Mon Jan 23 01:10:23 PST 2006 Christian Hammond <chipx86@chipx86.com>
* libnotify/internal.h:
* libnotify/notification.c:
* libnotify/notify.c:
* tests/test-replace-widget.c:
- Make a best attempt at clearing away notifications that require
actions or that exist until clicked when the calling application
exits. This doesn't always work.
Sun Jan 22 23:46:27 PST 2006 Christian Hammond <chipx86@chipx86.com>
* docs/notification-spec.xml:

View File

@ -36,7 +36,13 @@
#define NOTIFY_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
#define NOTIFY_DBUS_CORE_OBJECT "/org/freedesktop/Notifications"
DBusGConnection *get_dbus_g_conn(void);
DBusGProxy *get_g_proxy(void);
DBusGConnection *_notify_get_dbus_g_conn(void);
DBusGProxy *_notify_get_g_proxy(void);
void _notify_cache_add_notification(NotifyNotification *n);
void _notify_cache_remove_notification(NotifyNotification *n);
gint _notify_notification_get_timeout(const NotifyNotification *n);
gboolean _notify_notification_has_nondefault_actions(
const NotifyNotification *n);
#endif /* _LIBNOTIFY_INTERNAL_H_ */

View File

@ -72,6 +72,7 @@ struct _NotifyNotificationPrivate
gint widget_old_x;
gint widget_old_y;
gboolean has_nondefault_actions;
gboolean updates_pending;
gboolean signals_registered;
};
@ -141,7 +142,9 @@ notify_notification_finalize(GObject *object)
{
NotifyNotification *obj = NOTIFY_NOTIFICATION(object);
NotifyNotificationPrivate *priv = obj->priv;
DBusGProxy *proxy = get_g_proxy();
DBusGProxy *proxy = _notify_get_g_proxy();
_notify_cache_remove_notification(obj);
g_free(priv->summary);
g_free(priv->body);
@ -282,6 +285,8 @@ notify_notification_new(const gchar *summary, const gchar *body,
obj->priv->attached_widget = attach;
}
_notify_cache_add_notification(obj);
return obj;
}
@ -380,7 +385,7 @@ notify_notification_show(NotifyNotification *notification, GError **error)
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
priv = notification->priv;
proxy = get_g_proxy();
proxy = _notify_get_g_proxy();
if (!priv->signals_registered)
{
@ -437,6 +442,15 @@ notify_notification_set_timeout(NotifyNotification *notification,
notification->priv->timeout = timeout;
}
gint
_notify_notification_get_timeout(const NotifyNotification *notification)
{
g_return_val_if_fail(notification != NULL, -1);
g_return_val_if_fail(NOTIFY_IS_NOTIFICATION(notification), -1);
return notification->priv->timeout;
}
void
notify_notification_set_category(NotifyNotification *notification,
const char *category)
@ -692,6 +706,7 @@ notify_notification_clear_actions(NotifyNotification *notification)
}
notification->priv->actions = NULL;
notification->priv->has_nondefault_actions = FALSE;
}
void
@ -719,6 +734,21 @@ notify_notification_add_action(NotifyNotification *notification,
pair->cb = callback;
pair->user_data = user_data;
g_hash_table_insert(priv->action_map, g_strdup(action), pair);
if (notification->priv->has_nondefault_actions &&
g_ascii_strcasecmp(action, "default"))
{
notification->priv->has_nondefault_actions = TRUE;
}
}
gboolean
_notify_notification_has_nondefault_actions(const NotifyNotification *n)
{
g_return_val_if_fail(n != NULL, FALSE);
g_return_val_if_fail(NOTIFY_IS_NOTIFICATION(n), FALSE);
return n->priv->has_nondefault_actions;
}
gboolean
@ -734,7 +764,7 @@ notify_notification_close(NotifyNotification *notification,
priv = notification->priv;
dbus_g_proxy_call(get_g_proxy(), "CloseNotification", &tmp_error,
dbus_g_proxy_call(_notify_get_g_proxy(), "CloseNotification", &tmp_error,
G_TYPE_UINT, priv->id, G_TYPE_INVALID,
G_TYPE_INVALID);

View File

@ -31,6 +31,7 @@ static gboolean _initted = FALSE;
static gchar *_app_name = NULL;
static DBusGProxy *_proxy = NULL;
static DBusGConnection *_dbus_gconn = NULL;
static GList *_active_notifications = NULL;
#ifdef __GNUC__
# define format_func __attribute__((format(printf, 1, 2)))
@ -80,9 +81,7 @@ notify_init(const char *app_name)
G_TYPE_UINT, G_TYPE_STRING,
G_TYPE_INVALID);
#ifdef HAVE_ATEXIT
atexit(notify_uninit);
#endif /* HAVE_ATEXIT */
g_atexit(notify_uninit);
_initted = TRUE;
@ -98,16 +97,24 @@ notify_get_app_name(void)
void
notify_uninit(void)
{
GList *l;
if (_app_name != NULL)
{
g_free(_app_name);
_app_name = NULL;
}
/*
* TODO: Keep track of all notifications and destroy them here?
* Definitely all notifications that don't expire.
*/
for (l = _active_notifications; l != NULL; l = l->next)
{
NotifyNotification *n = NOTIFY_NOTIFICATION(l->data);
if (_notify_notification_get_timeout(n) == 0 ||
_notify_notification_has_nondefault_actions(n))
{
notify_notification_close(n, NULL);
}
}
}
gboolean
@ -117,13 +124,13 @@ notify_is_initted(void)
}
DBusGConnection *
get_dbus_g_conn(void)
_notify_get_dbus_g_conn(void)
{
return _dbus_gconn;
}
DBusGProxy *
get_g_proxy(void)
_notify_get_g_proxy(void)
{
return _proxy;
}
@ -134,7 +141,7 @@ notify_get_server_caps(void)
GError *error = NULL;
char **caps = NULL, **cap;
GList *result = NULL;
DBusGProxy *proxy = get_g_proxy();
DBusGProxy *proxy = _notify_get_g_proxy();
g_return_val_if_fail(proxy != NULL, NULL);
@ -162,7 +169,7 @@ notify_get_server_info(char **ret_name, char **ret_vendor,
char **ret_version, char **ret_spec_version)
{
GError *error = NULL;
DBusGProxy *proxy = get_g_proxy();
DBusGProxy *proxy = _notify_get_g_proxy();
char *name, *vendor, *version, *spec_version;
g_return_val_if_fail(proxy != NULL, FALSE);
@ -193,3 +200,15 @@ notify_get_server_info(char **ret_name, char **ret_vendor,
return TRUE;
}
void
_notify_cache_add_notification(NotifyNotification *n)
{
_active_notifications = g_list_prepend(_active_notifications, n);
}
void
_notify_cache_remove_notification(NotifyNotification *n)
{
_active_notifications = g_list_remove(_active_notifications, n);
}

View File

@ -41,6 +41,9 @@ main(int argc, char *argv[])
notify_init("Replace Test");
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(gtk_main_quit), NULL);
button = gtk_button_new_with_label("click here to change notification");
gtk_container_add(GTK_CONTAINER(window), button);