diff --git a/src/AppWindow.vala b/src/AppWindow.vala index d17570b8..571f2dae 100644 --- a/src/AppWindow.vala +++ b/src/AppWindow.vala @@ -6,6 +6,7 @@ public class Dock.AppWindow : GLib.Object { public uint64 uid { get; construct set; } + public string title { get; set; } public AppWindow (uint64 uid) { Object (uid: uid); diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala index 2180163d..3f8df2d6 100644 --- a/src/DesktopIntegration.vala +++ b/src/DesktopIntegration.vala @@ -23,4 +23,5 @@ public interface Dock.DesktopIntegration : GLib.Object { public abstract RunningApplication[] get_running_applications () throws GLib.DBusError, GLib.IOError; public abstract Window[] get_windows () throws GLib.DBusError, GLib.IOError; + public abstract void focus_window (uint64 uid) throws GLib.DBusError, GLib.IOError; } diff --git a/src/Launcher.vala b/src/Launcher.vala index b6c6fe79..817769de 100644 --- a/src/Launcher.vala +++ b/src/Launcher.vala @@ -22,6 +22,7 @@ public class Dock.Launcher : Gtk.Button { private string animate_css_class_name = ""; private uint animate_timeout_id = 0; + private Menu window_section; private Gtk.PopoverMenu popover; public Launcher (GLib.DesktopAppInfo app_info) { @@ -43,6 +44,8 @@ public class Dock.Launcher : Gtk.Button { windows = new GLib.List (); get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + window_section = new Menu (); + var action_section = new Menu (); foreach (var action in app_info.list_actions ()) { action_section.append ( @@ -58,6 +61,7 @@ public class Dock.Launcher : Gtk.Button { ); var model = new Menu (); + model.append_section (null, window_section); if (action_section.get_n_items () > 0) { model.append_section (null, action_section); } @@ -168,6 +172,20 @@ public class Dock.Launcher : Gtk.Button { } else { windows = (owned) new_windows; } + + window_section.remove_all (); + if (windows.length () < 2) { + return; + } + + foreach (var window in windows) { + var menu_item = new MenuItem ( + window.title, + MainWindow.ACTION_PREFIX + MainWindow.LAUNCHER_FOCUS_TEMPLATE.printf (app_info.get_id (), window.uid) + ); + menu_item.set_icon (app_info.get_icon ()); + window_section.append_item (menu_item); + } } public AppWindow? find_window (uint64 window_uid) { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 1c9fcd17..aeacc687 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -5,7 +5,9 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { // First %s is the app id second %s the action name - public const string LAUNCHER_ACTION_TEMPLATE = "%s.%s"; + public const string LAUNCHER_FOCUS_TEMPLATE = "%s.focus.%" + uint64.FORMAT; + // First %s is the app id second %s the action name + public const string LAUNCHER_ACTION_TEMPLATE = "%s.action.%s"; // %s is the app id public const string LAUNCHER_PINNED_ACTION_TEMPLATE = "%s-pinned"; public const string ACTION_GROUP_PREFIX = "win"; @@ -123,6 +125,22 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { AppWindow? app_window = launcher.find_window (window.uid); if (app_window == null) { app_window = new AppWindow (window.uid); + + var action = new SimpleAction (LAUNCHER_FOCUS_TEMPLATE.printf (app_id, window.uid), null); + add_action (action); + action.activate.connect (() => { + try { + desktop_integration.focus_window (window.uid); + } catch (Error e) { + warning ("Failed to focus window: %t", window.uid); + } + }); + } + app_window.title = (string) window.properties["title"]; + + var focus_action = (SimpleAction) lookup_action (LAUNCHER_FOCUS_TEMPLATE.printf (app_id, window.uid)); + if (focus_action != null && "has-focus" in window.properties) { + focus_action.set_enabled (!((bool) window.properties["has-focus"])); } unowned var window_list = launcher_window_list.get (launcher);