From 517ba7d0eb51b72bd4bba9b5f0069d57e0207419 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 10 Feb 2024 23:34:02 +0900 Subject: [PATCH] MultitaskingView: move keyboard navigation code into WindowCloneContainer (#1793) Co-authored-by: Leonhard <106322251+leolost2605@users.noreply.github.com> --- src/Widgets/MultitaskingView.vala | 54 ++--------- src/Widgets/WindowCloneContainer.vala | 126 ++++++++++++++------------ src/Widgets/WindowOverview.vala | 34 +++---- src/Widgets/WorkspaceClone.vala | 7 +- 4 files changed, 99 insertions(+), 122 deletions(-) diff --git a/src/Widgets/MultitaskingView.vala b/src/Widgets/MultitaskingView.vala index 6b548471d..64431bf74 100644 --- a/src/Widgets/MultitaskingView.vala +++ b/src/Widgets/MultitaskingView.vala @@ -595,45 +595,10 @@ namespace Gala { public override bool key_press_event (Clutter.KeyEvent event) { #endif if (!opened) { - return true; - } - - switch (event.get_key_symbol ()) { - case Clutter.Key.Escape: - toggle (); - break; - case Clutter.Key.Down: - select_window (Meta.MotionDirection.DOWN); - break; - case Clutter.Key.Up: - select_window (Meta.MotionDirection.UP); - break; - case Clutter.Key.Left: - select_window (Meta.MotionDirection.LEFT); - break; - case Clutter.Key.Right: - select_window (Meta.MotionDirection.RIGHT); - break; - case Clutter.Key.Return: - case Clutter.Key.KP_Enter: - if (!get_active_workspace_clone ().window_container.activate_selected_window ()) { - toggle (); - } - - break; + return Clutter.EVENT_PROPAGATE; } - return false; - } - - /** - * Inform the current WindowCloneContainer that we want to move the focus in - * a specific direction. - * - * @param direction The direction in which to move the focus to - */ - private void select_window (Meta.MotionDirection direction) { - get_active_workspace_clone ().window_container.select_next_window (direction); + return get_active_window_clone_container ().key_press_event (event); } /** @@ -641,12 +606,13 @@ namespace Gala { * * @return The active WorkspaceClone */ - private WorkspaceClone get_active_workspace_clone () { - unowned Meta.WorkspaceManager manager = display.get_workspace_manager (); + private WindowCloneContainer get_active_window_clone_container () { + unowned var manager = display.get_workspace_manager (); + unowned var active_workspace = manager.get_active_workspace (); foreach (unowned var child in workspaces.get_children ()) { - unowned WorkspaceClone workspace_clone = (WorkspaceClone) child; - if (workspace_clone.workspace == manager.get_active_workspace ()) { - return workspace_clone; + unowned var workspace_clone = (WorkspaceClone) child; + if (workspace_clone.workspace == active_workspace) { + return workspace_clone.window_container; } } @@ -655,8 +621,8 @@ namespace Gala { private void window_selected (Meta.Window window) { var time = display.get_current_time (); - unowned Meta.WorkspaceManager manager = display.get_workspace_manager (); - var workspace = window.get_workspace (); + unowned var manager = display.get_workspace_manager (); + unowned var workspace = window.get_workspace (); if (workspace != manager.get_active_workspace ()) { workspace.activate (time); diff --git a/src/Widgets/WindowCloneContainer.vala b/src/Widgets/WindowCloneContainer.vala index 473950f9e..59495b717 100644 --- a/src/Widgets/WindowCloneContainer.vala +++ b/src/Widgets/WindowCloneContainer.vala @@ -21,6 +21,7 @@ namespace Gala { */ public class WindowCloneContainer : Clutter.Actor { public signal void window_selected (Meta.Window window); + public signal void requested_close (); public int padding_top { get; set; default = 12; } public int padding_left { get; set; default = 12; } @@ -82,9 +83,9 @@ namespace Gala { var new_window = new WindowClone (wm, window, gesture_tracker, monitor_scale, overview_mode); - new_window.selected.connect (window_selected_cb); - new_window.destroy.connect (window_destroyed); - new_window.request_reposition.connect (window_request_reposition); + new_window.selected.connect ((clone) => window_selected (clone.window)); + new_window.destroy.connect (() => reflow ()); + new_window.request_reposition.connect (() => reflow ()); unowned Meta.Window? target = null; foreach (unowned var w in windows_ordered) { @@ -124,24 +125,6 @@ namespace Gala { } } - private void window_selected_cb (WindowClone clone) { - window_selected (clone.window); - } - - private void window_destroyed (Clutter.Actor actor) { - unowned var clone = (WindowClone) actor; - - clone.destroy.disconnect (window_destroyed); - clone.selected.disconnect (window_selected_cb); - clone.request_reposition.disconnect (window_request_reposition); - - reflow (); - } - - private void window_request_reposition () { - reflow (); - } - /** * Sort the windows z-order by their actual stacking to make intersections * during animations correct. @@ -217,6 +200,47 @@ namespace Gala { } } + /** + * Collect key events, mainly for redirecting them to the WindowCloneContainers to + * select the active window. + */ +#if HAS_MUTTER45 + public override bool key_press_event (Clutter.Event event) { +#else + public override bool key_press_event (Clutter.KeyEvent event) { +#endif + if (!opened) { + return Clutter.EVENT_PROPAGATE; + } + + + switch (event.get_key_symbol ()) { + case Clutter.Key.Escape: + requested_close (); + break; + case Clutter.Key.Down: + select_next_window (Meta.MotionDirection.DOWN); + break; + case Clutter.Key.Up: + select_next_window (Meta.MotionDirection.UP); + break; + case Clutter.Key.Left: + select_next_window (Meta.MotionDirection.LEFT); + break; + case Clutter.Key.Right: + select_next_window (Meta.MotionDirection.RIGHT); + break; + case Clutter.Key.Return: + case Clutter.Key.KP_Enter: + if (!activate_selected_window ()) { + requested_close (); + } + break; + } + + return Clutter.EVENT_STOP; + } + /** * Look for the next window in a direction and make this window the * new current_window. Used for keyboard navigation. @@ -228,23 +252,21 @@ namespace Gala { return; } - if (current_window == null) { - current_window = (WindowClone) get_child_at_index (0); - return; - } + WindowClone? closest = null; - var current_rect = current_window.slot; + if (current_window == null) { + closest = (WindowClone) get_child_at_index (0); + } else { + var current_rect = current_window.slot; - WindowClone? closest = null; - foreach (unowned var child in get_children ()) { - if (child == current_window) { - continue; - } + foreach (unowned var child in get_children ()) { + if (child == current_window) { + continue; + } - var window_rect = ((WindowClone) child).slot; + var window_rect = ((WindowClone) child).slot; - switch (direction) { - case Meta.MotionDirection.LEFT: + if (direction == LEFT) { if (window_rect.x > current_rect.x) { continue; } @@ -253,14 +275,11 @@ namespace Gala { if (window_rect.y + window_rect.height > current_rect.y && window_rect.y < current_rect.y + current_rect.height) { - if (closest == null - || closest.slot.x < window_rect.x) { - + if (closest == null || closest.slot.x < window_rect.x) { closest = (WindowClone) child; } } - break; - case Meta.MotionDirection.RIGHT: + } else if (direction == RIGHT) { if (window_rect.x < current_rect.x) { continue; } @@ -269,14 +288,11 @@ namespace Gala { if (window_rect.y + window_rect.height > current_rect.y && window_rect.y < current_rect.y + current_rect.height) { - if (closest == null - || closest.slot.x > window_rect.x) { - + if (closest == null || closest.slot.x > window_rect.x) { closest = (WindowClone) child; } } - break; - case Meta.MotionDirection.UP: + } else if (direction == UP) { if (window_rect.y > current_rect.y) { continue; } @@ -285,14 +301,11 @@ namespace Gala { if (window_rect.x + window_rect.width > current_rect.x && window_rect.x < current_rect.x + current_rect.width) { - if (closest == null - || closest.slot.y < window_rect.y) { - - closest = (WindowClone) child; + if (closest == null || closest.slot.y < window_rect.y) { + closest = (WindowClone) child; } } - break; - case Meta.MotionDirection.DOWN: + } else if (direction == DOWN) { if (window_rect.y < current_rect.y) { continue; } @@ -301,15 +314,14 @@ namespace Gala { if (window_rect.x + window_rect.width > current_rect.x && window_rect.x < current_rect.x + current_rect.width) { - if (closest == null - || closest.slot.y > window_rect.y) { - + if (closest == null || closest.slot.y > window_rect.y) { closest = (WindowClone) child; } } + } else { + warning ("Invalid direction"); break; - default: - break; + } } } @@ -330,7 +342,7 @@ namespace Gala { */ public bool activate_selected_window () { if (current_window != null) { - current_window.selected (); + window_selected (current_window.window); return true; } @@ -340,7 +352,7 @@ namespace Gala { /** * When opened the WindowClones are animated to a tiled layout */ - public void open (Meta.Window? selected_window = null, bool with_gesture = false, bool is_cancel_animation = false) { + public void open (Meta.Window? selected_window, bool with_gesture, bool is_cancel_animation) { if (opened) { return; } diff --git a/src/Widgets/WindowOverview.vala b/src/Widgets/WindowOverview.vala index b2e122024..95213708a 100644 --- a/src/Widgets/WindowOverview.vala +++ b/src/Widgets/WindowOverview.vala @@ -13,9 +13,9 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent { public WindowManager wm { get; construct; } private ModalProxy modal_proxy; - // the workspaces which we expose right now private List workspaces; + private WindowCloneContainer window_clone_container; public WindowOverview (WindowManager wm) { Object (wm : wm); @@ -26,24 +26,17 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent { reactive = true; } + #if HAS_MUTTER45 public override bool key_press_event (Clutter.Event event) { #else public override bool key_press_event (Clutter.KeyEvent event) { #endif - if (event.get_key_symbol () == Clutter.Key.Escape) { - close (); - - return Clutter.EVENT_STOP; + if (!is_opened ()) { + return Clutter.EVENT_PROPAGATE; } - return Clutter.EVENT_PROPAGATE; - } - - public override void key_focus_out () { - if (!contains (get_stage ().key_focus)) { - close (); - } + return window_clone_container.key_press_event (event); } #if HAS_MUTTER45 @@ -131,17 +124,20 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent { var geometry = display.get_monitor_geometry (i); var scale = display.get_monitor_scale (i); - var container = new WindowCloneContainer (wm, null, scale, true) { + window_clone_container = new WindowCloneContainer (wm, null, scale, true) { padding_top = TOP_GAP, padding_left = BORDER, padding_right = BORDER, - padding_bottom = BOTTOM_GAP + padding_bottom = BOTTOM_GAP, + width = geometry.width, + height = geometry.height, + x = geometry.x, + y = geometry.y, }; - container.set_position (geometry.x, geometry.y); - container.set_size (geometry.width, geometry.height); - container.window_selected.connect (thumb_selected); + window_clone_container.window_selected.connect (thumb_selected); + window_clone_container.requested_close.connect (() => close ()); - add_child (container); + add_child (window_clone_container); } visible = true; @@ -156,7 +152,7 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent { } container.add_window (window); - container.open (); + container.open (display.get_focus_window (), false, false); } } diff --git a/src/Widgets/WorkspaceClone.vala b/src/Widgets/WorkspaceClone.vala index 092de984d..5fe20222d 100644 --- a/src/Widgets/WorkspaceClone.vala +++ b/src/Widgets/WorkspaceClone.vala @@ -182,9 +182,12 @@ namespace Gala { background = new FramedBackground (wm); background.add_action (background_click_action); - window_container = new WindowCloneContainer (wm, gesture_tracker, scale_factor); + window_container = new WindowCloneContainer (wm, gesture_tracker, scale_factor) { + width = monitor_geometry.width, + height = monitor_geometry.height, + }; window_container.window_selected.connect ((w) => { window_selected (w); }); - window_container.set_size (monitor_geometry.width, monitor_geometry.height); + window_container.requested_close.connect (() => selected (true)); icon_group = new IconGroup (wm, workspace, scale_factor); icon_group.selected.connect (() => selected (true));