Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Gesture configuration backend #396

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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),
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need another enum for this? We already have the Action-enum that is used for key-bindings. Can't we just use that and special case some actions like NextWorkspace/PreviousWorkspace when using gestures? (To animate those properly.)

That would make configuration much more flexible and allow binding more things to gestures.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll look into doing that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking into it, I'll hold onto this PR until #400 is finished, because it moves the Actions enum into cosmic-comp-config, where I need it


#[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