From 66f3e0afbc88b52cc2264d4a58ec013001cd8237 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 14:25:05 +0300 Subject: [PATCH 01/11] Introduce SuperScrollAction --- src/SuperScrollAction.vala | 24 ++++++++++++++++++++++++ src/WindowManager.vala | 6 ++++++ src/meson.build | 1 + 3 files changed, 31 insertions(+) create mode 100644 src/SuperScrollAction.vala diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala new file mode 100644 index 000000000..163009dcc --- /dev/null +++ b/src/SuperScrollAction.vala @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) + */ + +public class Gala.SuperScrollAction : Clutter.Action { + public signal void triggered (); + + public Meta.Display display { private get; construct; } + + public SuperScrollAction (Meta.Display display) { + Object (display: display); + } + + public override bool handle_event (Clutter.Event event) { + if (event.get_type () == SCROLL && (event.get_state() & display.compositor_modifiers) != 0) { + triggered (); + + return Clutter.EVENT_STOP; + } + + return Clutter.EVENT_PROPAGATE; + } +} diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 825b11cf3..c3b5f71a5 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -157,8 +157,14 @@ namespace Gala { }); } #endif + + var scroll_action = new SuperScrollAction (display); + scroll_action.triggered.connect (() => warning ("Scroll")); + + stage.add_action_full ("super-scroll-action", CAPTURE, scroll_action); } + #if WITH_SYSTEMD private async void start_x11_services (GLib.Task task) { try { diff --git a/src/meson.build b/src/meson.build index 70d9d7b97..9660dd2b8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,6 +14,7 @@ gala_bin_sources = files( 'ScreenSaverManager.vala', 'ScreenshotManager.vala', 'SessionManager.vala', + 'SuperScrollAction.vala', 'WindowAttentionTracker.vala', 'WindowGrabTracker.vala', 'WindowListener.vala', From c67a14b79ec46887c7191284f4388bbaafcb257c Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 14:36:32 +0300 Subject: [PATCH 02/11] Simple prototype --- src/SuperScrollAction.vala | 8 ++++++-- src/WindowManager.vala | 12 +++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala index 163009dcc..1965300e0 100644 --- a/src/SuperScrollAction.vala +++ b/src/SuperScrollAction.vala @@ -4,7 +4,7 @@ */ public class Gala.SuperScrollAction : Clutter.Action { - public signal void triggered (); + public signal void triggered (uint32 timestamp, double dx, double dy); public Meta.Display display { private get; construct; } @@ -14,7 +14,11 @@ public class Gala.SuperScrollAction : Clutter.Action { public override bool handle_event (Clutter.Event event) { if (event.get_type () == SCROLL && (event.get_state() & display.compositor_modifiers) != 0) { - triggered (); + + double dx, dy; + event.get_scroll_delta (out dx, out dy); + + triggered (event.get_time (), dx, dy); return Clutter.EVENT_STOP; } diff --git a/src/WindowManager.vala b/src/WindowManager.vala index c3b5f71a5..3bb59338d 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -159,11 +159,21 @@ namespace Gala { #endif var scroll_action = new SuperScrollAction (display); - scroll_action.triggered.connect (() => warning ("Scroll")); + scroll_action.triggered.connect (handle_super_scroll); stage.add_action_full ("super-scroll-action", CAPTURE, scroll_action); } + private void handle_super_scroll (uint32 timestamp, double dx, double dy) { + var d = dx.abs () > dy.abs () ? dx : dy; + + if (d < 0) { + switch_to_next_workspace (Meta.MotionDirection.RIGHT, timestamp); + } else if (d > 0) { + switch_to_next_workspace (Meta.MotionDirection.LEFT, timestamp); + } + } + #if WITH_SYSTEMD private async void start_x11_services (GLib.Task task) { From 6e55a8d8eb7cb33f3033bb4c441fc3af7699c2c3 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 16:36:07 +0300 Subject: [PATCH 03/11] Fixes --- src/SuperScrollAction.vala | 31 +++++++++++++++++++++++++++---- src/WindowManager.vala | 4 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala index 1965300e0..de7204df1 100644 --- a/src/SuperScrollAction.vala +++ b/src/SuperScrollAction.vala @@ -13,10 +13,33 @@ public class Gala.SuperScrollAction : Clutter.Action { } public override bool handle_event (Clutter.Event event) { - if (event.get_type () == SCROLL && (event.get_state() & display.compositor_modifiers) != 0) { - - double dx, dy; - event.get_scroll_delta (out dx, out dy); + if ( + event.get_type () == SCROLL && + (event.get_state() & display.compositor_modifiers) != 0 && + event.get_device_type () == POINTER_DEVICE + ) { + + warning (event.get_device_type ().to_string ()); + + double dx = 0.0, dy = 0.0; + switch (event.get_scroll_direction ()) { + case LEFT: + dx = -1.0; + break; + case RIGHT: + dx = 1.0; + break; + case UP: + dy = 1.0; + break; + case DOWN: + dy = -1.0; + break; + default: + break; + } + + // TODO: support natural scroll settings triggered (event.get_time (), dx, dy); diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 3bb59338d..649fcf214 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -167,9 +167,9 @@ namespace Gala { private void handle_super_scroll (uint32 timestamp, double dx, double dy) { var d = dx.abs () > dy.abs () ? dx : dy; - if (d < 0) { + if (d > 0) { switch_to_next_workspace (Meta.MotionDirection.RIGHT, timestamp); - } else if (d > 0) { + } else if (d < 0) { switch_to_next_workspace (Meta.MotionDirection.LEFT, timestamp); } } From 7425695e27ad5c9c0577d5bfb1c8d6693f361455 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:00:39 +0300 Subject: [PATCH 04/11] Add Super + Scroll to zoom --- data/gala.gschema.xml | 11 +++++++++++ lib/WindowManager.vala | 6 ++++++ src/WindowManager.vala | 5 +++++ src/Zoom.vala | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/data/gala.gschema.xml b/data/gala.gschema.xml index e6bff01ba..b727649b0 100644 --- a/data/gala.gschema.xml +++ b/data/gala.gschema.xml @@ -14,6 +14,12 @@ + + + + + + true @@ -96,6 +102,11 @@ Whether hotcorners should be enabled when fullscreen window is opened + + "none" + What action should be performed on Super + Scroll + + diff --git a/lib/WindowManager.vala b/lib/WindowManager.vala index 38cb294a6..5fc5e184f 100644 --- a/lib/WindowManager.vala +++ b/lib/WindowManager.vala @@ -123,6 +123,12 @@ namespace Gala { */ public abstract Gala.ActivatableComponent workspace_view { get; protected set; } + /* + * This signal is sent when Super + Scroll was performed and WindowManager couldn't handle it + * which probably means that the user doesn't want to switch workspaces on Super + Scroll. + */ + public abstract signal void super_scroll_triggered (uint32 timestamp, double dx, double dy); + /** * Enters the modal mode, which means that all events are directed to the stage instead * of the windows. This is the only way to receive keyboard events besides shortcut listeners. diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 649fcf214..ca2ac861f 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -165,6 +165,11 @@ namespace Gala { } private void handle_super_scroll (uint32 timestamp, double dx, double dy) { + if (behavior_settings.get_enum ("super-scroll-action") != 1) { + super_scroll_triggered (timestamp, dx, dy); + return; + } + var d = dx.abs () > dy.abs () ? dx : dy; if (d > 0) { diff --git a/src/Zoom.vala b/src/Zoom.vala index 29d471d47..003c4f72f 100644 --- a/src/Zoom.vala +++ b/src/Zoom.vala @@ -19,6 +19,7 @@ public class Gala.Zoom : Object { private ulong wins_handler_id = 0UL; private GestureTracker gesture_tracker; + private GLib.Settings behavior_settings; public Zoom (WindowManager wm) { Object (wm: wm); @@ -32,6 +33,9 @@ public class Gala.Zoom : Object { gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION); gesture_tracker.enable_touchpad (); gesture_tracker.on_gesture_detected.connect (on_gesture_detected); + + behavior_settings = new GLib.Settings ("io.elementary.desktop.wm.behavior"); + wm.super_scroll_triggered.connect (handle_super_scroll); } ~Zoom () { @@ -49,6 +53,7 @@ public class Gala.Zoom : Object { } } + [CCode (instance_pos = -1)] private void zoom_in (Meta.Display display, Meta.Window? window, Clutter.KeyEvent event, Meta.KeyBinding binding) { @@ -75,6 +80,20 @@ public class Gala.Zoom : Object { } } + private void handle_super_scroll (uint32 timestamp, double dx, double dy) { + if (behavior_settings.get_enum ("super-scroll-action") != 2) { + return; + } + + var d = dx.abs () > dy.abs () ? dx : dy; + + if (d > 0) { + zoom (SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ()); + } else if (d < 0) { + zoom (-SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ()); + } + } + private void zoom_with_gesture (GestureDirection direction) { var initial_zoom = current_zoom; var target_zoom = (direction == GestureDirection.IN) From 7f9c279b81a9d7b4253e19542612b0fb71ae69b1 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:02:28 +0300 Subject: [PATCH 05/11] . --- src/SuperScrollAction.vala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala index de7204df1..6ebca02f9 100644 --- a/src/SuperScrollAction.vala +++ b/src/SuperScrollAction.vala @@ -15,8 +15,7 @@ public class Gala.SuperScrollAction : Clutter.Action { public override bool handle_event (Clutter.Event event) { if ( event.get_type () == SCROLL && - (event.get_state() & display.compositor_modifiers) != 0 && - event.get_device_type () == POINTER_DEVICE + (event.get_state() & display.compositor_modifiers) != 0 ) { warning (event.get_device_type ().to_string ()); From b05d74745036452401745476185a60ec40322f60 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:03:39 +0300 Subject: [PATCH 06/11] Remove blank line --- src/WindowManager.vala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WindowManager.vala b/src/WindowManager.vala index ca2ac861f..b477c5b8f 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -179,7 +179,6 @@ namespace Gala { } } - #if WITH_SYSTEMD private async void start_x11_services (GLib.Task task) { try { From e3f6debe712af5a7774e5e97b7ab4ee6f8e433aa Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:03:53 +0300 Subject: [PATCH 07/11] Remove blank line --- src/Zoom.vala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Zoom.vala b/src/Zoom.vala index 003c4f72f..3f4aa5499 100644 --- a/src/Zoom.vala +++ b/src/Zoom.vala @@ -53,7 +53,6 @@ public class Gala.Zoom : Object { } } - [CCode (instance_pos = -1)] private void zoom_in (Meta.Display display, Meta.Window? window, Clutter.KeyEvent event, Meta.KeyBinding binding) { From f4bf4f5228ead1f1f9cde7376a2659ef3c3899a4 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:04:32 +0300 Subject: [PATCH 08/11] Fix lint --- src/SuperScrollAction.vala | 2 +- src/Zoom.vala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala index 6ebca02f9..6d6d0a9ba 100644 --- a/src/SuperScrollAction.vala +++ b/src/SuperScrollAction.vala @@ -15,7 +15,7 @@ public class Gala.SuperScrollAction : Clutter.Action { public override bool handle_event (Clutter.Event event) { if ( event.get_type () == SCROLL && - (event.get_state() & display.compositor_modifiers) != 0 + (event.get_state () & display.compositor_modifiers) != 0 ) { warning (event.get_device_type ().to_string ()); diff --git a/src/Zoom.vala b/src/Zoom.vala index 3f4aa5499..db9dc8d98 100644 --- a/src/Zoom.vala +++ b/src/Zoom.vala @@ -84,7 +84,7 @@ public class Gala.Zoom : Object { return; } - var d = dx.abs () > dy.abs () ? dx : dy; + var d = dx.abs () > dy.abs () ? dx : dy; if (d > 0) { zoom (SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ()); From 148cf0f0e5420a02eb412e4b99f112b72429a23e Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:05:11 +0300 Subject: [PATCH 09/11] Remove debug --- src/SuperScrollAction.vala | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/SuperScrollAction.vala b/src/SuperScrollAction.vala index 6d6d0a9ba..430ba82ec 100644 --- a/src/SuperScrollAction.vala +++ b/src/SuperScrollAction.vala @@ -17,9 +17,6 @@ public class Gala.SuperScrollAction : Clutter.Action { event.get_type () == SCROLL && (event.get_state () & display.compositor_modifiers) != 0 ) { - - warning (event.get_device_type ().to_string ()); - double dx = 0.0, dy = 0.0; switch (event.get_scroll_direction ()) { case LEFT: From 2a636c9a18f30f45d873f8a8db78e19ab2202e27 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:10:12 +0300 Subject: [PATCH 10/11] Fix lint --- src/WindowManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WindowManager.vala b/src/WindowManager.vala index b477c5b8f..f5a194bde 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -170,7 +170,7 @@ namespace Gala { return; } - var d = dx.abs () > dy.abs () ? dx : dy; + var d = dx.abs () > dy.abs () ? dx : dy; if (d > 0) { switch_to_next_workspace (Meta.MotionDirection.RIGHT, timestamp); From 1c7456f2df07ac87ca6a34eb8304cfe1483b2526 Mon Sep 17 00:00:00 2001 From: lenemter Date: Fri, 13 Dec 2024 17:42:21 +0300 Subject: [PATCH 11/11] Move to `show_stage` --- src/WindowManager.vala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/WindowManager.vala b/src/WindowManager.vala index f5a194bde..8886bb827 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -157,11 +157,6 @@ namespace Gala { }); } #endif - - var scroll_action = new SuperScrollAction (display); - scroll_action.triggered.connect (handle_super_scroll); - - stage.add_action_full ("super-scroll-action", CAPTURE, scroll_action); } private void handle_super_scroll (uint32 timestamp, double dx, double dy) { @@ -416,6 +411,10 @@ namespace Gala { display.window_created.connect ((window) => window_created (window)); + var scroll_action = new SuperScrollAction (display); + scroll_action.triggered.connect (handle_super_scroll); + stage.add_action_full ("super-scroll-action", CAPTURE, scroll_action); + stage.show (); Idle.add (() => {