diff --git a/src/DBusAccelerator.vala b/src/DBusAccelerator.vala index 493e0118f..56012be08 100644 --- a/src/DBusAccelerator.vala +++ b/src/DBusAccelerator.vala @@ -167,6 +167,7 @@ public class Gala.DBusAccelerator { icon, label, "", + {}, hints ); } diff --git a/src/NotificationsManager.vala b/src/NotificationsManager.vala index 8898fc4c1..6624af574 100644 --- a/src/NotificationsManager.vala +++ b/src/NotificationsManager.vala @@ -10,12 +10,15 @@ public class Gala.NotificationsManager : GLib.Object { [DBus (name = "org.freedesktop.Notifications")] private interface DBusNotifications : GLib.Object { + public signal void action_invoked (uint32 id, string action_key); + public abstract async uint32 notify (string app_name, uint32 replaces_id, string app_icon, string summary, string body, string[] actions, HashTable hints, int32 expire_timeout) throws DBusError, IOError; } private const int EXPIRE_TIMEOUT = 2000; + private GLib.SimpleActionGroup action_group = new GLib.SimpleActionGroup (); private DBusNotifications? notifications = null; private GLib.HashTable replaces_id_table = new GLib.HashTable (str_hash, str_equal); @@ -29,6 +32,7 @@ public class Gala.NotificationsManager : GLib.Object { (obj, res) => { try { notifications = ((DBusConnection) obj).get_proxy.end (res); + notifications.action_invoked.connect (handle_action_invoked); } catch (Error e) { warning ("NotificationsManager: Couldn't connect to notifications server: %s", e.message); notifications = null; @@ -42,11 +46,32 @@ public class Gala.NotificationsManager : GLib.Object { notifications = null; } + private void handle_action_invoked (uint32 id, string action_name) { + string name; + GLib.Variant? target_value; + + try { + GLib.Action.parse_detailed_name (action_name, out name, out target_value); + } catch (Error e) { + warning ("NotificationsManager: Couldn't parse action: %s", e.message); + return; + } + + if (action_group.has_action (name)) { + action_group.activate_action (name, target_value); + } + } + + public void add_action (GLib.Action action) { + action_group.add_action (action); + } + public async void send ( string component_name, string icon, string summary, string body, + string[] actions, GLib.HashTable hints ) { if (notifications == null) { @@ -66,7 +91,7 @@ public class Gala.NotificationsManager : GLib.Object { icon, summary, body, - {}, + actions, hints, EXPIRE_TIMEOUT ); diff --git a/src/ScreenshotManager.vala b/src/ScreenshotManager.vala index 64b56d966..ac6c0f1f4 100644 --- a/src/ScreenshotManager.vala +++ b/src/ScreenshotManager.vala @@ -22,7 +22,11 @@ namespace Gala { [DBus (name="org.gnome.Shell.Screenshot")] public class ScreenshotManager : Object { - private WindowManager wm; + [DBus (visible = false)] + public WindowManager wm { get; construct; } + [DBus (visible = false)] + public NotificationsManager notifications_manager { get; construct; } + private Settings desktop_settings; private string prev_font_regular; @@ -31,12 +35,29 @@ namespace Gala { private uint conceal_timeout; [DBus (visible = false)] - public ScreenshotManager (WindowManager _wm) { - wm = _wm; + public ScreenshotManager (WindowManager wm, NotificationsManager notifications_manager) { + Object (wm: wm, notifications_manager: notifications_manager); } construct { desktop_settings = new Settings ("org.gnome.desktop.interface"); + + var show_in_files_action = new GLib.SimpleAction ("show-in-files", GLib.VariantType.STRING); + show_in_files_action.activate.connect (show_in_files); + notifications_manager.add_action (show_in_files_action); + } + + private void show_in_files (GLib.Variant? variant) requires (variant != null && variant.is_of_type (GLib.VariantType.STRING)) { + var files_list = new GLib.List (); + files_list.append (GLib.File.new_for_path (variant.get_string ())); + + var files_appinfo = AppInfo.get_default_for_type ("inode/directory", true); + + try { + files_appinfo.launch (files_list, null); + } catch (Error e) { + warning (e.message); + } } public void flash_area (int x, int y, int width, int height) throws DBusError, IOError { diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 0a0aeead5..dee84102d 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -193,7 +193,7 @@ namespace Gala { unowned Meta.Display display = get_display (); notifications_manager = new NotificationsManager (); - screenshot_manager = new ScreenshotManager (this); + screenshot_manager = new ScreenshotManager (this, notifications_manager); DBus.init (this, notifications_manager, screenshot_manager); WindowListener.init (display); @@ -2324,7 +2324,7 @@ namespace Gala { yield screenshot_manager.screenshot_window (true, false, true, filename, out success, out filename_used); if (success) { - send_screenshot_notification (clipboard); + send_screenshot_notification (filename_used); } } catch (Error e) { // Ignore this error @@ -2342,7 +2342,7 @@ namespace Gala { yield screenshot_manager.screenshot_area (x, y, w, h, true, filename, out success, out filename_used); if (success) { - send_screenshot_notification (clipboard); + send_screenshot_notification (filename_used); } } catch (Error e) { // Ignore this error @@ -2357,19 +2357,28 @@ namespace Gala { yield screenshot_manager.screenshot (false, true, filename, out success, out filename_used); if (success) { - send_screenshot_notification (clipboard); + send_screenshot_notification (filename_used); } } catch (Error e) { // Ignore this error } } - private void send_screenshot_notification (bool clipboard) { + private void send_screenshot_notification (string filename_used) { + var clipboard = filename_used == null; + + string[] actions = {}; + if (!clipboard) { + /// TRANSLATORS: 'Files' is the name of file manager used by elementary OS + actions = { GLib.Action.print_detailed_name ("show-in-files", new Variant ("s", filename_used)), _("Show in Files") }; + } + notifications_manager.send.begin ( "ScreenshotManager", "image-x-generic", _("Screenshot taken"), clipboard ? _("Screenshot is saved to clipboard") : _("Screenshot saved to screenshots folder"), + actions, new GLib.HashTable (null, null) ); }