Skip to content

Commit

Permalink
gestures: Implement configurable gestures using new cosmic-settings-d…
Browse files Browse the repository at this point in the history
…aemon 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]>
  • Loading branch information
ryanabx committed Dec 23, 2024
1 parent 7ac204e commit e48e352
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 71 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ calloop = {version = "0.14.1", features = ["executor"]}
cosmic-comp-config = {path = "cosmic-comp-config"}
cosmic-config = {git = "https://github.com/pop-os/libcosmic/", features = ["calloop", "macro"]}
cosmic-protocols = {git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"]}
cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" }
# cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" }
cosmic-settings-config = { git = "https://github.com/ryanabx-contrib/cosmic-settings-daemon", branch = "gestures" }
edid-rs = {version = "0.1"}
egui = {version = "0.29.0", optional = true}
egui_plot = {version = "0.29.0", optional = true}
Expand Down
24 changes: 24 additions & 0 deletions src/config/gestures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use cosmic_comp_config::workspace::WorkspaceLayout;
use cosmic_settings_config::shortcuts::{self, action::Direction, Gestures};

pub fn add_default_gestures(gestures: &mut Gestures, workspace_layout: WorkspaceLayout) {
// TODO: Do we take into account natural scroll?
let (workspace_forward, workspace_backward) = match workspace_layout {
WorkspaceLayout::Vertical => (Direction::Up, Direction::Down),
WorkspaceLayout::Horizontal => (Direction::Left, Direction::Right),
};

gestures.insert_default_gesture(
4 as u32,
workspace_forward.clone(),
shortcuts::Action::NextWorkspace,
);

gestures.insert_default_gesture(
4 as u32,
workspace_backward.clone(),
shortcuts::Action::PreviousWorkspace,
);

// TODO: More default gestures?
}
20 changes: 19 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
},
};
use cosmic_config::{ConfigGet, CosmicConfigEntry};
use cosmic_settings_config::window_rules::ApplicationException;
use cosmic_settings_config::{shortcuts, window_rules, Shortcuts};
use cosmic_settings_config::{shortcuts::Gestures, window_rules::ApplicationException};
use serde::{Deserialize, Serialize};
use smithay::wayland::xdg_activation::XdgActivationState;
pub use smithay::{
Expand Down Expand Up @@ -37,6 +37,7 @@ use tracing::{error, warn};
mod input_config;
pub mod key_bindings;
pub use key_bindings::{Action, PrivateAction};
pub mod gestures;
mod types;
pub use self::types::*;
use cosmic::config::CosmicTk;
Expand All @@ -54,6 +55,8 @@ pub struct Config {
pub settings_context: cosmic_config::Config,
/// Key bindings from `com.system76.CosmicSettings.Shortcuts`
pub shortcuts: Shortcuts,
/// Gestures from `com.system76.CosmicSettings.Shortcuts`
pub gestures: Gestures,
// Tiling exceptions from `com.system76.CosmicSettings.WindowRules`
pub tiling_exceptions: Vec<ApplicationException>,
/// System actions from `com.system76.CosmicSettings.Shortcuts`
Expand Down Expand Up @@ -230,6 +233,12 @@ impl Config {
// Add any missing default shortcuts recommended by the compositor.
key_bindings::add_default_bindings(&mut shortcuts, workspace.workspace_layout);

// Source gestures
let mut gestures = shortcuts::gestures(&settings_context);

// Add any missing default gestures recommended by the compositor.
gestures::add_default_gestures(&mut gestures, workspace.workspace_layout);

// Listen for updates to the keybindings config.
match cosmic_config::calloop::ConfigWatchSource::new(&settings_context) {
Ok(source) => {
Expand All @@ -245,6 +254,14 @@ impl Config {
state.common.config.shortcuts = shortcuts;
}

"custom_gestures" | "default_gestures" => {
let mut gestures = shortcuts::gestures(&config);
let layout = get_config::<WorkspaceConfig>(&config, "workspaces")
.workspace_layout;
gestures::add_default_gestures(&mut gestures, layout);
state.common.config.gestures = gestures;
}

"system_actions" => {
state.common.config.system_actions =
shortcuts::system_actions(&config);
Expand Down Expand Up @@ -309,6 +326,7 @@ impl Config {
cosmic_helper: config,
settings_context,
shortcuts,
gestures,
system_actions,
tiling_exceptions,
}
Expand Down
9 changes: 4 additions & 5 deletions src/input/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,25 @@ impl State {
}
}

pub fn handle_swipe_action(&mut self, action: gestures::SwipeAction, seat: &Seat<State>) {
use gestures::SwipeAction;

pub fn handle_swipe_action(&mut self, action: shortcuts::Action, seat: &Seat<State>) {
match action {
SwipeAction::NextWorkspace => {
shortcuts::Action::NextWorkspace => {
let _ = to_next_workspace(
&mut *self.common.shell.write().unwrap(),
&seat,
true,
&mut self.common.workspace_state.update(),
);
}
SwipeAction::PrevWorkspace => {
shortcuts::Action::PreviousWorkspace => {
let _ = to_previous_workspace(
&mut *self.common.shell.write().unwrap(),
&seat,
true,
&mut self.common.workspace_state.update(),
);
}
_ => {} // TODO: Handle more actions
}
}

Expand Down
10 changes: 2 additions & 8 deletions src/input/gestures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmic_settings_config::shortcuts::action::Direction;
use cosmic_settings_config::{shortcuts::action::Direction, Action};
use smithay::utils::{Logical, Point};
use std::{collections::VecDeque, time::Duration};
use tracing::trace;
Expand All @@ -12,17 +12,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<Action>,
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
74 changes: 21 additions & 53 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
},
Action, Config, PrivateAction,
},
input::gestures::{GestureState, SwipeAction},
input::gestures::GestureState,
shell::{
focus::{
render_input_order,
Expand All @@ -34,8 +34,8 @@ use calloop::{
RegistrationToken,
};
use cosmic_comp_config::workspace::WorkspaceLayout;
use cosmic_settings_config::shortcuts;
use cosmic_settings_config::shortcuts::action::{Direction, ResizeDirection};
use cosmic_settings_config::shortcuts::{self, Gesture};
use smithay::{
backend::input::{
AbsolutePositionEvent, Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent,
Expand Down Expand Up @@ -880,7 +880,7 @@ impl State {
.cloned();
if let Some(seat) = maybe_seat {
self.common.idle_notifier_state.notify_activity(&seat);
let mut activate_action: Option<SwipeAction> = None;
let mut activate_action: Option<shortcuts::Action> = None;
if let Some(ref mut gesture_state) = self.common.gesture_state {
let first_update = gesture_state.update(
event.delta(),
Expand All @@ -896,63 +896,30 @@ impl State {
natural_scroll = natural;
}
}
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) => {
if natural_scroll {
Some(SwipeAction::NextWorkspace)
} else {
Some(SwipeAction::PrevWorkspace)
}
}
Some(Direction::Right) => {
if natural_scroll {
Some(SwipeAction::PrevWorkspace)
} else {
Some(SwipeAction::NextWorkspace)
}
}
_ => None, // TODO: Other actions
}
} else {
match gesture_state.direction {
Some(Direction::Up) => {
if natural_scroll {
Some(SwipeAction::NextWorkspace)
} else {
Some(SwipeAction::PrevWorkspace)
}
}
Some(Direction::Down) => {
if natural_scroll {
Some(SwipeAction::PrevWorkspace)
} else {
Some(SwipeAction::NextWorkspace)
}
}
_ => None, // TODO: Other actions
}
}
}
_ => None,
};

gesture_state.action = activate_action;
activate_action = self
.common
.config
.gestures
.0
.iter()
.find(|(gesture, action)| {
gesture.fingers == gesture_state.fingers
&& Some(gesture.direction) == gesture_state.direction
})
.map(|(_, action)| action)
.cloned();
gesture_state.action = activate_action.clone();
}

match gesture_state.action {
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
Some(shortcuts::Action::NextWorkspace)
| Some(shortcuts::Action::PreviousWorkspace) => {
self.common.shell.write().unwrap().update_workspace_delta(
&seat.active_output(),
gesture_state.delta,
)
}
_ => {}
_ => {} // TODO: Other actions
}
} else {
let pointer = seat.get_pointer().unwrap();
Expand Down Expand Up @@ -983,7 +950,8 @@ impl State {
self.common.idle_notifier_state.notify_activity(&seat);
if let Some(ref gesture_state) = self.common.gesture_state {
match gesture_state.action {
Some(SwipeAction::NextWorkspace) | Some(SwipeAction::PrevWorkspace) => {
Some(shortcuts::Action::NextWorkspace)
| Some(shortcuts::Action::PreviousWorkspace) => {
let velocity = gesture_state.velocity();
let norm_velocity =
if self.common.config.cosmic_conf.workspaces.workspace_layout
Expand Down

0 comments on commit e48e352

Please sign in to comment.