Skip to content

Commit 9319fe3

Browse files
committed
feat: touchpad gesture configuration
1 parent 8cee91c commit 9319fe3

File tree

5 files changed

+125
-39
lines changed

5 files changed

+125
-39
lines changed

cosmic-comp-config/src/input.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,43 @@ pub struct ScrollConfig {
4646
pub scroll_button: Option<u32>,
4747
pub scroll_factor: Option<f64>,
4848
}
49+
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
50+
pub struct TouchpadGestureConfig {
51+
pub three_finger: Option<GestureConfig>,
52+
pub four_finger: Option<GestureConfig>,
53+
pub five_finger: Option<GestureConfig>,
54+
}
55+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
56+
pub enum GestureConfig {
57+
WorkspaceDependent(RelativeGestureConfig),
58+
Directional(AbsoluteGestureConfig),
59+
}
60+
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
61+
pub struct RelativeGestureConfig {
62+
pub action_forward: Option<GestureCommand>,
63+
pub action_backward: Option<GestureCommand>,
64+
pub action_side_1: Option<GestureCommand>,
65+
pub action_side_2: Option<GestureCommand>,
66+
}
67+
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
68+
pub struct AbsoluteGestureConfig {
69+
pub action_up: Option<GestureCommand>,
70+
pub action_down: Option<GestureCommand>,
71+
pub action_left: Option<GestureCommand>,
72+
pub action_right: Option<GestureCommand>,
73+
}
74+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
75+
pub enum GestureCommand {
76+
WorkspaceForward,
77+
WorkspaceBackward,
78+
WorkspaceOverviewEnable,
79+
WorkspaceOverviewDisable,
80+
WindowUp,
81+
WindowDown,
82+
WindowLeft,
83+
WindowRight,
84+
Custom(String),
85+
}
4986

5087
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
5188
pub enum DeviceState {

cosmic-comp-config/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub struct CosmicCompConfig {
1313
pub workspaces: workspace::WorkspaceConfig,
1414
pub input_default: input::InputConfig,
1515
pub input_touchpad: input::InputConfig,
16+
pub input_touchpad_gestures: input::TouchpadGestureConfig,
1617
pub input_devices: HashMap<String, input::InputConfig>,
1718
pub xkb_config: XkbConfig,
1819
/// Autotiling enabled
@@ -31,6 +32,7 @@ impl Default for CosmicCompConfig {
3132
workspaces: Default::default(),
3233
input_default: Default::default(),
3334
input_touchpad: Default::default(),
35+
input_touchpad_gestures: Default::default(),
3436
input_devices: Default::default(),
3537
xkb_config: Default::default(),
3638
autotile: Default::default(),

src/config/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern};
3232
mod types;
3333
pub use self::types::*;
3434
use cosmic_comp_config::{
35-
input::InputConfig,
35+
input::{InputConfig, TouchpadGestureConfig},
3636
workspace::{WorkspaceConfig, WorkspaceLayout},
3737
CosmicCompConfig, TileBehavior, XkbConfig,
3838
};
@@ -567,6 +567,11 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
567567
state.common.config.cosmic_conf.input_touchpad = value;
568568
update_input(state);
569569
}
570+
"input_touchpad_gestures" => {
571+
let value = get_config::<TouchpadGestureConfig>(&config, "input_touchpad_gestures");
572+
state.common.config.cosmic_conf.input_touchpad_gestures = value;
573+
update_input(state);
574+
}
570575
"input_devices" => {
571576
let value = get_config::<HashMap<String, InputConfig>>(&config, "input_devices");
572577
state.common.config.cosmic_conf.input_devices = value;

src/input/gestures/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use cosmic_comp_config::input::GestureCommand;
12
use smithay::utils::{Logical, Point};
23
use std::{collections::VecDeque, time::Duration};
34
use tracing::trace;
@@ -13,17 +14,11 @@ pub struct SwipeEvent {
1314
timestamp: Duration,
1415
}
1516

16-
#[derive(Debug, Clone, Copy)]
17-
pub enum SwipeAction {
18-
NextWorkspace,
19-
PrevWorkspace,
20-
}
21-
2217
#[derive(Debug, Clone)]
2318
pub struct GestureState {
2419
pub fingers: u32,
2520
pub direction: Option<Direction>,
26-
pub action: Option<SwipeAction>,
21+
pub action: Option<GestureCommand>,
2722
pub delta: f64,
2823
// Delta tracking inspired by Niri (GPL-3.0) https://github.com/YaLTeR/niri/tree/v0.1.3
2924
pub history: VecDeque<SwipeEvent>,

src/input/mod.rs

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::{
44
config::{Action, Config, KeyModifiers, KeyPattern},
5-
input::gestures::{GestureState, SwipeAction},
5+
input::gestures::GestureState,
66
shell::{
77
focus::{
88
target::{KeyboardFocusTarget, PointerFocusTarget},
@@ -26,7 +26,11 @@ use crate::{
2626
},
2727
};
2828
use calloop::{timer::Timer, RegistrationToken};
29-
use cosmic_comp_config::{workspace::WorkspaceLayout, TileBehavior};
29+
use cosmic_comp_config::{
30+
input::{GestureCommand, GestureConfig},
31+
workspace::WorkspaceLayout,
32+
TileBehavior,
33+
};
3034
use cosmic_config::ConfigSet;
3135
use smithay::{
3236
backend::input::{
@@ -1091,47 +1095,89 @@ impl State {
10911095
.for_device(&event.device())
10921096
.cloned();
10931097
if let Some(seat) = maybe_seat {
1094-
let mut activate_action: Option<SwipeAction> = None;
1098+
let mut activate_action: Option<GestureCommand> = None;
10951099
if let Some(ref mut gesture_state) = self.common.gesture_state {
10961100
let first_update = gesture_state.update(
10971101
event.delta(),
10981102
Duration::from_millis(event.time_msec() as u64),
10991103
);
11001104
// Decide on action if first update
11011105
if first_update {
1102-
activate_action = match gesture_state.fingers {
1103-
3 => None, // TODO: 3 finger gestures
1104-
4 => {
1105-
if self.common.config.cosmic_conf.workspaces.workspace_layout
1106-
== WorkspaceLayout::Horizontal
1107-
{
1108-
match gesture_state.direction {
1109-
Some(Direction::Left) => {
1110-
Some(SwipeAction::NextWorkspace)
1111-
}
1112-
Some(Direction::Right) => {
1113-
Some(SwipeAction::PrevWorkspace)
1114-
}
1115-
_ => None, // TODO: Other actions
1106+
let target_config = match gesture_state.fingers {
1107+
3 => self
1108+
.common
1109+
.config
1110+
.cosmic_conf
1111+
.input_touchpad_gestures
1112+
.three_finger
1113+
.clone(),
1114+
4 => self
1115+
.common
1116+
.config
1117+
.cosmic_conf
1118+
.input_touchpad_gestures
1119+
.four_finger
1120+
.clone(),
1121+
5 => self
1122+
.common
1123+
.config
1124+
.cosmic_conf
1125+
.input_touchpad_gestures
1126+
.five_finger
1127+
.clone(),
1128+
_ => None,
1129+
};
1130+
1131+
activate_action = match target_config {
1132+
Some(GestureConfig::WorkspaceDependent(config)) => {
1133+
match (
1134+
self.common.config.cosmic_conf.workspaces.workspace_layout,
1135+
gesture_state.direction,
1136+
) {
1137+
(WorkspaceLayout::Vertical, Some(Direction::Down)) => {
1138+
config.action_forward.clone()
11161139
}
1117-
} else {
1118-
match gesture_state.direction {
1119-
Some(Direction::Up) => Some(SwipeAction::NextWorkspace),
1120-
Some(Direction::Down) => {
1121-
Some(SwipeAction::PrevWorkspace)
1122-
}
1123-
_ => None, // TODO: Other actions
1140+
(WorkspaceLayout::Vertical, Some(Direction::Up)) => {
1141+
config.action_backward.clone()
11241142
}
1143+
(WorkspaceLayout::Vertical, Some(Direction::Right)) => {
1144+
config.action_side_1.clone()
1145+
}
1146+
(WorkspaceLayout::Vertical, Some(Direction::Left)) => {
1147+
config.action_side_2.clone()
1148+
}
1149+
(WorkspaceLayout::Horizontal, Some(Direction::Down)) => {
1150+
config.action_side_1.clone()
1151+
}
1152+
(WorkspaceLayout::Horizontal, Some(Direction::Up)) => {
1153+
config.action_side_2.clone()
1154+
}
1155+
(WorkspaceLayout::Horizontal, Some(Direction::Right)) => {
1156+
config.action_forward.clone()
1157+
}
1158+
(WorkspaceLayout::Horizontal, Some(Direction::Left)) => {
1159+
config.action_backward.clone()
1160+
}
1161+
_ => None,
11251162
}
11261163
}
1127-
_ => None,
1164+
Some(GestureConfig::Directional(config)) => {
1165+
match gesture_state.direction {
1166+
Some(Direction::Up) => config.action_up.clone(),
1167+
Some(Direction::Down) => config.action_down.clone(),
1168+
Some(Direction::Right) => config.action_right.clone(),
1169+
Some(Direction::Left) => config.action_left.clone(),
1170+
None => None,
1171+
}
1172+
}
1173+
None => None,
11281174
};
1129-
1130-
gesture_state.action = activate_action;
1175+
gesture_state.action = activate_action.clone();
11311176
}
11321177

11331178
match gesture_state.action {
1134-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
1179+
Some(GestureCommand::WorkspaceForward)
1180+
| Some(GestureCommand::WorkspaceBackward) => {
11351181
self.common.shell.write().unwrap().update_workspace_delta(
11361182
&seat.active_output(),
11371183
gesture_state.delta,
@@ -1150,15 +1196,15 @@ impl State {
11501196
);
11511197
}
11521198
match activate_action {
1153-
Some(SwipeAction::NextWorkspace) => {
1199+
Some(GestureCommand::WorkspaceForward) => {
11541200
let _ = to_next_workspace(
11551201
&mut *self.common.shell.write().unwrap(),
11561202
&seat,
11571203
true,
11581204
&mut self.common.workspace_state.update(),
11591205
);
11601206
}
1161-
Some(SwipeAction::PrevWorkspace) => {
1207+
Some(GestureCommand::WorkspaceBackward) => {
11621208
let _ = to_previous_workspace(
11631209
&mut *self.common.shell.write().unwrap(),
11641210
&seat,
@@ -1182,7 +1228,8 @@ impl State {
11821228
if let Some(seat) = maybe_seat {
11831229
if let Some(ref gesture_state) = self.common.gesture_state {
11841230
match gesture_state.action {
1185-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
1231+
Some(GestureCommand::WorkspaceForward)
1232+
| Some(GestureCommand::WorkspaceBackward) => {
11861233
let velocity = gesture_state.velocity();
11871234
let norm_velocity =
11881235
if self.common.config.cosmic_conf.workspaces.workspace_layout

0 commit comments

Comments
 (0)