Skip to content

Commit e48e352

Browse files
committed
gestures: Implement configurable gestures using new cosmic-settings-daemon config
This commit adds very very simple configurable touchpad gestures, starting with next and previous workspace. We need to add support for more actions at some point, but this is a good start. Signed-off-by: Ryan Brue <[email protected]>
1 parent 7ac204e commit e48e352

File tree

7 files changed

+75
-71
lines changed

7 files changed

+75
-71
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ calloop = {version = "0.14.1", features = ["executor"]}
1818
cosmic-comp-config = {path = "cosmic-comp-config"}
1919
cosmic-config = {git = "https://github.com/pop-os/libcosmic/", features = ["calloop", "macro"]}
2020
cosmic-protocols = {git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"]}
21-
cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" }
21+
# cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" }
22+
cosmic-settings-config = { git = "https://github.com/ryanabx-contrib/cosmic-settings-daemon", branch = "gestures" }
2223
edid-rs = {version = "0.1"}
2324
egui = {version = "0.29.0", optional = true}
2425
egui_plot = {version = "0.29.0", optional = true}

src/config/gestures.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use cosmic_comp_config::workspace::WorkspaceLayout;
2+
use cosmic_settings_config::shortcuts::{self, action::Direction, Gestures};
3+
4+
pub fn add_default_gestures(gestures: &mut Gestures, workspace_layout: WorkspaceLayout) {
5+
// TODO: Do we take into account natural scroll?
6+
let (workspace_forward, workspace_backward) = match workspace_layout {
7+
WorkspaceLayout::Vertical => (Direction::Up, Direction::Down),
8+
WorkspaceLayout::Horizontal => (Direction::Left, Direction::Right),
9+
};
10+
11+
gestures.insert_default_gesture(
12+
4 as u32,
13+
workspace_forward.clone(),
14+
shortcuts::Action::NextWorkspace,
15+
);
16+
17+
gestures.insert_default_gesture(
18+
4 as u32,
19+
workspace_backward.clone(),
20+
shortcuts::Action::PreviousWorkspace,
21+
);
22+
23+
// TODO: More default gestures?
24+
}

src/config/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::{
88
},
99
};
1010
use cosmic_config::{ConfigGet, CosmicConfigEntry};
11-
use cosmic_settings_config::window_rules::ApplicationException;
1211
use cosmic_settings_config::{shortcuts, window_rules, Shortcuts};
12+
use cosmic_settings_config::{shortcuts::Gestures, window_rules::ApplicationException};
1313
use serde::{Deserialize, Serialize};
1414
use smithay::wayland::xdg_activation::XdgActivationState;
1515
pub use smithay::{
@@ -37,6 +37,7 @@ use tracing::{error, warn};
3737
mod input_config;
3838
pub mod key_bindings;
3939
pub use key_bindings::{Action, PrivateAction};
40+
pub mod gestures;
4041
mod types;
4142
pub use self::types::*;
4243
use cosmic::config::CosmicTk;
@@ -54,6 +55,8 @@ pub struct Config {
5455
pub settings_context: cosmic_config::Config,
5556
/// Key bindings from `com.system76.CosmicSettings.Shortcuts`
5657
pub shortcuts: Shortcuts,
58+
/// Gestures from `com.system76.CosmicSettings.Shortcuts`
59+
pub gestures: Gestures,
5760
// Tiling exceptions from `com.system76.CosmicSettings.WindowRules`
5861
pub tiling_exceptions: Vec<ApplicationException>,
5962
/// System actions from `com.system76.CosmicSettings.Shortcuts`
@@ -230,6 +233,12 @@ impl Config {
230233
// Add any missing default shortcuts recommended by the compositor.
231234
key_bindings::add_default_bindings(&mut shortcuts, workspace.workspace_layout);
232235

236+
// Source gestures
237+
let mut gestures = shortcuts::gestures(&settings_context);
238+
239+
// Add any missing default gestures recommended by the compositor.
240+
gestures::add_default_gestures(&mut gestures, workspace.workspace_layout);
241+
233242
// Listen for updates to the keybindings config.
234243
match cosmic_config::calloop::ConfigWatchSource::new(&settings_context) {
235244
Ok(source) => {
@@ -245,6 +254,14 @@ impl Config {
245254
state.common.config.shortcuts = shortcuts;
246255
}
247256

257+
"custom_gestures" | "default_gestures" => {
258+
let mut gestures = shortcuts::gestures(&config);
259+
let layout = get_config::<WorkspaceConfig>(&config, "workspaces")
260+
.workspace_layout;
261+
gestures::add_default_gestures(&mut gestures, layout);
262+
state.common.config.gestures = gestures;
263+
}
264+
248265
"system_actions" => {
249266
state.common.config.system_actions =
250267
shortcuts::system_actions(&config);
@@ -309,6 +326,7 @@ impl Config {
309326
cosmic_helper: config,
310327
settings_context,
311328
shortcuts,
329+
gestures,
312330
system_actions,
313331
tiling_exceptions,
314332
}

src/input/actions.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,25 @@ impl State {
9292
}
9393
}
9494

95-
pub fn handle_swipe_action(&mut self, action: gestures::SwipeAction, seat: &Seat<State>) {
96-
use gestures::SwipeAction;
97-
95+
pub fn handle_swipe_action(&mut self, action: shortcuts::Action, seat: &Seat<State>) {
9896
match action {
99-
SwipeAction::NextWorkspace => {
97+
shortcuts::Action::NextWorkspace => {
10098
let _ = to_next_workspace(
10199
&mut *self.common.shell.write().unwrap(),
102100
&seat,
103101
true,
104102
&mut self.common.workspace_state.update(),
105103
);
106104
}
107-
SwipeAction::PrevWorkspace => {
105+
shortcuts::Action::PreviousWorkspace => {
108106
let _ = to_previous_workspace(
109107
&mut *self.common.shell.write().unwrap(),
110108
&seat,
111109
true,
112110
&mut self.common.workspace_state.update(),
113111
);
114112
}
113+
_ => {} // TODO: Handle more actions
115114
}
116115
}
117116

src/input/gestures/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use cosmic_settings_config::shortcuts::action::Direction;
1+
use cosmic_settings_config::{shortcuts::action::Direction, Action};
22
use smithay::utils::{Logical, Point};
33
use std::{collections::VecDeque, time::Duration};
44
use tracing::trace;
@@ -12,17 +12,11 @@ pub struct SwipeEvent {
1212
timestamp: Duration,
1313
}
1414

15-
#[derive(Debug, Clone, Copy)]
16-
pub enum SwipeAction {
17-
NextWorkspace,
18-
PrevWorkspace,
19-
}
20-
2115
#[derive(Debug, Clone)]
2216
pub struct GestureState {
2317
pub fingers: u32,
2418
pub direction: Option<Direction>,
25-
pub action: Option<SwipeAction>,
19+
pub action: Option<Action>,
2620
pub delta: f64,
2721
// Delta tracking inspired by Niri (GPL-3.0) https://github.com/YaLTeR/niri/tree/v0.1.3
2822
pub history: VecDeque<SwipeEvent>,

src/input/mod.rs

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
},
1010
Action, Config, PrivateAction,
1111
},
12-
input::gestures::{GestureState, SwipeAction},
12+
input::gestures::GestureState,
1313
shell::{
1414
focus::{
1515
render_input_order,
@@ -34,8 +34,8 @@ use calloop::{
3434
RegistrationToken,
3535
};
3636
use cosmic_comp_config::workspace::WorkspaceLayout;
37-
use cosmic_settings_config::shortcuts;
3837
use cosmic_settings_config::shortcuts::action::{Direction, ResizeDirection};
38+
use cosmic_settings_config::shortcuts::{self, Gesture};
3939
use smithay::{
4040
backend::input::{
4141
AbsolutePositionEvent, Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent,
@@ -880,7 +880,7 @@ impl State {
880880
.cloned();
881881
if let Some(seat) = maybe_seat {
882882
self.common.idle_notifier_state.notify_activity(&seat);
883-
let mut activate_action: Option<SwipeAction> = None;
883+
let mut activate_action: Option<shortcuts::Action> = None;
884884
if let Some(ref mut gesture_state) = self.common.gesture_state {
885885
let first_update = gesture_state.update(
886886
event.delta(),
@@ -896,63 +896,30 @@ impl State {
896896
natural_scroll = natural;
897897
}
898898
}
899-
activate_action = match gesture_state.fingers {
900-
3 => None, // TODO: 3 finger gestures
901-
4 => {
902-
if self.common.config.cosmic_conf.workspaces.workspace_layout
903-
== WorkspaceLayout::Horizontal
904-
{
905-
match gesture_state.direction {
906-
Some(Direction::Left) => {
907-
if natural_scroll {
908-
Some(SwipeAction::NextWorkspace)
909-
} else {
910-
Some(SwipeAction::PrevWorkspace)
911-
}
912-
}
913-
Some(Direction::Right) => {
914-
if natural_scroll {
915-
Some(SwipeAction::PrevWorkspace)
916-
} else {
917-
Some(SwipeAction::NextWorkspace)
918-
}
919-
}
920-
_ => None, // TODO: Other actions
921-
}
922-
} else {
923-
match gesture_state.direction {
924-
Some(Direction::Up) => {
925-
if natural_scroll {
926-
Some(SwipeAction::NextWorkspace)
927-
} else {
928-
Some(SwipeAction::PrevWorkspace)
929-
}
930-
}
931-
Some(Direction::Down) => {
932-
if natural_scroll {
933-
Some(SwipeAction::PrevWorkspace)
934-
} else {
935-
Some(SwipeAction::NextWorkspace)
936-
}
937-
}
938-
_ => None, // TODO: Other actions
939-
}
940-
}
941-
}
942-
_ => None,
943-
};
944-
945-
gesture_state.action = activate_action;
899+
activate_action = self
900+
.common
901+
.config
902+
.gestures
903+
.0
904+
.iter()
905+
.find(|(gesture, action)| {
906+
gesture.fingers == gesture_state.fingers
907+
&& Some(gesture.direction) == gesture_state.direction
908+
})
909+
.map(|(_, action)| action)
910+
.cloned();
911+
gesture_state.action = activate_action.clone();
946912
}
947913

948914
match gesture_state.action {
949-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
915+
Some(shortcuts::Action::NextWorkspace)
916+
| Some(shortcuts::Action::PreviousWorkspace) => {
950917
self.common.shell.write().unwrap().update_workspace_delta(
951918
&seat.active_output(),
952919
gesture_state.delta,
953920
)
954921
}
955-
_ => {}
922+
_ => {} // TODO: Other actions
956923
}
957924
} else {
958925
let pointer = seat.get_pointer().unwrap();
@@ -983,7 +950,8 @@ impl State {
983950
self.common.idle_notifier_state.notify_activity(&seat);
984951
if let Some(ref gesture_state) = self.common.gesture_state {
985952
match gesture_state.action {
986-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
953+
Some(shortcuts::Action::NextWorkspace)
954+
| Some(shortcuts::Action::PreviousWorkspace) => {
987955
let velocity = gesture_state.velocity();
988956
let norm_velocity =
989957
if self.common.config.cosmic_conf.workspaces.workspace_layout

0 commit comments

Comments
 (0)