diff --git a/src/config/input_config.rs b/src/config/input_config.rs new file mode 100644 index 00000000..86a01140 --- /dev/null +++ b/src/config/input_config.rs @@ -0,0 +1,315 @@ +use serde::{Deserialize, Serialize}; +pub use smithay::{ + backend::input::KeyState, + input::keyboard::{keysyms as KeySyms, Keysym, ModifiersState}, + output::{Mode, Output}, + reexports::{ + calloop::LoopHandle, + input::{ + AccelProfile, ClickMethod, Device as InputDevice, ScrollMethod, SendEventsMode, + TapButtonMap, + }, + }, + utils::{Logical, Physical, Point, Size, Transform}, +}; +use tracing::warn; + +use super::types::*; + +#[derive(Debug, Deserialize, Serialize)] +pub struct InputConfig { + state: DeviceState, + #[serde(skip_serializing_if = "Option::is_none", default)] + acceleration: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + calibration: Option<[f32; 6]>, + #[serde(with = "ClickMethodDef")] + #[serde(skip_serializing_if = "Option::is_none", default)] + click_method: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + disable_while_typing: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + left_handed: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + middle_button_emulation: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + rotation_angle: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + scroll_config: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + tap_config: Option, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct AccelConfig { + #[serde(with = "AccelProfileDef")] + profile: Option, + speed: f64, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct ScrollConfig { + #[serde(with = "ScrollMethodDef")] + method: Option, + natural_scroll: Option, + scroll_button: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum DeviceState { + Enabled, + Disabled, + DisabledOnExternalMouse, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct TapConfig { + enabled: bool, + #[serde(with = "TapButtonMapDef")] + button_map: Option, + drag: bool, + drag_lock: bool, +} + +impl InputConfig { + pub fn for_device(device: &InputDevice) -> Self { + InputConfig { + state: match device.config_send_events_mode() { + x if x.contains(SendEventsMode::ENABLED) => DeviceState::Enabled, + x if x.contains(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE) => { + DeviceState::DisabledOnExternalMouse + } + x if x.contains(SendEventsMode::DISABLED) => DeviceState::Disabled, + _ => DeviceState::Disabled, + }, + acceleration: if device.config_accel_is_available() { + Some(AccelConfig { + profile: device.config_accel_profile(), + speed: device.config_accel_speed(), + }) + } else { + None + }, + calibration: device.config_calibration_matrix(), + click_method: device.config_click_method(), + disable_while_typing: if device.config_dwt_is_available() { + Some(device.config_dwt_enabled()) + } else { + None + }, + left_handed: if device.config_left_handed_is_available() { + Some(device.config_left_handed()) + } else { + None + }, + middle_button_emulation: if device.config_middle_emulation_is_available() { + Some(device.config_middle_emulation_enabled()) + } else { + None + }, + rotation_angle: if device.config_rotation_is_available() { + Some(device.config_rotation_angle()) + } else { + None + }, + scroll_config: if device + .config_scroll_methods() + .iter() + .any(|x| *x != ScrollMethod::NoScroll) + { + Some(ScrollConfig { + method: device.config_scroll_method(), + natural_scroll: if device.config_scroll_has_natural_scroll() { + Some(device.config_scroll_natural_scroll_enabled()) + } else { + None + }, + scroll_button: if device.config_scroll_method() + == Some(ScrollMethod::OnButtonDown) + { + Some(device.config_scroll_button()) + } else { + None + }, + }) + } else { + None + }, + tap_config: if device.config_tap_finger_count() > 0 { + Some(TapConfig { + enabled: device.config_tap_enabled(), + button_map: device.config_tap_button_map(), + drag: device.config_tap_drag_enabled(), + drag_lock: device.config_tap_drag_lock_enabled(), + }) + } else { + None + }, + } + } + + pub fn update_device(&self, device: &mut InputDevice) { + if let Err(err) = match self.state { + DeviceState::Enabled => device.config_send_events_set_mode(SendEventsMode::ENABLED), + DeviceState::Disabled => device.config_send_events_set_mode(SendEventsMode::DISABLED), + DeviceState::DisabledOnExternalMouse => { + device.config_send_events_set_mode(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE) + } + } { + warn!( + ?err, + "Failed to apply mode {:?} for device {:?}.", + self.state, + device.name(), + ); + } + if let Some(accel) = self.acceleration.as_ref() { + if let Some(profile) = accel.profile { + if let Err(err) = device.config_accel_set_profile(profile) { + warn!( + ?err, + "Failed to apply acceleration profile {:?} for device {:?}.", + profile, + device.name(), + ); + } + } + if let Err(err) = device.config_accel_set_speed(accel.speed) { + warn!( + ?err, + "Failed to apply acceleration speed {:?} for device {:?}.", + accel.speed, + device.name(), + ); + } + } + if let Some(matrix) = self.calibration { + if let Err(err) = device.config_calibration_set_matrix(matrix) { + warn!( + ?err, + "Failed to apply calibration matrix {:?} for device {:?}.", + matrix, + device.name(), + ); + } + } + if let Some(method) = self.click_method { + if let Err(err) = device.config_click_set_method(method) { + warn!( + ?err, + "Failed to apply click method {:?} for device {:?}.", + method, + device.name(), + ); + } + } + if let Some(dwt) = self.disable_while_typing { + if let Err(err) = device.config_dwt_set_enabled(dwt) { + warn!( + ?err, + "Failed to apply disable-while-typing {:?} for device {:?}.", + dwt, + device.name(), + ); + } + } + if let Some(left) = self.left_handed { + if let Err(err) = device.config_left_handed_set(left) { + warn!( + ?err, + "Failed to apply left-handed {:?} for device {:?}.", + left, + device.name(), + ); + } + } + if let Some(middle) = self.middle_button_emulation { + if let Err(err) = device.config_middle_emulation_set_enabled(middle) { + warn!( + ?err, + "Failed to apply middle-button-emulation {:?} for device {:?}.", + middle, + device.name(), + ); + } + } + if let Some(angle) = self.rotation_angle { + if let Err(err) = device.config_rotation_set_angle(angle) { + warn!( + ?err, + "Failed to apply rotation-angle {:?} for device {:?}", + angle, + device.name(), + ); + } + } + if let Some(scroll) = self.scroll_config.as_ref() { + if let Some(method) = scroll.method { + if let Err(err) = device.config_scroll_set_method(method) { + warn!( + ?err, + "Failed to apply scroll method {:?} for device {:?}.", + method, + device.name(), + ); + } + } + if let Some(natural) = scroll.natural_scroll { + if let Err(err) = device.config_scroll_set_natural_scroll_enabled(natural) { + warn!( + ?err, + "Failed to apply natural scrolling {:?} for device {:?}.", + natural, + device.name(), + ); + } + } + if let Some(button) = scroll.scroll_button { + if let Err(err) = device.config_scroll_set_button(button) { + warn!( + ?err, + "Failed to apply scroll button {:?} for device {:?}.", + button, + device.name(), + ); + } + } + } + if let Some(tap) = self.tap_config.as_ref() { + if let Err(err) = device.config_tap_set_enabled(tap.enabled) { + warn!( + ?err, + "Failed to apply tap-to-click {:?} for device {:?}.", + tap.enabled, + device.name(), + ); + } + if let Some(button_map) = tap.button_map { + if let Err(err) = device.config_tap_set_button_map(button_map) { + warn!( + ?err, + "Failed to apply button map {:?} for device {:?}.", + button_map, + device.name(), + ); + } + } + if let Err(err) = device.config_tap_set_drag_enabled(tap.drag) { + warn!( + ?err, + "Failed to apply tap-drag {:?} for device {:?}.", + tap.drag, + device.name(), + ); + } + if let Err(err) = device.config_tap_set_drag_lock_enabled(tap.drag_lock) { + warn!( + ?err, + "Failed to apply tap-drag-lock {:?} for device {:?}.", + tap.drag_lock, + device.name(), + ); + } + } + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 2a663ddd..832724a9 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,9 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - shell::{ - Shell, WorkspaceAmount, - }, + shell::{Shell, WorkspaceAmount}, state::{BackendData, Data, State}, wayland::protocols::output_configuration::OutputConfigurationState, }; @@ -25,6 +23,8 @@ pub use smithay::{ use std::{cell::RefCell, collections::HashMap, fs::OpenOptions, path::PathBuf}; use tracing::{debug, error, info, warn}; +mod input_config; +use input_config::InputConfig; mod key_bindings; pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern}; mod types; @@ -158,61 +158,6 @@ pub struct InputsConfig { devices: HashMap, } -#[derive(Debug, Deserialize, Serialize)] -pub struct InputConfig { - state: DeviceState, - #[serde(skip_serializing_if = "Option::is_none", default)] - acceleration: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - calibration: Option<[f32; 6]>, - #[serde(with = "ClickMethodDef")] - #[serde(skip_serializing_if = "Option::is_none", default)] - click_method: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - disable_while_typing: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - left_handed: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - middle_button_emulation: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - rotation_angle: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - scroll_config: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - tap_config: Option, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct AccelConfig { - #[serde(with = "AccelProfileDef")] - profile: Option, - speed: f64, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct ScrollConfig { - #[serde(with = "ScrollMethodDef")] - method: Option, - natural_scroll: Option, - scroll_button: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum DeviceState { - Enabled, - Disabled, - DisabledOnExternalMouse, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TapConfig { - enabled: bool, - #[serde(with = "TapButtonMapDef")] - button_map: Option, - drag: bool, - drag_lock: bool, -} - impl Config { pub fn load() -> Config { let xdg = xdg::BaseDirectories::new().ok(); @@ -485,248 +430,9 @@ impl Config { let mut inputs = self.dynamic_conf.inputs_mut(); match inputs.devices.entry(device.name().into()) { - Entry::Occupied(entry) => { - let config = entry.get(); - if let Err(err) = match config.state { - DeviceState::Enabled => { - device.config_send_events_set_mode(SendEventsMode::ENABLED) - } - DeviceState::Disabled => { - device.config_send_events_set_mode(SendEventsMode::DISABLED) - } - DeviceState::DisabledOnExternalMouse => device - .config_send_events_set_mode(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE), - } { - warn!( - ?err, - "Failed to apply mode {:?} for device {:?}.", - config.state, - device.name(), - ); - } - if let Some(accel) = config.acceleration.as_ref() { - if let Some(profile) = accel.profile { - if let Err(err) = device.config_accel_set_profile(profile) { - warn!( - ?err, - "Failed to apply acceleration profile {:?} for device {:?}.", - profile, - device.name(), - ); - } - } - if let Err(err) = device.config_accel_set_speed(accel.speed) { - warn!( - ?err, - "Failed to apply acceleration speed {:?} for device {:?}.", - accel.speed, - device.name(), - ); - } - } - if let Some(matrix) = config.calibration { - if let Err(err) = device.config_calibration_set_matrix(matrix) { - warn!( - ?err, - "Failed to apply calibration matrix {:?} for device {:?}.", - matrix, - device.name(), - ); - } - } - if let Some(method) = config.click_method { - if let Err(err) = device.config_click_set_method(method) { - warn!( - ?err, - "Failed to apply click method {:?} for device {:?}.", - method, - device.name(), - ); - } - } - if let Some(dwt) = config.disable_while_typing { - if let Err(err) = device.config_dwt_set_enabled(dwt) { - warn!( - ?err, - "Failed to apply disable-while-typing {:?} for device {:?}.", - dwt, - device.name(), - ); - } - } - if let Some(left) = config.left_handed { - if let Err(err) = device.config_left_handed_set(left) { - warn!( - ?err, - "Failed to apply left-handed {:?} for device {:?}.", - left, - device.name(), - ); - } - } - if let Some(middle) = config.middle_button_emulation { - if let Err(err) = device.config_middle_emulation_set_enabled(middle) { - warn!( - ?err, - "Failed to apply middle-button-emulation {:?} for device {:?}.", - middle, - device.name(), - ); - } - } - if let Some(angle) = config.rotation_angle { - if let Err(err) = device.config_rotation_set_angle(angle) { - warn!( - ?err, - "Failed to apply rotation-angle {:?} for device {:?}", - angle, - device.name(), - ); - } - } - if let Some(scroll) = config.scroll_config.as_ref() { - if let Some(method) = scroll.method { - if let Err(err) = device.config_scroll_set_method(method) { - warn!( - ?err, - "Failed to apply scroll method {:?} for device {:?}.", - method, - device.name(), - ); - } - } - if let Some(natural) = scroll.natural_scroll { - if let Err(err) = device.config_scroll_set_natural_scroll_enabled(natural) { - warn!( - ?err, - "Failed to apply natural scrolling {:?} for device {:?}.", - natural, - device.name(), - ); - } - } - if let Some(button) = scroll.scroll_button { - if let Err(err) = device.config_scroll_set_button(button) { - warn!( - ?err, - "Failed to apply scroll button {:?} for device {:?}.", - button, - device.name(), - ); - } - } - } - if let Some(tap) = config.tap_config.as_ref() { - if let Err(err) = device.config_tap_set_enabled(tap.enabled) { - warn!( - ?err, - "Failed to apply tap-to-click {:?} for device {:?}.", - tap.enabled, - device.name(), - ); - } - if let Some(button_map) = tap.button_map { - if let Err(err) = device.config_tap_set_button_map(button_map) { - warn!( - ?err, - "Failed to apply button map {:?} for device {:?}.", - button_map, - device.name(), - ); - } - } - if let Err(err) = device.config_tap_set_drag_enabled(tap.drag) { - warn!( - ?err, - "Failed to apply tap-drag {:?} for device {:?}.", - tap.drag, - device.name(), - ); - } - if let Err(err) = device.config_tap_set_drag_lock_enabled(tap.drag_lock) { - warn!( - ?err, - "Failed to apply tap-drag-lock {:?} for device {:?}.", - tap.drag_lock, - device.name(), - ); - } - } - } + Entry::Occupied(entry) => entry.get().update_device(device), Entry::Vacant(entry) => { - entry.insert(InputConfig { - state: match device.config_send_events_mode() { - x if x.contains(SendEventsMode::ENABLED) => DeviceState::Enabled, - x if x.contains(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE) => { - DeviceState::DisabledOnExternalMouse - } - x if x.contains(SendEventsMode::DISABLED) => DeviceState::Disabled, - _ => DeviceState::Disabled, - }, - acceleration: if device.config_accel_is_available() { - Some(AccelConfig { - profile: device.config_accel_profile(), - speed: device.config_accel_speed(), - }) - } else { - None - }, - calibration: device.config_calibration_matrix(), - click_method: device.config_click_method(), - disable_while_typing: if device.config_dwt_is_available() { - Some(device.config_dwt_enabled()) - } else { - None - }, - left_handed: if device.config_left_handed_is_available() { - Some(device.config_left_handed()) - } else { - None - }, - middle_button_emulation: if device.config_middle_emulation_is_available() { - Some(device.config_middle_emulation_enabled()) - } else { - None - }, - rotation_angle: if device.config_rotation_is_available() { - Some(device.config_rotation_angle()) - } else { - None - }, - scroll_config: if device - .config_scroll_methods() - .iter() - .any(|x| *x != ScrollMethod::NoScroll) - { - Some(ScrollConfig { - method: device.config_scroll_method(), - natural_scroll: if device.config_scroll_has_natural_scroll() { - Some(device.config_scroll_natural_scroll_enabled()) - } else { - None - }, - scroll_button: if device.config_scroll_method() - == Some(ScrollMethod::OnButtonDown) - { - Some(device.config_scroll_button()) - } else { - None - }, - }) - } else { - None - }, - tap_config: if device.config_tap_finger_count() > 0 { - Some(TapConfig { - enabled: device.config_tap_enabled(), - button_map: device.config_tap_button_map(), - drag: device.config_tap_drag_enabled(), - drag_lock: device.config_tap_drag_lock_enabled(), - }) - } else { - None - }, - }); + entry.insert(InputConfig::for_device(device)); } } }