diff --git a/lib/Constants.vala b/lib/Constants.vala index 71e216811..5b2a1ae0c 100644 --- a/lib/Constants.vala +++ b/lib/Constants.vala @@ -35,6 +35,16 @@ namespace Gala { NUDGE = 360, } + public enum GestureAction { + NONE, + SWITCH_WORKSPACE, + SWITCH_WINDOWS, + MULTITASKING_VIEW, + DOCK, + ZOOM, + N_ACTIONS + } + /** * Used as a key for Object.set_data on Meta.Windows that should be * treated as notifications. Has to be set before the window is mapped. diff --git a/lib/WindowManager.vala b/lib/WindowManager.vala index e9201697b..c85b55be2 100644 --- a/lib/WindowManager.vala +++ b/lib/WindowManager.vala @@ -70,6 +70,9 @@ namespace Gala { */ public class ModalProxy : Object { public Clutter.Grab? grab { get; set; } + + private GestureAction[] allowed_actions; + /** * A function which is called whenever a keybinding is pressed. If you supply a custom * one you can filter out those that'd you like to be passed through and block all others. @@ -94,6 +97,14 @@ namespace Gala { public void allow_all_keybindings () { _keybinding_filter = null; } + + public void allow_actions (GestureAction[] actions) { + allowed_actions = actions; + } + + public bool filter_action (GestureAction action) { + return !(action in allowed_actions); + } } public interface WindowManager : Meta.Plugin { @@ -185,5 +196,11 @@ namespace Gala { * @param action_key The gsettings key of action. Available keys are stored in ActionKeys */ public abstract void launch_action (string action_key); + + /** + * Checks whether the action should currently be prohibited. + * @return true if the action should be prohibited, false otherwise + */ + public abstract bool filter_action (GestureAction action); } } diff --git a/src/Gestures/Gesture.vala b/src/Gestures/Gesture.vala index d0d8d7807..5ffd2831d 100644 --- a/src/Gestures/Gesture.vala +++ b/src/Gestures/Gesture.vala @@ -34,16 +34,6 @@ namespace Gala { OUT = 6, } - public enum GestureAction { - NONE, - SWITCH_WORKSPACE, - SWITCH_WINDOWS, - MULTITASKING_VIEW, - DOCK, - ZOOM, - N_ACTIONS - } - public class Gesture { public const float INVALID_COORD = float.MAX; diff --git a/src/Gestures/GestureController.vala b/src/Gestures/GestureController.vala index a3df15841..fd0d8c338 100644 --- a/src/Gestures/GestureController.vala +++ b/src/Gestures/GestureController.vala @@ -33,6 +33,7 @@ public class Gala.GestureController : Object { private const double MAX_VELOCITY = 0.01; public GestureAction action { get; construct; } + public WindowManager wm { get; construct; } private GestureTarget? _target; public GestureTarget target { @@ -89,8 +90,8 @@ public class Gala.GestureController : Object { private SpringTimeline? timeline; - public GestureController (GestureAction action, GestureTarget target) { - Object (action: action, target: target); + public GestureController (GestureAction action, GestureTarget target, WindowManager wm) { + Object (action: action, target: target, wm: wm); } public void enable_touchpad () { @@ -119,8 +120,9 @@ public class Gala.GestureController : Object { } private bool gesture_detected (GestureBackend backend, Gesture gesture, uint32 timestamp) { - recognizing = enabled && (GestureSettings.get_action (gesture, out _action_info) == action - || backend == scroll_backend && GestureSettings.get_action (gesture) == NONE); + var recognized_action = GestureSettings.get_action (gesture, out _action_info); + recognizing = enabled && (!wm.filter_action (recognized_action) && recognized_action == action || + backend == scroll_backend && recognized_action == NONE); if (recognizing) { if (gesture.direction == UP || gesture.direction == RIGHT || gesture.direction == OUT) { diff --git a/src/ShellClients/PanelWindow.vala b/src/ShellClients/PanelWindow.vala index 06bc6bc26..c2e628ce2 100644 --- a/src/ShellClients/PanelWindow.vala +++ b/src/ShellClients/PanelWindow.vala @@ -63,7 +63,7 @@ public class Gala.PanelWindow : ShellWindow { window.size_changed.connect (update_strut); window.position_changed.connect (update_strut); - gesture_controller = new GestureController (DOCK, this); + gesture_controller = new GestureController (DOCK, this, wm); window.display.in_fullscreen_changed.connect (() => { if (wm.get_display ().get_monitor_in_fullscreen (window.get_monitor ())) { diff --git a/src/Widgets/MultitaskingView/MultitaskingView.vala b/src/Widgets/MultitaskingView/MultitaskingView.vala index dea2578c8..2dfc2afa0 100644 --- a/src/Widgets/MultitaskingView/MultitaskingView.vala +++ b/src/Widgets/MultitaskingView/MultitaskingView.vala @@ -23,7 +23,6 @@ namespace Gala { */ public class MultitaskingView : ActorTarget, ActivatableComponent { public const int ANIMATION_DURATION = 250; - private const string OPEN_MULTITASKING_VIEW = "dbus-send --session --dest=org.pantheon.gala --print-reply /org/pantheon/gala org.pantheon.gala.PerformAction int32:1"; private GestureController workspaces_gesture_controller; private GestureController multitasking_gesture_controller; @@ -59,14 +58,14 @@ namespace Gala { opened = false; display = wm.get_display (); - multitasking_gesture_controller = new GestureController (MULTITASKING_VIEW, this); + multitasking_gesture_controller = new GestureController (MULTITASKING_VIEW, this, wm); multitasking_gesture_controller.enable_touchpad (); add_target (ShellClientsManager.get_instance ()); // For hiding the panels workspaces = new WorkspaceRow (display); - workspaces_gesture_controller = new GestureController (SWITCH_WORKSPACE, this) { + workspaces_gesture_controller = new GestureController (SWITCH_WORKSPACE, this, wm) { overshoot_upper_clamp = 0.1 }; workspaces_gesture_controller.enable_touchpad (); @@ -248,6 +247,7 @@ namespace Gala { modal_proxy = wm.push_modal (this); modal_proxy.set_keybinding_filter (keybinding_filter); + modal_proxy.allow_actions ({ MULTITASKING_VIEW, SWITCH_WORKSPACE, ZOOM }); var scale = display.get_monitor_scale (display.get_primary_monitor ()); icon_groups.force_reposition (); @@ -490,28 +490,7 @@ namespace Gala { private bool keybinding_filter (Meta.KeyBinding binding) { var action = Meta.Prefs.get_keybinding_action (binding.get_name ()); - // allow super key only when it toggles multitasking view - if (action == Meta.KeyBindingAction.OVERLAY_KEY && - gala_behavior_settings.get_string ("overlay-action") == OPEN_MULTITASKING_VIEW) { - return false; - } - switch (action) { - case Meta.KeyBindingAction.WORKSPACE_1: - case Meta.KeyBindingAction.WORKSPACE_2: - case Meta.KeyBindingAction.WORKSPACE_3: - case Meta.KeyBindingAction.WORKSPACE_4: - case Meta.KeyBindingAction.WORKSPACE_5: - case Meta.KeyBindingAction.WORKSPACE_6: - case Meta.KeyBindingAction.WORKSPACE_7: - case Meta.KeyBindingAction.WORKSPACE_8: - case Meta.KeyBindingAction.WORKSPACE_9: - case Meta.KeyBindingAction.WORKSPACE_10: - case Meta.KeyBindingAction.WORKSPACE_11: - case Meta.KeyBindingAction.WORKSPACE_12: - case Meta.KeyBindingAction.WORKSPACE_LEFT: - case Meta.KeyBindingAction.WORKSPACE_RIGHT: - case Meta.KeyBindingAction.SHOW_DESKTOP: case Meta.KeyBindingAction.NONE: case Meta.KeyBindingAction.LOCATE_POINTER_KEY: return false; @@ -520,12 +499,6 @@ namespace Gala { } switch (binding.get_name ()) { - case "cycle-workspaces-next": - case "cycle-workspaces-previous": - case "switch-to-workspace-first": - case "switch-to-workspace-last": - case "zoom-in": - case "zoom-out": case "screenshot": case "screenshot-clip": return false; diff --git a/src/Widgets/WindowOverview.vala b/src/Widgets/WindowOverview.vala index 6162fbc20..fcffd630e 100644 --- a/src/Widgets/WindowOverview.vala +++ b/src/Widgets/WindowOverview.vala @@ -26,7 +26,7 @@ public class Gala.WindowOverview : ActorTarget, ActivatableComponent { construct { visible = false; reactive = true; - gesture_controller = new GestureController (MULTITASKING_VIEW, this) { + gesture_controller = new GestureController (MULTITASKING_VIEW, this, wm) { enabled = false }; } @@ -113,6 +113,7 @@ public class Gala.WindowOverview : ActorTarget, ActivatableComponent { modal_proxy = wm.push_modal (this); modal_proxy.set_keybinding_filter (keybinding_filter); + modal_proxy.allow_actions ({ ZOOM }); unowned var display = wm.get_display (); @@ -166,8 +167,6 @@ public class Gala.WindowOverview : ActorTarget, ActivatableComponent { switch (binding.get_name ()) { case "expose-all-windows": - case "zoom-in": - case "zoom-out": return false; default: break; diff --git a/src/Widgets/WindowSwitcher/WindowSwitcher.vala b/src/Widgets/WindowSwitcher/WindowSwitcher.vala index c01193d4e..3cc72ca2d 100644 --- a/src/Widgets/WindowSwitcher/WindowSwitcher.vala +++ b/src/Widgets/WindowSwitcher/WindowSwitcher.vala @@ -60,7 +60,7 @@ public class Gala.WindowSwitcher : CanvasActor, GestureTarget { construct { style_manager = Drawing.StyleManager.get_instance (); - gesture_controller = new GestureController (SWITCH_WINDOWS, this) { + gesture_controller = new GestureController (SWITCH_WINDOWS, this, wm) { overshoot_upper_clamp = int.MAX, overshoot_lower_clamp = int.MIN, snap = false @@ -447,18 +447,13 @@ public class Gala.WindowSwitcher : CanvasActor, GestureTarget { private void push_modal () { modal_proxy = wm.push_modal (this); + modal_proxy.allow_actions ({ SWITCH_WINDOWS }); modal_proxy.set_keybinding_filter ((binding) => { var action = Meta.Prefs.get_keybinding_action (binding.get_name ()); switch (action) { case Meta.KeyBindingAction.NONE: case Meta.KeyBindingAction.LOCATE_POINTER_KEY: - case Meta.KeyBindingAction.SWITCH_APPLICATIONS: - case Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD: - case Meta.KeyBindingAction.SWITCH_WINDOWS: - case Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD: - case Meta.KeyBindingAction.SWITCH_GROUP: - case Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD: return false; default: break; diff --git a/src/WindowManager.vala b/src/WindowManager.vala index b19c37daa..0f5045a72 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -18,6 +18,8 @@ namespace Gala { public class WindowManagerGala : Meta.Plugin, WindowManager { + private const string OPEN_MULTITASKING_VIEW = "dbus-send --session --dest=org.pantheon.gala --print-reply /org/pantheon/gala org.pantheon.gala.PerformAction int32:1"; + /** * {@inheritDoc} */ @@ -1680,15 +1682,65 @@ namespace Gala { } public override bool keybinding_filter (Meta.KeyBinding binding) { - if (!is_modal ()) + if (!is_modal ()) { return false; + } + + var action = Meta.Prefs.get_keybinding_action (binding.get_name ()); + + switch (action) { + case Meta.KeyBindingAction.OVERLAY_KEY: + if (behavior_settings.get_string ("overlay-action") == OPEN_MULTITASKING_VIEW) { + return filter_action (MULTITASKING_VIEW); + } + break; + case Meta.KeyBindingAction.WORKSPACE_1: + case Meta.KeyBindingAction.WORKSPACE_2: + case Meta.KeyBindingAction.WORKSPACE_3: + case Meta.KeyBindingAction.WORKSPACE_4: + case Meta.KeyBindingAction.WORKSPACE_5: + case Meta.KeyBindingAction.WORKSPACE_6: + case Meta.KeyBindingAction.WORKSPACE_7: + case Meta.KeyBindingAction.WORKSPACE_8: + case Meta.KeyBindingAction.WORKSPACE_9: + case Meta.KeyBindingAction.WORKSPACE_10: + case Meta.KeyBindingAction.WORKSPACE_11: + case Meta.KeyBindingAction.WORKSPACE_12: + case Meta.KeyBindingAction.WORKSPACE_LEFT: + case Meta.KeyBindingAction.WORKSPACE_RIGHT: + return filter_action (SWITCH_WORKSPACE); + case Meta.KeyBindingAction.SHOW_DESKTOP: + return filter_action (MULTITASKING_VIEW); + case Meta.KeyBindingAction.SWITCH_APPLICATIONS: + case Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD: + case Meta.KeyBindingAction.SWITCH_WINDOWS: + case Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD: + case Meta.KeyBindingAction.SWITCH_GROUP: + case Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD: + return filter_action (SWITCH_WINDOWS); + default: + break; + } + + switch (binding.get_name ()) { + case "cycle-workspaces-next": + case "cycle-workspaces-previous": + case "switch-to-workspace-first": + case "switch-to-workspace-last": + return filter_action (SWITCH_WORKSPACE); + case "zoom-in": + case "zoom-out": + return filter_action (ZOOM); + default: + break; + } var modal_proxy = modal_stack.peek_head (); if (modal_proxy == null) { return false; } - unowned var filter = modal_proxy.get_keybinding_filter (); + unowned var filter = modal_proxy.get_keybinding_filter (); if (filter == null) { return false; } @@ -1696,6 +1748,14 @@ namespace Gala { return filter (binding); } + public bool filter_action (GestureAction action) { + if (!is_modal ()) { + return false; + } + + return modal_stack.peek_head ().filter_action (action); + } + public override void confirm_display_change () { unowned var monitor_manager = get_display ().get_context ().get_backend ().get_monitor_manager (); var timeout = monitor_manager.get_display_configuration_timeout (); diff --git a/src/Zoom.vala b/src/Zoom.vala index ce13b3176..a21309f71 100644 --- a/src/Zoom.vala +++ b/src/Zoom.vala @@ -34,7 +34,7 @@ public class Gala.Zoom : Object, GestureTarget { display.add_keybinding ("zoom-in", schema, Meta.KeyBindingFlags.NONE, (Meta.KeyHandlerFunc) zoom_in); display.add_keybinding ("zoom-out", schema, Meta.KeyBindingFlags.NONE, (Meta.KeyHandlerFunc) zoom_out); - gesture_controller = new GestureController (ZOOM, this) { + gesture_controller = new GestureController (ZOOM, this, wm) { snap = false }; gesture_controller.enable_touchpad ();