From 813f87faaa7d69d93119da7a1875111ff5f7ffbb Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 12 Mar 2024 16:16:21 +0100 Subject: [PATCH] backend: make input device properties readable --- src/backend.rs | 24 +++++ src/backends/metal.rs | 188 ++++++++++++++++++++++++++-------- src/backends/metal/input.rs | 12 ++- src/backends/metal/monitor.rs | 12 +-- src/libinput/device.rs | 41 +++++++- src/libinput/sys.rs | 13 +++ 6 files changed, 232 insertions(+), 58 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 9b05dc4f..1e2119b4 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -118,14 +118,38 @@ pub trait InputDevice { fn on_change(&self, cb: Rc); fn grab(&self, grab: bool); fn has_capability(&self, cap: InputDeviceCapability) -> bool; + fn left_handed(&self) -> Option { + None + } fn set_left_handed(&self, left_handed: bool); + fn accel_profile(&self) -> Option { + None + } fn set_accel_profile(&self, profile: InputDeviceAccelProfile); + fn accel_speed(&self) -> Option { + None + } fn set_accel_speed(&self, speed: f64); + fn transform_matrix(&self) -> Option { + None + } fn set_transform_matrix(&self, matrix: TransformMatrix); fn name(&self) -> Rc; + fn tap_enabled(&self) -> Option { + None + } fn set_tap_enabled(&self, enabled: bool); + fn drag_enabled(&self) -> Option { + None + } fn set_drag_enabled(&self, enabled: bool); + fn drag_lock_enabled(&self) -> Option { + None + } fn set_drag_lock_enabled(&self, enabled: bool); + fn natural_scrolling_enabled(&self) -> Option { + None + } fn set_natural_scrolling_enabled(&self, enabled: bool); } diff --git a/src/backends/metal.rs b/src/backends/metal.rs index 6f18a7d7..0f11d34c 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -290,17 +290,22 @@ struct MetalInputDevice { events: SyncQueue, cb: CloneCell>>, name: CloneCell>, - natural_scrolling: Cell, + transform_matrix: Cell>, // state pressed_keys: SmallMap, pressed_buttons: SmallMap, // config + desired: InputDeviceProperties, + effective: InputDeviceProperties, +} + +#[derive(Default)] +struct InputDeviceProperties { left_handed: Cell>, accel_profile: Cell>, accel_speed: Cell>, - transform_matrix: Cell>, tap_enabled: Cell>, drag_enabled: Cell>, drag_lock_enabled: Cell>, @@ -341,30 +346,58 @@ impl LibInputAdapter for DeviceHolder { impl MetalInputDevice { fn apply_config(&self) { - let dev = match self.inputdev.get() { - Some(dev) => dev, - _ => return, + if self.inputdev.is_none() { + return; + } + if let Some(lh) = self.desired.left_handed.get() { + self.set_left_handed(lh); + } + if let Some(profile) = self.desired.accel_profile.get() { + self.set_accel_profile_(profile); + } + if let Some(speed) = self.desired.accel_speed.get() { + self.set_accel_speed(speed); + } + if let Some(enabled) = self.desired.tap_enabled.get() { + self.set_tap_enabled(enabled); + } + if let Some(enabled) = self.desired.drag_enabled.get() { + self.set_drag_enabled(enabled); + } + if let Some(enabled) = self.desired.drag_lock_enabled.get() { + self.set_drag_lock_enabled(enabled); + } + if let Some(enabled) = self.desired.natural_scrolling_enabled.get() { + self.set_natural_scrolling_enabled(enabled); + } + self.fetch_effective(); + } + + fn fetch_effective(&self) { + let Some(dev) = self.inputdev.get() else { + return; }; - if let Some(lh) = self.left_handed.get() { - dev.device().set_left_handed(lh); + let device = dev.device(); + if device.left_handed_available() { + self.effective.left_handed.set(Some(device.left_handed())); } - if let Some(profile) = self.accel_profile.get() { - dev.device().set_accel_profile(profile); + if device.accel_available() { + self.effective + .accel_profile + .set(Some(device.accel_profile())); + self.effective.accel_speed.set(Some(device.accel_speed())); } - if let Some(speed) = self.accel_speed.get() { - dev.device().set_accel_speed(speed); + if device.tap_available() { + self.effective.tap_enabled.set(Some(device.tap_enabled())); + self.effective.drag_enabled.set(Some(device.drag_enabled())); + self.effective + .drag_lock_enabled + .set(Some(device.drag_lock_enabled())); } - if let Some(enabled) = self.tap_enabled.get() { - dev.device().set_tap_enabled(enabled); - } - if let Some(enabled) = self.drag_enabled.get() { - dev.device().set_drag_enabled(enabled); - } - if let Some(enabled) = self.drag_lock_enabled.get() { - dev.device().set_drag_lock_enabled(enabled); - } - if let Some(enabled) = self.natural_scrolling_enabled.get() { - self.do_set_natural_scrolling_enabled(&dev, enabled); + if device.has_natural_scrolling() { + self.effective + .natural_scrolling_enabled + .set(Some(device.natural_scrolling_enabled())); } } @@ -386,10 +419,16 @@ impl MetalInputDevice { } } - fn do_set_natural_scrolling_enabled(&self, dev: &RegisteredDevice, enabled: bool) { - dev.device().set_natural_scrolling_enabled(enabled); - self.natural_scrolling - .set(dev.device().natural_scrolling_enabled()); + fn set_accel_profile_(&self, profile: AccelProfile) { + self.desired.accel_profile.set(Some(profile)); + if let Some(dev) = self.inputdev.get() { + if dev.device().accel_available() { + dev.device().set_accel_profile(profile); + self.effective + .accel_profile + .set(Some(dev.device().accel_profile())); + } + } } } @@ -431,9 +470,14 @@ impl InputDevice for MetalInputDevice { } fn set_left_handed(&self, left_handed: bool) { - self.left_handed.set(Some(left_handed)); + self.desired.left_handed.set(Some(left_handed)); if let Some(dev) = self.inputdev.get() { - dev.device().set_left_handed(left_handed); + if dev.device().left_handed_available() { + dev.device().set_left_handed(left_handed); + self.effective + .left_handed + .set(Some(dev.device().left_handed())); + } } } @@ -442,16 +486,18 @@ impl InputDevice for MetalInputDevice { InputDeviceAccelProfile::Flat => LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, InputDeviceAccelProfile::Adaptive => LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, }; - self.accel_profile.set(Some(profile)); - if let Some(dev) = self.inputdev.get() { - dev.device().set_accel_profile(profile); - } + self.set_accel_profile_(profile); } fn set_accel_speed(&self, speed: f64) { - self.accel_speed.set(Some(speed)); + self.desired.accel_speed.set(Some(speed)); if let Some(dev) = self.inputdev.get() { - dev.device().set_accel_speed(speed); + if dev.device().accel_available() { + dev.device().set_accel_speed(speed); + self.effective + .accel_speed + .set(Some(dev.device().accel_speed())); + } } } @@ -464,32 +510,90 @@ impl InputDevice for MetalInputDevice { } fn set_tap_enabled(&self, enabled: bool) { - self.tap_enabled.set(Some(enabled)); + self.desired.tap_enabled.set(Some(enabled)); if let Some(dev) = self.inputdev.get() { - dev.device().set_tap_enabled(enabled); + if dev.device().tap_available() { + dev.device().set_tap_enabled(enabled); + self.effective + .tap_enabled + .set(Some(dev.device().tap_enabled())); + } } } fn set_drag_enabled(&self, enabled: bool) { - self.drag_enabled.set(Some(enabled)); + self.desired.drag_enabled.set(Some(enabled)); if let Some(dev) = self.inputdev.get() { - dev.device().set_drag_enabled(enabled); + if dev.device().tap_available() { + dev.device().set_drag_enabled(enabled); + self.effective + .drag_enabled + .set(Some(dev.device().drag_enabled())); + } } } fn set_drag_lock_enabled(&self, enabled: bool) { - self.drag_lock_enabled.set(Some(enabled)); + self.desired.drag_lock_enabled.set(Some(enabled)); if let Some(dev) = self.inputdev.get() { - dev.device().set_drag_lock_enabled(enabled); + if dev.device().tap_available() { + dev.device().set_drag_lock_enabled(enabled); + self.effective + .drag_lock_enabled + .set(Some(dev.device().drag_lock_enabled())); + } } } fn set_natural_scrolling_enabled(&self, enabled: bool) { - self.natural_scrolling_enabled.set(Some(enabled)); + self.desired.natural_scrolling_enabled.set(Some(enabled)); if let Some(dev) = self.inputdev.get() { - self.do_set_natural_scrolling_enabled(&dev, enabled); + if dev.device().has_natural_scrolling() { + dev.device().set_natural_scrolling_enabled(enabled); + self.effective + .natural_scrolling_enabled + .set(Some(dev.device().natural_scrolling_enabled())); + } } } + + fn left_handed(&self) -> Option { + self.effective.left_handed.get() + } + + fn accel_profile(&self) -> Option { + let p = self.effective.accel_profile.get()?; + let p = match p { + LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT => InputDeviceAccelProfile::Flat, + LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive, + _ => return None, + }; + Some(p) + } + + fn accel_speed(&self) -> Option { + self.effective.accel_speed.get() + } + + fn transform_matrix(&self) -> Option { + self.transform_matrix.get() + } + + fn tap_enabled(&self) -> Option { + self.effective.tap_enabled.get() + } + + fn drag_enabled(&self) -> Option { + self.effective.drag_enabled.get() + } + + fn drag_lock_enabled(&self) -> Option { + self.effective.drag_lock_enabled.get() + } + + fn natural_scrolling_enabled(&self) -> Option { + self.effective.natural_scrolling_enabled.get() + } } impl MetalInputDevice { diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index d9390ccb..0f168bf7 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -149,13 +149,21 @@ impl MetalBackend { InputEvent::Axis120 { dist: scroll as _, axis, - inverted: dev.natural_scrolling.get(), + inverted: dev + .effective + .natural_scrolling_enabled + .get() + .unwrap_or_default(), } } else { InputEvent::AxisPx { dist: Fixed::from_f64(scroll), axis, - inverted: dev.natural_scrolling.get(), + inverted: dev + .effective + .natural_scrolling_enabled + .get() + .unwrap_or_default(), } }; dev.event(ie); diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 829ad07a..3f20e07b 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -287,17 +287,11 @@ impl MetalBackend { events: Default::default(), cb: Default::default(), name: Default::default(), - natural_scrolling: Default::default(), pressed_keys: Default::default(), pressed_buttons: Default::default(), - left_handed: Default::default(), - accel_profile: Default::default(), - accel_speed: Default::default(), + desired: Default::default(), transform_matrix: Default::default(), - tap_enabled: Default::default(), - drag_enabled: Default::default(), - drag_lock_enabled: Default::default(), - natural_scrolling_enabled: Default::default(), + effective: Default::default(), }); slots[slot] = Some(dev.clone()); self.device_holder @@ -337,8 +331,6 @@ impl MetalBackend { }; inputdev.device().set_slot(slot); dev.name.set(Rc::new(inputdev.device().name())); - dev.natural_scrolling - .set(inputdev.device().natural_scrolling_enabled()); dev.inputdev.set(Some(inputdev)); dev.apply_config(); slf.state diff --git a/src/libinput/device.rs b/src/libinput/device.rs index b12f04bf..73eb1965 100644 --- a/src/libinput/device.rs +++ b/src/libinput/device.rs @@ -7,13 +7,19 @@ use { LIBINPUT_CONFIG_TAP_DISABLED, LIBINPUT_CONFIG_TAP_ENABLED, }, sys::{ - libinput_device, libinput_device_config_accel_set_profile, - libinput_device_config_accel_set_speed, libinput_device_config_left_handed_set, + libinput_device, libinput_device_config_accel_get_profile, + libinput_device_config_accel_get_speed, libinput_device_config_accel_is_available, + libinput_device_config_accel_set_profile, libinput_device_config_accel_set_speed, + libinput_device_config_left_handed_get, + libinput_device_config_left_handed_is_available, + libinput_device_config_left_handed_set, libinput_device_config_scroll_get_natural_scroll_enabled, + libinput_device_config_scroll_has_natural_scroll, libinput_device_config_scroll_set_natural_scroll_enabled, libinput_device_config_tap_get_drag_enabled, libinput_device_config_tap_get_drag_lock_enabled, - libinput_device_config_tap_get_enabled, libinput_device_config_tap_set_drag_enabled, + libinput_device_config_tap_get_enabled, libinput_device_config_tap_get_finger_count, + libinput_device_config_tap_set_drag_enabled, libinput_device_config_tap_set_drag_lock_enabled, libinput_device_config_tap_set_enabled, libinput_device_get_name, libinput_device_get_user_data, libinput_device_has_capability, @@ -64,12 +70,32 @@ impl<'a> LibInputDevice<'a> { res != 0 } + pub fn left_handed_available(&self) -> bool { + unsafe { libinput_device_config_left_handed_is_available(self.dev) != 0 } + } + + pub fn left_handed(&self) -> bool { + unsafe { libinput_device_config_left_handed_get(self.dev) != 0 } + } + pub fn set_left_handed(&self, left_handed: bool) { unsafe { libinput_device_config_left_handed_set(self.dev, left_handed as _); } } + pub fn accel_available(&self) -> bool { + unsafe { libinput_device_config_accel_is_available(self.dev) != 0 } + } + + pub fn accel_profile(&self) -> AccelProfile { + unsafe { AccelProfile(libinput_device_config_accel_get_profile(self.dev)) } + } + + pub fn accel_speed(&self) -> f64 { + unsafe { libinput_device_config_accel_get_speed(self.dev) } + } + pub fn set_accel_profile(&self, profile: AccelProfile) { unsafe { libinput_device_config_accel_set_profile(self.dev, profile.raw() as _); @@ -99,7 +125,10 @@ impl<'a> LibInputDevice<'a> { } } - #[allow(dead_code)] + pub fn tap_available(&self) -> bool { + unsafe { libinput_device_config_tap_get_finger_count(self.dev) != 0 } + } + pub fn tap_enabled(&self) -> bool { let enabled = unsafe { ConfigTapState(libinput_device_config_tap_get_enabled(self.dev)) }; match enabled { @@ -158,6 +187,10 @@ impl<'a> LibInputDevice<'a> { pub fn natural_scrolling_enabled(&self) -> bool { unsafe { libinput_device_config_scroll_get_natural_scroll_enabled(self.dev) != 0 } } + + pub fn has_natural_scrolling(&self) -> bool { + unsafe { libinput_device_config_scroll_has_natural_scroll(self.dev) != 0 } + } } impl RegisteredDevice { diff --git a/src/libinput/sys.rs b/src/libinput/sys.rs index acd9dc7b..77e90a1e 100644 --- a/src/libinput/sys.rs +++ b/src/libinput/sys.rs @@ -41,19 +41,29 @@ extern "C" { device: *mut libinput_device, cap: libinput_device_capability, ) -> c::c_int; + pub fn libinput_device_config_left_handed_is_available( + device: *mut libinput_device, + ) -> c::c_int; + pub fn libinput_device_config_left_handed_get(device: *mut libinput_device) -> c::c_int; pub fn libinput_device_config_left_handed_set( device: *mut libinput_device, left_handed: c::c_int, ) -> libinput_config_status; + pub fn libinput_device_config_accel_is_available(device: *mut libinput_device) -> c::c_int; + pub fn libinput_device_config_accel_get_profile( + device: *mut libinput_device, + ) -> libinput_config_accel_profile; pub fn libinput_device_config_accel_set_profile( device: *mut libinput_device, profile: libinput_config_accel_profile, ) -> libinput_config_status; + pub fn libinput_device_config_accel_get_speed(device: *mut libinput_device) -> f64; pub fn libinput_device_config_accel_set_speed( device: *mut libinput_device, speed: f64, ) -> libinput_config_status; pub fn libinput_device_get_name(device: *mut libinput_device) -> *const c::c_char; + pub fn libinput_device_config_tap_get_finger_count(device: *mut libinput_device) -> c::c_int; pub fn libinput_device_config_tap_set_enabled( device: *mut libinput_device, enable: libinput_config_tap_state, @@ -82,6 +92,9 @@ extern "C" { pub fn libinput_device_config_scroll_get_natural_scroll_enabled( device: *mut libinput_device, ) -> c::c_int; + pub fn libinput_device_config_scroll_has_natural_scroll( + device: *mut libinput_device, + ) -> c::c_int; pub fn libinput_event_destroy(event: *mut libinput_event); pub fn libinput_event_get_type(event: *mut libinput_event) -> libinput_event_type;