Skip to content

Commit

Permalink
feat: touchpad gesture configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanabx committed Apr 16, 2024
1 parent 5d5a510 commit 38898bf
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 39 deletions.
37 changes: 37 additions & 0 deletions cosmic-comp-config/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,43 @@ pub struct ScrollConfig {
pub scroll_button: Option<u32>,
pub scroll_factor: Option<f64>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct TouchpadGestureConfig {
pub three_finger: Option<GestureConfig>,
pub four_finger: Option<GestureConfig>,
pub five_finger: Option<GestureConfig>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum GestureConfig {
WorkspaceDependent(RelativeGestureConfig),
Directional(AbsoluteGestureConfig),
}
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
pub struct RelativeGestureConfig {
pub action_forward: Option<GestureCommand>,
pub action_backward: Option<GestureCommand>,
pub action_side_1: Option<GestureCommand>,
pub action_side_2: Option<GestureCommand>,
}
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
pub struct AbsoluteGestureConfig {
pub action_up: Option<GestureCommand>,
pub action_down: Option<GestureCommand>,
pub action_left: Option<GestureCommand>,
pub action_right: Option<GestureCommand>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum GestureCommand {
WorkspaceForward,
WorkspaceBackward,
WorkspaceOverviewEnable,
WorkspaceOverviewDisable,
WindowUp,
WindowDown,
WindowLeft,
WindowRight,
Custom(String),
}

#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum DeviceState {
Expand Down
2 changes: 2 additions & 0 deletions cosmic-comp-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct CosmicCompConfig {
pub workspaces: workspace::WorkspaceConfig,
pub input_default: input::InputConfig,
pub input_touchpad: input::InputConfig,
pub input_touchpad_gestures: input::TouchpadGestureConfig,
pub input_devices: HashMap<String, input::InputConfig>,
pub xkb_config: XkbConfig,
/// Autotiling enabled
Expand All @@ -31,6 +32,7 @@ impl Default for CosmicCompConfig {
workspaces: Default::default(),
input_default: Default::default(),
input_touchpad: Default::default(),
input_touchpad_gestures: Default::default(),
input_devices: Default::default(),
xkb_config: Default::default(),
autotile: Default::default(),
Expand Down
7 changes: 6 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern};
mod types;
pub use self::types::*;
use cosmic_comp_config::{
input::InputConfig,
input::{InputConfig, TouchpadGestureConfig},
workspace::{WorkspaceConfig, WorkspaceLayout},
CosmicCompConfig, TileBehavior, XkbConfig,
};
Expand Down Expand Up @@ -567,6 +567,11 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
state.common.config.cosmic_conf.input_touchpad = value;
update_input(state);
}
"input_touchpad_gestures" => {
let value = get_config::<TouchpadGestureConfig>(&config, "input_touchpad_gestures");
state.common.config.cosmic_conf.input_touchpad_gestures = value;
update_input(state);
}
"input_devices" => {
let value = get_config::<HashMap<String, InputConfig>>(&config, "input_devices");
state.common.config.cosmic_conf.input_devices = value;
Expand Down
9 changes: 2 additions & 7 deletions src/input/gestures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use cosmic_comp_config::input::GestureCommand;
use smithay::utils::{Logical, Point};
use std::{collections::VecDeque, time::Duration};
use tracing::trace;
Expand All @@ -13,17 +14,11 @@ pub struct SwipeEvent {
timestamp: Duration,
}

#[derive(Debug, Clone, Copy)]
pub enum SwipeAction {
NextWorkspace,
PrevWorkspace,
}

#[derive(Debug, Clone)]
pub struct GestureState {
pub fingers: u32,
pub direction: Option<Direction>,
pub action: Option<SwipeAction>,
pub action: Option<GestureCommand>,
pub delta: f64,
// Delta tracking inspired by Niri (GPL-3.0) https://github.com/YaLTeR/niri/tree/v0.1.3
pub history: VecDeque<SwipeEvent>,
Expand Down
109 changes: 78 additions & 31 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
config::{Action, Config, KeyModifiers, KeyPattern},
input::gestures::{GestureState, SwipeAction},
input::gestures::GestureState,
shell::{
focus::{
target::{KeyboardFocusTarget, PointerFocusTarget},
Expand All @@ -26,7 +26,11 @@ use crate::{
},
};
use calloop::{timer::Timer, RegistrationToken};
use cosmic_comp_config::{workspace::WorkspaceLayout, TileBehavior};
use cosmic_comp_config::{
input::{GestureCommand, GestureConfig},
workspace::WorkspaceLayout,
TileBehavior,
};
use cosmic_config::ConfigSet;
use smithay::{
backend::input::{
Expand Down Expand Up @@ -1091,47 +1095,89 @@ impl State {
.for_device(&event.device())
.cloned();
if let Some(seat) = maybe_seat {
let mut activate_action: Option<SwipeAction> = None;
let mut activate_action: Option<GestureCommand> = None;
if let Some(ref mut gesture_state) = self.common.gesture_state {
let first_update = gesture_state.update(
event.delta(),
Duration::from_millis(event.time_msec() as u64),
);
// Decide on action if first update
if first_update {
activate_action = match gesture_state.fingers {
3 => None, // TODO: 3 finger gestures
4 => {
if self.common.config.cosmic_conf.workspaces.workspace_layout
== WorkspaceLayout::Horizontal
{
match gesture_state.direction {
Some(Direction::Left) => {
Some(SwipeAction::NextWorkspace)
}
Some(Direction::Right) => {
Some(SwipeAction::PrevWorkspace)
}
_ => None, // TODO: Other actions
let target_config = match gesture_state.fingers {
3 => self
.common
.config
.cosmic_conf
.input_touchpad_gestures
.three_finger
.clone(),
4 => self
.common
.config
.cosmic_conf
.input_touchpad_gestures
.four_finger
.clone(),
5 => self
.common
.config
.cosmic_conf
.input_touchpad_gestures
.five_finger
.clone(),
_ => None,
};

activate_action = match target_config {
Some(GestureConfig::WorkspaceDependent(config)) => {
match (
self.common.config.cosmic_conf.workspaces.workspace_layout,
gesture_state.direction,
) {
(WorkspaceLayout::Vertical, Some(Direction::Down)) => {
config.action_forward.clone()
}
} else {
match gesture_state.direction {
Some(Direction::Up) => Some(SwipeAction::NextWorkspace),
Some(Direction::Down) => {
Some(SwipeAction::PrevWorkspace)
}
_ => None, // TODO: Other actions
(WorkspaceLayout::Vertical, Some(Direction::Up)) => {
config.action_backward.clone()
}
(WorkspaceLayout::Vertical, Some(Direction::Right)) => {
config.action_side_1.clone()
}
(WorkspaceLayout::Vertical, Some(Direction::Left)) => {
config.action_side_2.clone()
}
(WorkspaceLayout::Horizontal, Some(Direction::Down)) => {
config.action_side_1.clone()
}
(WorkspaceLayout::Horizontal, Some(Direction::Up)) => {
config.action_side_2.clone()
}
(WorkspaceLayout::Horizontal, Some(Direction::Right)) => {
config.action_forward.clone()
}
(WorkspaceLayout::Horizontal, Some(Direction::Left)) => {
config.action_backward.clone()
}
_ => None,
}
}
_ => None,
Some(GestureConfig::Directional(config)) => {
match gesture_state.direction {
Some(Direction::Up) => config.action_up.clone(),
Some(Direction::Down) => config.action_down.clone(),
Some(Direction::Right) => config.action_right.clone(),
Some(Direction::Left) => config.action_left.clone(),
None => None,
}
}
None => None,
};

gesture_state.action = activate_action;
gesture_state.action = activate_action.clone();
}

match gesture_state.action {
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
Some(GestureCommand::WorkspaceForward)
| Some(GestureCommand::WorkspaceBackward) => {
self.common.shell.write().unwrap().update_workspace_delta(
&seat.active_output(),
gesture_state.delta,
Expand All @@ -1150,15 +1196,15 @@ impl State {
);
}
match activate_action {
Some(SwipeAction::NextWorkspace) => {
Some(GestureCommand::WorkspaceForward) => {
let _ = to_next_workspace(
&mut *self.common.shell.write().unwrap(),
&seat,
true,
&mut self.common.workspace_state.update(),
);
}
Some(SwipeAction::PrevWorkspace) => {
Some(GestureCommand::WorkspaceBackward) => {
let _ = to_previous_workspace(
&mut *self.common.shell.write().unwrap(),
&seat,
Expand All @@ -1182,7 +1228,8 @@ impl State {
if let Some(seat) = maybe_seat {
if let Some(ref gesture_state) = self.common.gesture_state {
match gesture_state.action {
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
Some(GestureCommand::WorkspaceForward)
| Some(GestureCommand::WorkspaceBackward) => {
let velocity = gesture_state.velocity();
let norm_velocity =
if self.common.config.cosmic_conf.workspaces.workspace_layout
Expand Down

0 comments on commit 38898bf

Please sign in to comment.