Skip to content

Commit c7d14d6

Browse files
Add Super+Scroll action (#2182)
Co-authored-by: lenemter <[email protected]>
1 parent 0e82d63 commit c7d14d6

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

data/gala.gschema.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
<value nick="switch-to-workspace-last" value="10" />
1515
</enum>
1616

17+
<enum id="SuperScrollAction">
18+
<value nick="none" value="0" />
19+
<value nick="switch-workspace" value="1" />
20+
<value nick="zoom" value="2" />
21+
</enum>
22+
1723
<schema path="/io/elementary/desktop/screensaver/" id="io.elementary.desktop.screensaver">
1824
<key type="b" name="lock-on-suspend">
1925
<default>true</default>
@@ -96,6 +102,11 @@
96102
<summary>Whether hotcorners should be enabled when fullscreen window is opened</summary>
97103
<description></description>
98104
</key>
105+
<key enum="SuperScrollAction" name="super-scroll-action">
106+
<default>"none"</default>
107+
<summary>What action should be performed on Super + Scroll</summary>
108+
<description></description>
109+
</key>
99110
</schema>
100111

101112
<schema path="/io/elementary/desktop/wm/keybindings/" id="io.elementary.desktop.wm.keybindings">

src/SuperScrollAction.vala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SPDX-License-Identifier: GPL-3.0-or-later
3+
* SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
4+
*/
5+
6+
public class Gala.SuperScrollAction : Clutter.Action {
7+
public signal bool triggered (uint32 timestamp, double dx, double dy);
8+
9+
public Meta.Display display { private get; construct; }
10+
11+
public SuperScrollAction (Meta.Display display) {
12+
Object (display: display);
13+
}
14+
15+
public override bool handle_event (Clutter.Event event) {
16+
if (
17+
event.get_type () == SCROLL &&
18+
(event.get_state () & display.compositor_modifiers) != 0
19+
) {
20+
double dx = 0.0, dy = 0.0;
21+
switch (event.get_scroll_direction ()) {
22+
case LEFT:
23+
dx = -1.0;
24+
break;
25+
case RIGHT:
26+
dx = 1.0;
27+
break;
28+
case UP:
29+
dy = 1.0;
30+
break;
31+
case DOWN:
32+
dy = -1.0;
33+
break;
34+
default:
35+
break;
36+
}
37+
38+
// TODO: support natural scroll settings
39+
40+
return triggered (event.get_time (), dx, dy);
41+
}
42+
43+
return Clutter.EVENT_PROPAGATE;
44+
}
45+
}

src/WindowManager.vala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ namespace Gala {
383383

384384
display.window_created.connect ((window) => window_created (window));
385385

386+
var scroll_action = new SuperScrollAction (display);
387+
scroll_action.triggered.connect (handle_super_scroll);
388+
stage.add_action_full ("wm-super-scroll-action", CAPTURE, scroll_action);
389+
386390
stage.show ();
387391

388392
plugin_manager.load_waiting_plugins ();
@@ -438,6 +442,23 @@ namespace Gala {
438442
}
439443
}
440444

445+
446+
private bool handle_super_scroll (uint32 timestamp, double dx, double dy) {
447+
if (behavior_settings.get_enum ("super-scroll-action") != 1) {
448+
return Clutter.EVENT_PROPAGATE;
449+
}
450+
451+
var d = dx.abs () > dy.abs () ? dx : dy;
452+
453+
if (d > 0) {
454+
switch_to_next_workspace (Meta.MotionDirection.RIGHT, timestamp);
455+
} else if (d < 0) {
456+
switch_to_next_workspace (Meta.MotionDirection.LEFT, timestamp);
457+
}
458+
459+
return Clutter.EVENT_STOP;
460+
}
461+
441462
[CCode (instance_pos = -1)]
442463
private void handle_cycle_workspaces (Meta.Display display, Meta.Window? window, Clutter.KeyEvent event,
443464
Meta.KeyBinding binding) {

src/Zoom.vala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class Gala.Zoom : Object {
1919
private ulong wins_handler_id = 0UL;
2020

2121
private GestureTracker gesture_tracker;
22+
private GLib.Settings behavior_settings;
2223

2324
public Zoom (WindowManager wm) {
2425
Object (wm: wm);
@@ -33,6 +34,12 @@ public class Gala.Zoom : Object {
3334
gesture_tracker.enable_touchpad ();
3435
gesture_tracker.on_gesture_detected.connect (on_gesture_detected);
3536
gesture_tracker.on_gesture_handled.connect ((gesture) => zoom_with_gesture (gesture.direction));
37+
38+
behavior_settings = new GLib.Settings ("io.elementary.desktop.wm.behavior");
39+
40+
var scroll_action = new SuperScrollAction (display);
41+
scroll_action.triggered.connect (handle_super_scroll);
42+
display.get_stage ().add_action_full ("zoom-super-scroll-action", CAPTURE, scroll_action);
3643
}
3744

3845
~Zoom () {
@@ -78,6 +85,22 @@ public class Gala.Zoom : Object {
7885
return false;
7986
}
8087

88+
private bool handle_super_scroll (uint32 timestamp, double dx, double dy) {
89+
if (behavior_settings.get_enum ("super-scroll-action") != 2) {
90+
return Clutter.EVENT_PROPAGATE;
91+
}
92+
93+
var d = dx.abs () > dy.abs () ? dx : dy;
94+
95+
if (d > 0) {
96+
zoom (SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
97+
} else if (d < 0) {
98+
zoom (-SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
99+
}
100+
101+
return Clutter.EVENT_STOP;
102+
}
103+
81104
private void zoom_with_gesture (GestureDirection direction) {
82105
var initial_zoom = current_zoom;
83106
var target_zoom = (direction == GestureDirection.IN)

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ gala_bin_sources = files(
1414
'ScreenSaverManager.vala',
1515
'ScreenshotManager.vala',
1616
'SessionManager.vala',
17+
'SuperScrollAction.vala',
1718
'WindowAttentionTracker.vala',
1819
'WindowGrabTracker.vala',
1920
'WindowListener.vala',

0 commit comments

Comments
 (0)