notifications: add support for default action

This implements activation of the "default" action and adds the "actions" capability
to the server in order to make all apps set their actions if they have any.
This commit is contained in:
Tom Beckmann 2014-10-07 19:08:31 +02:00
parent 5c76b8046f
commit ead2a1fe45
2 changed files with 38 additions and 3 deletions

View File

@ -167,9 +167,11 @@ namespace Gala.Plugins.Notify
public string summary { get; construct set; }
public string body { get; construct set; }
public uint32 sender_pid { get; construct; }
public string[] notification_actions { get; construct; }
public string[] notification_actions { get; construct set; }
public Screen screen { get; construct; }
public signal void default_action_invoked ();
Actor content_container;
NormalNotificationContent notification_content;
NormalNotificationContent? old_notification_content = null;
@ -234,6 +236,7 @@ namespace Gala.Plugins.Notify
});
}
notification_actions = actions;
update_base (icon, expire_timeout);
}
@ -270,6 +273,17 @@ namespace Gala.Plugins.Notify
public override void activate ()
{
// we currently only support the default action, which can be triggered by clicking
// on the notification according to spec
for (var i = 0; i < notification_actions.length; i += 2) {
if (notification_actions[i] == "default") {
default_action_invoked ();
return;
}
}
// if no default action has been set, we fallback to trying to find a window for the
// notification's sender process
var window = get_window ();
if (window != null) {
var workspace = window.get_workspace ();

View File

@ -91,6 +91,11 @@ namespace Gala.Plugins.Notify
"body",
"body-markup",
"sound",
// even though we don't fully support actions, we still want to receive the default
// action. Well written applications will check if the actions capability is available
// before settings a default action, so we have to specify it here. Also, not displaying
// certain actions even though requested is allowed according to spec, so we should be fine
"actions",
"x-canonical-private-synchronous",
"x-canonical-private-icon-only"
};
@ -146,7 +151,7 @@ namespace Gala.Plugins.Notify
var confirmation = hints.contains ("x-canonical-private-synchronous");
var progress = confirmation && hints.contains ("value");
#if 0 // enable to debug notifications
#if true // enable to debug notifications
print ("Notification from '%s', replaces: %u\n" +
"\tapp icon: '%s'\n\tsummary: '%s'\n\tbody: '%s'\n\tn actions: %u\n\texpire: %i\n\tHints:\n",
app_name, replaces_id, app_icon, summary, body, actions.length);
@ -154,6 +159,11 @@ namespace Gala.Plugins.Notify
print ("\t\t%s => %s\n", key, val.is_of_type (VariantType.STRING) ?
val.get_string () : "<" + val.get_type ().dup_string () + ">");
});
print ("\tActions: ");
foreach (var action in actions) {
print ("%s, ", action);
}
print ("\n");
#endif
uint32 pid = 0;
@ -204,9 +214,11 @@ namespace Gala.Plugins.Notify
notification = new ConfirmationNotification (id, pixbuf, icon_only,
progress ? hints.@get ("value").get_int32 () : -1,
hints.@get ("x-canonical-private-synchronous").get_string ());
else
else {
notification = new NormalNotification (stack.screen, id, summary, body, pixbuf,
urgency, timeout, pid, actions);
((NormalNotification) notification).default_action_invoked.connect (default_action_invoked);
}
notification.closed.connect (notification_closed_callback);
stack.show_notification (notification);
@ -456,8 +468,17 @@ namespace Gala.Plugins.Notify
{
notification.closed.disconnect (notification_closed_callback);
var normal_notification = notification as NormalNotification;
if (normal_notification != null)
normal_notification.default_action_invoked.disconnect (default_action_invoked);
notification_closed (id, reason);
}
void default_action_invoked (Notification notification)
{
action_invoked (notification.id, "default");
}
}
}