Skip to content

Commit d42b6df

Browse files
committed
feat: touchpad gesture configuration
1 parent 3da08ed commit d42b6df

File tree

6 files changed

+142
-58
lines changed

6 files changed

+142
-58
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
@@ -30,7 +30,7 @@ pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern};
3030
mod types;
3131
pub use self::types::*;
3232
use cosmic_comp_config::{
33-
input::InputConfig,
33+
input::{InputConfig, TouchpadGestureConfig},
3434
workspace::{WorkspaceConfig, WorkspaceLayout},
3535
CosmicCompConfig, TileBehavior, XkbConfig,
3636
};
@@ -553,6 +553,11 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
553553
state.common.config.cosmic_conf.input_touchpad = value;
554554
update_input(state);
555555
}
556+
"input_touchpad_gestures" => {
557+
let value = get_config::<TouchpadGestureConfig>(&config, "input_touchpad_gestures");
558+
state.common.config.cosmic_conf.input_touchpad_gestures = value;
559+
update_input(state);
560+
}
556561
"input_devices" => {
557562
let value = get_config::<HashMap<String, InputConfig>>(&config, "input_devices");
558563
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: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{
44
backend::render::cursor::CursorState,
55
config::{xkb_config_to_wl, Action, Config, KeyModifiers, KeyPattern},
6-
input::gestures::{GestureState, SwipeAction},
6+
input::gestures::GestureState,
77
shell::{
88
focus::{
99
target::{KeyboardFocusTarget, PointerFocusTarget},
@@ -25,7 +25,11 @@ use crate::{
2525
},
2626
};
2727
use calloop::{timer::Timer, RegistrationToken};
28-
use cosmic_comp_config::{workspace::WorkspaceLayout, TileBehavior};
28+
use cosmic_comp_config::{
29+
input::{GestureCommand, GestureConfig},
30+
workspace::WorkspaceLayout,
31+
TileBehavior,
32+
};
2933
use cosmic_config::ConfigSet;
3034
use smithay::{
3135
backend::input::{
@@ -1121,52 +1125,92 @@ impl State {
11211125
}
11221126
InputEvent::GestureSwipeUpdate { event, .. } => {
11231127
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
1124-
let mut activate_action: Option<SwipeAction> = None;
1128+
let mut activate_action: Option<GestureCommand> = None;
11251129
if let Some(ref mut gesture_state) = self.common.gesture_state {
11261130
let first_update = gesture_state.update(
11271131
event.delta(),
11281132
Duration::from_millis(event.time_msec() as u64),
11291133
);
11301134
// Decide on action if first update
11311135
if first_update {
1132-
activate_action = match gesture_state.fingers {
1133-
3 => None, // TODO: 3 finger gestures
1134-
4 => {
1135-
if self.common.config.cosmic_conf.workspaces.workspace_layout
1136-
== WorkspaceLayout::Horizontal
1137-
{
1138-
match gesture_state.direction {
1139-
Some(Direction::Left) => {
1140-
Some(SwipeAction::NextWorkspace)
1141-
}
1142-
Some(Direction::Right) => {
1143-
Some(SwipeAction::PrevWorkspace)
1144-
}
1145-
_ => None, // TODO: Other actions
1136+
let target_config = match gesture_state.fingers {
1137+
3 => self
1138+
.common
1139+
.config
1140+
.cosmic_conf
1141+
.input_touchpad_gestures
1142+
.three_finger
1143+
.clone(),
1144+
4 => self
1145+
.common
1146+
.config
1147+
.cosmic_conf
1148+
.input_touchpad_gestures
1149+
.four_finger
1150+
.clone(),
1151+
5 => self
1152+
.common
1153+
.config
1154+
.cosmic_conf
1155+
.input_touchpad_gestures
1156+
.five_finger
1157+
.clone(),
1158+
_ => None,
1159+
};
1160+
1161+
activate_action = match target_config {
1162+
Some(GestureConfig::WorkspaceDependent(config)) => {
1163+
match (
1164+
self.common.config.cosmic_conf.workspaces.workspace_layout,
1165+
gesture_state.direction,
1166+
) {
1167+
(WorkspaceLayout::Vertical, Some(Direction::Down)) => {
1168+
config.action_forward.clone()
11461169
}
1147-
} else {
1148-
match gesture_state.direction {
1149-
Some(Direction::Up) => Some(SwipeAction::NextWorkspace),
1150-
Some(Direction::Down) => {
1151-
Some(SwipeAction::PrevWorkspace)
1152-
}
1153-
_ => None, // TODO: Other actions
1170+
(WorkspaceLayout::Vertical, Some(Direction::Up)) => {
1171+
config.action_backward.clone()
1172+
}
1173+
(WorkspaceLayout::Vertical, Some(Direction::Right)) => {
1174+
config.action_side_1.clone()
1175+
}
1176+
(WorkspaceLayout::Vertical, Some(Direction::Left)) => {
1177+
config.action_side_2.clone()
1178+
}
1179+
(WorkspaceLayout::Horizontal, Some(Direction::Down)) => {
1180+
config.action_side_1.clone()
1181+
}
1182+
(WorkspaceLayout::Horizontal, Some(Direction::Up)) => {
1183+
config.action_side_2.clone()
1184+
}
1185+
(WorkspaceLayout::Horizontal, Some(Direction::Right)) => {
1186+
config.action_forward.clone()
1187+
}
1188+
(WorkspaceLayout::Horizontal, Some(Direction::Left)) => {
1189+
config.action_backward.clone()
11541190
}
1191+
_ => None,
11551192
}
11561193
}
1157-
_ => None,
1194+
Some(GestureConfig::Directional(config)) => {
1195+
match gesture_state.direction {
1196+
Some(Direction::Up) => config.action_up.clone(),
1197+
Some(Direction::Down) => config.action_down.clone(),
1198+
Some(Direction::Right) => config.action_right.clone(),
1199+
Some(Direction::Left) => config.action_left.clone(),
1200+
None => None,
1201+
}
1202+
}
1203+
None => None,
11581204
};
1159-
1160-
gesture_state.action = activate_action;
1205+
gesture_state.action = activate_action.clone();
11611206
}
11621207

11631208
match gesture_state.action {
1164-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
1165-
self.common.shell.update_workspace_delta(
1166-
&seat.active_output(),
1167-
gesture_state.delta,
1168-
)
1169-
}
1209+
Some(GestureCommand::WorkspaceForward)
1210+
| Some(GestureCommand::WorkspaceBackward) => self
1211+
.common
1212+
.shell
1213+
.update_workspace_delta(&seat.active_output(), gesture_state.delta),
11701214
_ => {}
11711215
}
11721216
} else {
@@ -1180,10 +1224,10 @@ impl State {
11801224
);
11811225
}
11821226
match activate_action {
1183-
Some(SwipeAction::NextWorkspace) => {
1227+
Some(GestureCommand::WorkspaceForward) => {
11841228
let _ = self.to_next_workspace(&seat, true);
11851229
}
1186-
Some(SwipeAction::PrevWorkspace) => {
1230+
Some(GestureCommand::WorkspaceBackward) => {
11871231
let _ = self.to_previous_workspace(&seat, true);
11881232
}
11891233
_ => {}
@@ -1194,7 +1238,8 @@ impl State {
11941238
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
11951239
if let Some(ref gesture_state) = self.common.gesture_state {
11961240
match gesture_state.action {
1197-
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
1241+
Some(GestureCommand::WorkspaceForward)
1242+
| Some(GestureCommand::WorkspaceBackward) => {
11981243
let velocity = gesture_state.velocity();
11991244
let norm_velocity =
12001245
if self.common.config.cosmic_conf.workspaces.workspace_layout

src/shell/focus/mod.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -266,21 +266,21 @@ impl Common {
266266
.get::<PopupGrabData>()
267267
.and_then(|x| x.take())
268268
{
269-
if !popup_grab.has_ended() {
270-
if let Some(new) = popup_grab.current_grab() {
271-
trace!("restore focus to previous popup grab");
272-
if let Some(keyboard) = seat.get_keyboard() {
273-
keyboard.set_focus(
274-
state,
275-
Some(new.clone()),
276-
SERIAL_COUNTER.next_serial(),
277-
);
278-
}
279-
ActiveFocus::set(&seat, Some(new));
280-
seat.user_data()
269+
if !popup_grab.has_ended() {
270+
if let Some(new) = popup_grab.current_grab() {
271+
trace!("restore focus to previous popup grab");
272+
if let Some(keyboard) = seat.get_keyboard() {
273+
keyboard.set_focus(
274+
state,
275+
Some(new.clone()),
276+
SERIAL_COUNTER.next_serial(),
277+
);
278+
}
279+
ActiveFocus::set(&seat, Some(new));
280+
seat.user_data()
281281
.get_or_insert::<PopupGrabData, _>(PopupGrabData::default)
282-
.set(Some(popup_grab));
283-
continue;
282+
.set(Some(popup_grab));
283+
continue;
284284
}
285285
}
286286
}

0 commit comments

Comments
 (0)