input: add click method and middle button emulation
This commit is contained in:
parent
0524e01a3c
commit
b20153550e
24 changed files with 598 additions and 21 deletions
|
|
@ -229,6 +229,14 @@ pub trait InputDevice {
|
|||
None
|
||||
}
|
||||
fn set_natural_scrolling_enabled(&self, enabled: bool);
|
||||
fn click_method(&self) -> Option<InputDeviceClickMethod> {
|
||||
None
|
||||
}
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod);
|
||||
fn middle_button_emulation_enabled(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool);
|
||||
fn tablet_info(&self) -> Option<Box<TabletInit>> {
|
||||
None
|
||||
}
|
||||
|
|
@ -269,6 +277,13 @@ pub enum InputDeviceAccelProfile {
|
|||
Adaptive,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum InputDeviceClickMethod {
|
||||
None,
|
||||
ButtonAreas,
|
||||
Clickfinger,
|
||||
}
|
||||
|
||||
pub enum BackendEvent {
|
||||
NewDrmDevice(Rc<dyn BackendDrmDevice>),
|
||||
NewConnector(Rc<dyn Connector>),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ use {
|
|||
async_engine::SpawnedFuture,
|
||||
backend::{
|
||||
Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||
InputDeviceGroupId, InputDeviceId, InputEvent, KeyState, TransformMatrix,
|
||||
InputDeviceClickMethod, InputDeviceGroupId, InputDeviceId, InputEvent, KeyState,
|
||||
TransformMatrix,
|
||||
},
|
||||
backends::metal::video::{
|
||||
MetalDrmDeviceData, MetalLeaseData, MetalRenderContext, PendingDrmDevice,
|
||||
|
|
@ -26,9 +27,10 @@ use {
|
|||
libinput::{
|
||||
LibInput, LibInputAdapter, LibInputError,
|
||||
consts::{
|
||||
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, LIBINPUT_DEVICE_CAP_TABLET_PAD,
|
||||
LIBINPUT_DEVICE_CAP_TABLET_TOOL,
|
||||
AccelProfile, ConfigClickMethod, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER, LIBINPUT_CONFIG_CLICK_METHOD_NONE,
|
||||
LIBINPUT_DEVICE_CAP_TABLET_PAD, LIBINPUT_DEVICE_CAP_TABLET_TOOL,
|
||||
},
|
||||
device::{LibInputDevice, RegisteredDevice},
|
||||
},
|
||||
|
|
@ -400,6 +402,8 @@ struct InputDeviceProperties {
|
|||
drag_lock_enabled: Cell<Option<bool>>,
|
||||
natural_scrolling_enabled: Cell<Option<bool>>,
|
||||
calibration_matrix: Cell<Option<[[f32; 3]; 2]>>,
|
||||
click_method: Cell<Option<ConfigClickMethod>>,
|
||||
middle_button_emulation_enabled: Cell<Option<bool>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -463,6 +467,12 @@ impl MetalInputDevice {
|
|||
if let Some(lh) = self.desired.calibration_matrix.get() {
|
||||
self.set_calibration_matrix(lh);
|
||||
}
|
||||
if let Some(method) = self.desired.click_method.get() {
|
||||
self.set_click_method_(method);
|
||||
}
|
||||
if let Some(enabled) = self.desired.middle_button_emulation_enabled.get() {
|
||||
self.set_middle_button_emulation_enabled(enabled);
|
||||
}
|
||||
self.fetch_effective();
|
||||
}
|
||||
|
||||
|
|
@ -497,6 +507,14 @@ impl MetalInputDevice {
|
|||
.calibration_matrix
|
||||
.set(Some(device.get_calibration_matrix()));
|
||||
}
|
||||
if device.has_click_methods() {
|
||||
self.effective.click_method.set(Some(device.click_method()));
|
||||
}
|
||||
if device.middle_button_emulation_available() {
|
||||
self.effective
|
||||
.middle_button_emulation_enabled
|
||||
.set(Some(device.middle_button_emulation_enabled()));
|
||||
}
|
||||
}
|
||||
|
||||
fn pre_pause(&self) {
|
||||
|
|
@ -528,6 +546,18 @@ impl MetalInputDevice {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_click_method_(&self, method: ConfigClickMethod) {
|
||||
self.desired.click_method.set(Some(method));
|
||||
if let Some(dev) = self.inputdev.get() {
|
||||
if dev.device().has_click_methods() {
|
||||
dev.device().set_click_method(method);
|
||||
self.effective
|
||||
.click_method
|
||||
.set(Some(dev.device().click_method()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InputDevice for MetalInputDevice {
|
||||
|
|
@ -705,6 +735,44 @@ impl InputDevice for MetalInputDevice {
|
|||
}
|
||||
}
|
||||
|
||||
fn click_method(&self) -> Option<InputDeviceClickMethod> {
|
||||
let p = self.effective.click_method.get()?;
|
||||
let p = match p {
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE => InputDeviceClickMethod::None,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS => InputDeviceClickMethod::ButtonAreas,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER => InputDeviceClickMethod::Clickfinger,
|
||||
_ => return None,
|
||||
};
|
||||
Some(p)
|
||||
}
|
||||
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod) {
|
||||
let method = match method {
|
||||
InputDeviceClickMethod::None => LIBINPUT_CONFIG_CLICK_METHOD_NONE,
|
||||
InputDeviceClickMethod::ButtonAreas => LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS,
|
||||
InputDeviceClickMethod::Clickfinger => LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER,
|
||||
};
|
||||
self.set_click_method_(method);
|
||||
}
|
||||
|
||||
fn middle_button_emulation_enabled(&self) -> Option<bool> {
|
||||
self.effective.middle_button_emulation_enabled.get()
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
self.desired
|
||||
.middle_button_emulation_enabled
|
||||
.set(Some(enabled));
|
||||
if let Some(dev) = self.inputdev.get() {
|
||||
if dev.device().middle_button_emulation_available() {
|
||||
dev.device().set_middle_button_emulation_enabled(enabled);
|
||||
self.effective
|
||||
.middle_button_emulation_enabled
|
||||
.set(Some(dev.device().middle_button_emulation_enabled()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tablet_info(&self) -> Option<Box<TabletInit>> {
|
||||
let dev = self.inputdev.get()?;
|
||||
let dev = dev.device();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ use {
|
|||
AXIS_120, AxisSource, Backend, BackendColorSpace, BackendDrmDevice, BackendEvent,
|
||||
BackendTransferFunction, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId,
|
||||
DrmDeviceId, DrmEvent, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||
InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis, TransformMatrix,
|
||||
InputDeviceClickMethod, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo,
|
||||
ScrollAxis, TransformMatrix,
|
||||
},
|
||||
cmm::cmm_primaries::Primaries,
|
||||
fixed::Fixed,
|
||||
|
|
@ -1219,6 +1220,14 @@ impl InputDevice for XSeatKeyboard {
|
|||
fn set_natural_scrolling_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod) {
|
||||
let _ = method;
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
impl InputDevice for XSeatMouse {
|
||||
|
|
@ -1288,4 +1297,12 @@ impl InputDevice for XSeatMouse {
|
|||
fn set_natural_scrolling_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod) {
|
||||
let _ = method;
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::{InputDeviceAccelProfile, InputDeviceCapability},
|
||||
backend::{InputDeviceAccelProfile, InputDeviceCapability, InputDeviceClickMethod},
|
||||
cli::GlobalArgs,
|
||||
clientmem::ClientMem,
|
||||
libinput::consts::{
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
ConfigClickMethod, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER, LIBINPUT_CONFIG_CLICK_METHOD_NONE,
|
||||
},
|
||||
tools::tool_client::{Handle, ToolClient, with_tool_client},
|
||||
utils::{errorfmt::ErrorFmt, string_ext::StringExt},
|
||||
|
|
@ -133,6 +135,10 @@ pub enum DeviceCommand {
|
|||
RemoveMapping,
|
||||
/// Set the calibration matrix.
|
||||
SetCalibrationMatrix(SetCalibrationMatrixArgs),
|
||||
/// Set the click method.
|
||||
SetClickMethod(SetClickMethodArgs),
|
||||
/// Set whether the device uses middle button emulation.
|
||||
SetMiddleButtonEmulation(SetMiddleButtonEmulationArgs),
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone)]
|
||||
|
|
@ -212,6 +218,26 @@ pub struct SetCalibrationMatrixArgs {
|
|||
pub m12: f32,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone)]
|
||||
pub enum ClickMethod {
|
||||
None,
|
||||
ButtonAreas,
|
||||
Clickfinger,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
pub struct SetClickMethodArgs {
|
||||
/// The method.
|
||||
pub method: ClickMethod,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
pub struct SetMiddleButtonEmulationArgs {
|
||||
/// Whether middle button emulation is enabled.
|
||||
#[arg(action = clap::ArgAction::Set)]
|
||||
pub middle_button_emulation: bool,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
pub struct MapToOutputArgs {
|
||||
/// The output to map to.
|
||||
|
|
@ -286,6 +312,8 @@ struct InputDevice {
|
|||
pub transform_matrix: Option<[[f64; 2]; 2]>,
|
||||
pub output: Option<String>,
|
||||
pub calibration_matrix: Option<[[f32; 3]; 2]>,
|
||||
pub click_method: Option<InputDeviceClickMethod>,
|
||||
pub middle_button_emulation_enabled: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
|
@ -626,6 +654,34 @@ impl Input {
|
|||
m12: a.m12,
|
||||
});
|
||||
}
|
||||
DeviceCommand::SetClickMethod(a) => {
|
||||
let method = match a.method {
|
||||
ClickMethod::None => LIBINPUT_CONFIG_CLICK_METHOD_NONE.0,
|
||||
ClickMethod::ButtonAreas => LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS.0,
|
||||
ClickMethod::Clickfinger => LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER.0,
|
||||
};
|
||||
self.handle_error(input, |e| {
|
||||
eprintln!("Could not set the click method: {}", e);
|
||||
});
|
||||
tc.send(jay_input::SetClickMethod {
|
||||
self_id: input,
|
||||
id: args.device,
|
||||
method,
|
||||
});
|
||||
}
|
||||
DeviceCommand::SetMiddleButtonEmulation(a) => {
|
||||
self.handle_error(input, |e| {
|
||||
eprintln!(
|
||||
"Could not modify the middle-button-emulation setting: {}",
|
||||
e
|
||||
);
|
||||
});
|
||||
tc.send(jay_input::SetMiddleButtonEmulation {
|
||||
self_id: input,
|
||||
id: args.device,
|
||||
enabled: a.middle_button_emulation as _,
|
||||
});
|
||||
}
|
||||
}
|
||||
tc.round_trip().await;
|
||||
}
|
||||
|
|
@ -762,6 +818,17 @@ impl Input {
|
|||
if let Some(v) = &device.calibration_matrix {
|
||||
println!("{prefix} calibration matrix: {:?}", v);
|
||||
}
|
||||
if let Some(v) = &device.click_method {
|
||||
let name = match v {
|
||||
InputDeviceClickMethod::None => "none",
|
||||
InputDeviceClickMethod::ButtonAreas => "button-areas",
|
||||
InputDeviceClickMethod::Clickfinger => "clickfinger",
|
||||
};
|
||||
println!("{prefix} click method: {}", name);
|
||||
}
|
||||
if let Some(v) = &device.middle_button_emulation_enabled {
|
||||
println!("{prefix} middle button emulation: {}", v);
|
||||
}
|
||||
}
|
||||
|
||||
async fn get(self: &Rc<Self>, input: JayInputId) -> Data {
|
||||
|
|
@ -827,6 +894,8 @@ impl Input {
|
|||
transform_matrix: uapi::pod_read(msg.transform_matrix).ok(),
|
||||
output: None,
|
||||
calibration_matrix: None,
|
||||
click_method: None,
|
||||
middle_button_emulation_enabled: None,
|
||||
});
|
||||
});
|
||||
jay_input::InputDeviceOutput::handle(tc, input, data.clone(), |data, msg| {
|
||||
|
|
@ -842,6 +911,29 @@ impl Input {
|
|||
Some([[msg.m00, msg.m01, msg.m02], [msg.m10, msg.m11, msg.m12]]);
|
||||
}
|
||||
});
|
||||
jay_input::ClickMethod::handle(tc, input, data.clone(), |data, msg| {
|
||||
let click_method = match ConfigClickMethod(msg.click_method) {
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE => Some(InputDeviceClickMethod::None),
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS => {
|
||||
Some(InputDeviceClickMethod::ButtonAreas)
|
||||
}
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER => {
|
||||
Some(InputDeviceClickMethod::Clickfinger)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let mut data = data.borrow_mut();
|
||||
if let Some(last) = data.input_device.last_mut() {
|
||||
last.click_method = click_method;
|
||||
}
|
||||
});
|
||||
jay_input::MiddleButtonEmulation::handle(tc, input, data.clone(), |data, msg| {
|
||||
let mut data = data.borrow_mut();
|
||||
if let Some(last) = data.input_device.last_mut() {
|
||||
last.middle_button_emulation_enabled =
|
||||
Some(msg.middle_button_emulation_enabled != 0);
|
||||
}
|
||||
});
|
||||
tc.round_trip().await;
|
||||
let x = data.borrow_mut().clone();
|
||||
x
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use {
|
|||
async_engine::SpawnedFuture,
|
||||
backend::{
|
||||
self, BackendColorSpace, BackendTransferFunction, ConnectorId, DrmDeviceId,
|
||||
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId,
|
||||
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceClickMethod, InputDeviceId,
|
||||
},
|
||||
client::{Client, ClientId},
|
||||
cmm::cmm_transfer_function::TransferFunction,
|
||||
|
|
@ -56,6 +56,9 @@ use {
|
|||
CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD,
|
||||
CAP_TABLET_TOOL, CAP_TOUCH, Capability,
|
||||
},
|
||||
clickmethod::{
|
||||
CLICK_METHOD_BUTTON_AREAS, CLICK_METHOD_CLICKFINGER, CLICK_METHOD_NONE, ClickMethod,
|
||||
},
|
||||
},
|
||||
keyboard::{Keymap, mods::Modifiers, syms::KeySym},
|
||||
logging::LogLevel,
|
||||
|
|
@ -828,6 +831,32 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_click_method(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
click_method: ClickMethod,
|
||||
) -> Result<(), CphError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
let method = match click_method {
|
||||
CLICK_METHOD_NONE => InputDeviceClickMethod::None,
|
||||
CLICK_METHOD_BUTTON_AREAS => InputDeviceClickMethod::ButtonAreas,
|
||||
CLICK_METHOD_CLICKFINGER => InputDeviceClickMethod::Clickfinger,
|
||||
_ => return Err(CphError::UnknownClickMethod(click_method)),
|
||||
};
|
||||
dev.device.set_click_method(method);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_middle_button_emulation_enabled(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
enabled: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
dev.device.set_middle_button_emulation_enabled(enabled);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_ei_socket_enabled(&self, enabled: bool) {
|
||||
self.state.enable_ei_acceptor.set(enabled);
|
||||
self.state.update_ei_acceptor();
|
||||
|
|
@ -2916,6 +2945,12 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SetPointerRevertKey { seat, key } => self
|
||||
.handle_set_pointer_revert_key(seat, key)
|
||||
.wrn("set_pointer_revert_key")?,
|
||||
ClientMessage::SetClickMethod { device, method } => self
|
||||
.handle_set_click_method(device, method)
|
||||
.wrn("set_click_method")?,
|
||||
ClientMessage::SetMiddleButtonEmulationEnabled { device, enabled } => self
|
||||
.handle_set_middle_button_emulation_enabled(device, enabled)
|
||||
.wrn("set_middle_button_emulation_enabled")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -2945,6 +2980,8 @@ enum CphError {
|
|||
UnknownAccelProfile(AccelProfile),
|
||||
#[error("Queried unknown capability: {}", (.0).0)]
|
||||
UnknownCapability(Capability),
|
||||
#[error("Tried to set an unknown click method: {}", (.0).0)]
|
||||
UnknownClickMethod(ClickMethod),
|
||||
#[error("The sized {} is outside the valid range [{}, {}] for component {}", .0, .1.min(), .1.max(), .1.name())]
|
||||
InvalidSize(i32, ThemeSized),
|
||||
#[error("The ol' forker is not available")]
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl Global for JayCompositorGlobal {
|
|||
}
|
||||
|
||||
fn version(&self) -> u32 {
|
||||
18
|
||||
19
|
||||
}
|
||||
|
||||
fn required_caps(&self) -> ClientCaps {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::{self, InputDeviceAccelProfile, InputDeviceId},
|
||||
backend::{self, InputDeviceAccelProfile, InputDeviceClickMethod, InputDeviceId},
|
||||
client::{Client, ClientError},
|
||||
clientmem::{ClientMem, ClientMemError},
|
||||
ifs::wl_seat::WlSeatGlobal,
|
||||
kbvm::{KbvmError, KbvmMap},
|
||||
leaks::Tracker,
|
||||
libinput::consts::{
|
||||
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
AccelProfile, ConfigClickMethod, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER, LIBINPUT_CONFIG_CLICK_METHOD_NONE,
|
||||
},
|
||||
object::{Object, Version},
|
||||
state::{DeviceHandlerData, InputDeviceData},
|
||||
|
|
@ -28,6 +29,8 @@ pub struct JayInput {
|
|||
}
|
||||
|
||||
const CALIBRATION_MATRIX_SINCE: Version = Version(4);
|
||||
const CLICK_METHOD_SINCE: Version = Version(19);
|
||||
const MIDDLE_BUTTON_EMULATION_SINCE: Version = Version(19);
|
||||
|
||||
impl JayInput {
|
||||
pub fn new(id: JayInputId, client: &Rc<Client>, version: Version) -> Self {
|
||||
|
|
@ -155,6 +158,30 @@ impl JayInput {
|
|||
});
|
||||
}
|
||||
}
|
||||
if self.version >= CLICK_METHOD_SINCE {
|
||||
if let Some(click_method) = dev.click_method() {
|
||||
self.client.event(ClickMethod {
|
||||
self_id: self.id,
|
||||
click_method: match click_method {
|
||||
InputDeviceClickMethod::None => LIBINPUT_CONFIG_CLICK_METHOD_NONE.0,
|
||||
InputDeviceClickMethod::Clickfinger => {
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER.0
|
||||
}
|
||||
InputDeviceClickMethod::ButtonAreas => {
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS.0
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
if self.version >= MIDDLE_BUTTON_EMULATION_SINCE {
|
||||
if let Some(middle_button_emulation) = dev.middle_button_emulation_enabled() {
|
||||
self.client.event(MiddleButtonEmulation {
|
||||
self_id: self.id,
|
||||
middle_button_emulation_enabled: middle_button_emulation as _,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn device(&self, id: u32) -> Result<Rc<DeviceHandlerData>, JayInputError> {
|
||||
|
|
@ -461,6 +488,33 @@ impl JayInputRequestHandler for JayInput {
|
|||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn set_click_method(&self, req: SetClickMethod, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.or_error(|| {
|
||||
let dev = self.device(req.id)?;
|
||||
let method = match ConfigClickMethod(req.method) {
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE => InputDeviceClickMethod::None,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS => InputDeviceClickMethod::ButtonAreas,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER => InputDeviceClickMethod::Clickfinger,
|
||||
_ => return Err(JayInputError::UnknownClickMethod(req.method)),
|
||||
};
|
||||
dev.device.set_click_method(method);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation(
|
||||
&self,
|
||||
req: SetMiddleButtonEmulation,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.or_error(|| {
|
||||
let dev = self.device(req.id)?;
|
||||
dev.device
|
||||
.set_middle_button_emulation_enabled(req.enabled != 0);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
@ -482,6 +536,8 @@ pub enum JayInputError {
|
|||
DeviceDoesNotExist(u32),
|
||||
#[error("There is no acceleration profile with id {0}")]
|
||||
UnknownAccelerationProfile(i32),
|
||||
#[error("There is no click method with id {0}")]
|
||||
UnknownClickMethod(i32),
|
||||
#[error("Repeat rate must not be negative")]
|
||||
NegativeRepeatRate,
|
||||
#[error("Repeat delay must not be negative")]
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use {
|
|||
backend::{
|
||||
AxisSource, Backend, BackendColorSpace, BackendEvent, BackendTransferFunction,
|
||||
Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, DrmDeviceId, InputDevice,
|
||||
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState,
|
||||
Mode, MonitorInfo, ScrollAxis, TransformMatrix,
|
||||
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceClickMethod, InputDeviceId,
|
||||
InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis, TransformMatrix,
|
||||
},
|
||||
cmm::cmm_primaries::Primaries,
|
||||
compositor::TestFuture,
|
||||
|
|
@ -543,6 +543,14 @@ trait TestInputDevice: InputDevice {
|
|||
fn set_natural_scrolling_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod) {
|
||||
let _ = method;
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
let _ = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TestInputDevice> InputDevice for T {
|
||||
|
|
@ -609,4 +617,12 @@ impl<T: TestInputDevice> InputDevice for T {
|
|||
fn set_natural_scrolling_enabled(&self, enabled: bool) {
|
||||
<Self as TestInputDevice>::set_natural_scrolling_enabled(self, enabled)
|
||||
}
|
||||
|
||||
fn set_click_method(&self, method: InputDeviceClickMethod) {
|
||||
<Self as TestInputDevice>::set_click_method(self, method)
|
||||
}
|
||||
|
||||
fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
<Self as TestInputDevice>::set_middle_button_emulation_enabled(self, enabled)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,3 +188,18 @@ cenum! {
|
|||
LIBINPUT_CONFIG_DRAG_LOCK_DISABLED = 0,
|
||||
LIBINPUT_CONFIG_DRAG_LOCK_ENABLED = 1,
|
||||
}
|
||||
|
||||
cenum! {
|
||||
ConfigClickMethod, LIBINPUT_CONFIG_CLICK_METHOD;
|
||||
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE = 0,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS = 1 << 0,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER = 1 << 1,
|
||||
}
|
||||
|
||||
cenum! {
|
||||
ConfigMiddleEmulationState, LIBINPUT_CONFIG_MIDDLE_EMULATION_STATE;
|
||||
|
||||
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED = 0,
|
||||
LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED = 1,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ use {
|
|||
crate::libinput::{
|
||||
LibInput,
|
||||
consts::{
|
||||
AccelProfile, ConfigDragLockState, ConfigDragState, ConfigTapState, DeviceCapability,
|
||||
AccelProfile, ConfigClickMethod, ConfigDragLockState, ConfigDragState,
|
||||
ConfigMiddleEmulationState, ConfigTapState, DeviceCapability,
|
||||
LIBINPUT_CONFIG_DRAG_DISABLED, LIBINPUT_CONFIG_DRAG_ENABLED,
|
||||
LIBINPUT_CONFIG_DRAG_LOCK_DISABLED, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED,
|
||||
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED, LIBINPUT_CONFIG_TAP_ENABLED,
|
||||
},
|
||||
sys::{
|
||||
|
|
@ -13,9 +15,14 @@ use {
|
|||
libinput_device_config_accel_set_profile, libinput_device_config_accel_set_speed,
|
||||
libinput_device_config_calibration_get_matrix,
|
||||
libinput_device_config_calibration_has_matrix,
|
||||
libinput_device_config_calibration_set_matrix, libinput_device_config_left_handed_get,
|
||||
libinput_device_config_calibration_set_matrix, libinput_device_config_click_get_method,
|
||||
libinput_device_config_click_get_methods, libinput_device_config_click_set_method,
|
||||
libinput_device_config_left_handed_get,
|
||||
libinput_device_config_left_handed_is_available,
|
||||
libinput_device_config_left_handed_set,
|
||||
libinput_device_config_middle_emulation_get_enabled,
|
||||
libinput_device_config_middle_emulation_is_available,
|
||||
libinput_device_config_middle_emulation_set_enabled,
|
||||
libinput_device_config_scroll_get_natural_scroll_enabled,
|
||||
libinput_device_config_scroll_has_natural_scroll,
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled,
|
||||
|
|
@ -209,6 +216,46 @@ impl<'a> LibInputDevice<'a> {
|
|||
unsafe { libinput_device_config_scroll_has_natural_scroll(self.dev) != 0 }
|
||||
}
|
||||
|
||||
pub fn has_click_methods(&self) -> bool {
|
||||
unsafe { libinput_device_config_click_get_methods(self.dev) != 0 }
|
||||
}
|
||||
|
||||
pub fn click_method(&self) -> ConfigClickMethod {
|
||||
unsafe { ConfigClickMethod(libinput_device_config_click_get_method(self.dev)) }
|
||||
}
|
||||
|
||||
pub fn set_click_method(&self, method: ConfigClickMethod) {
|
||||
unsafe {
|
||||
libinput_device_config_click_set_method(self.dev, method.raw() as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_middle_button_emulation_enabled(&self, enabled: bool) {
|
||||
let enabled = match enabled {
|
||||
true => LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED,
|
||||
false => LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED,
|
||||
};
|
||||
unsafe {
|
||||
libinput_device_config_middle_emulation_set_enabled(self.dev, enabled.raw() as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn middle_button_emulation_enabled(&self) -> bool {
|
||||
let enabled = unsafe {
|
||||
ConfigMiddleEmulationState(libinput_device_config_middle_emulation_get_enabled(
|
||||
self.dev,
|
||||
))
|
||||
};
|
||||
match enabled {
|
||||
LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn middle_button_emulation_available(&self) -> bool {
|
||||
unsafe { libinput_device_config_middle_emulation_is_available(self.dev) != 0 }
|
||||
}
|
||||
|
||||
pub fn device_group(&self) -> LibInputDeviceGroup<'_> {
|
||||
LibInputDeviceGroup {
|
||||
group: unsafe { libinput_device_get_device_group(self.dev) },
|
||||
|
|
|
|||
|
|
@ -114,6 +114,26 @@ unsafe extern "C" {
|
|||
device: *mut libinput_device,
|
||||
) -> c::c_int;
|
||||
|
||||
pub fn libinput_device_config_click_get_methods(device: *mut libinput_device) -> u32;
|
||||
pub fn libinput_device_config_click_get_method(
|
||||
device: *mut libinput_device,
|
||||
) -> libinput_config_click_method;
|
||||
pub fn libinput_device_config_click_set_method(
|
||||
device: *mut libinput_device,
|
||||
method: libinput_config_click_method,
|
||||
) -> libinput_config_status;
|
||||
|
||||
pub fn libinput_device_config_middle_emulation_set_enabled(
|
||||
device: *mut libinput_device,
|
||||
enable: libinput_config_middle_emulation_state,
|
||||
) -> libinput_config_status;
|
||||
pub fn libinput_device_config_middle_emulation_get_enabled(
|
||||
device: *mut libinput_device,
|
||||
) -> libinput_config_middle_emulation_state;
|
||||
pub fn libinput_device_config_middle_emulation_is_available(
|
||||
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;
|
||||
pub fn libinput_event_get_device(event: *mut libinput_event) -> *mut libinput_device;
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ impl ToolClient {
|
|||
self_id: s.registry,
|
||||
name: s.jay_compositor.0,
|
||||
interface: JayCompositor.name(),
|
||||
version: s.jay_compositor.1.min(18),
|
||||
version: s.jay_compositor.1.min(19),
|
||||
id: id.into(),
|
||||
});
|
||||
self.jay_compositor.set(Some(id));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue