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 1, 2024
1 parent 3da08ed commit d42b6df
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 58 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 @@ -30,7 +30,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 @@ -553,6 +553,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
117 changes: 81 additions & 36 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{
backend::render::cursor::CursorState,
config::{xkb_config_to_wl, Action, Config, KeyModifiers, KeyPattern},
input::gestures::{GestureState, SwipeAction},
input::gestures::GestureState,
shell::{
focus::{
target::{KeyboardFocusTarget, PointerFocusTarget},
Expand All @@ -25,7 +25,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 @@ -1121,52 +1125,92 @@ impl State {
}
InputEvent::GestureSwipeUpdate { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
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) => {
self.common.shell.update_workspace_delta(
&seat.active_output(),
gesture_state.delta,
)
}
Some(GestureCommand::WorkspaceForward)
| Some(GestureCommand::WorkspaceBackward) => self
.common
.shell
.update_workspace_delta(&seat.active_output(), gesture_state.delta),
_ => {}
}
} else {
Expand All @@ -1180,10 +1224,10 @@ impl State {
);
}
match activate_action {
Some(SwipeAction::NextWorkspace) => {
Some(GestureCommand::WorkspaceForward) => {
let _ = self.to_next_workspace(&seat, true);
}
Some(SwipeAction::PrevWorkspace) => {
Some(GestureCommand::WorkspaceBackward) => {
let _ = self.to_previous_workspace(&seat, true);
}
_ => {}
Expand All @@ -1194,7 +1238,8 @@ impl State {
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
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
28 changes: 14 additions & 14 deletions src/shell/focus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,21 +266,21 @@ impl Common {
.get::<PopupGrabData>()
.and_then(|x| x.take())
{
if !popup_grab.has_ended() {
if let Some(new) = popup_grab.current_grab() {
trace!("restore focus to previous popup grab");
if let Some(keyboard) = seat.get_keyboard() {
keyboard.set_focus(
state,
Some(new.clone()),
SERIAL_COUNTER.next_serial(),
);
}
ActiveFocus::set(&seat, Some(new));
seat.user_data()
if !popup_grab.has_ended() {
if let Some(new) = popup_grab.current_grab() {
trace!("restore focus to previous popup grab");
if let Some(keyboard) = seat.get_keyboard() {
keyboard.set_focus(
state,
Some(new.clone()),
SERIAL_COUNTER.next_serial(),
);
}
ActiveFocus::set(&seat, Some(new));
seat.user_data()
.get_or_insert::<PopupGrabData, _>(PopupGrabData::default)
.set(Some(popup_grab));
continue;
.set(Some(popup_grab));
continue;
}
}
}
Expand Down

0 comments on commit d42b6df

Please sign in to comment.