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
|
|
@ -131,6 +131,16 @@ pub fn main() -> anyhow::Result<()> {
|
|||
libinput::LIBINPUT_CONFIG_DRAG_LOCK_STATE,
|
||||
"libinput_config_drag_lock_state",
|
||||
)?;
|
||||
write_ty(
|
||||
&mut f,
|
||||
libinput::LIBINPUT_CONFIG_CLICK_METHOD,
|
||||
"libinput_config_click_method",
|
||||
)?;
|
||||
write_ty(
|
||||
&mut f,
|
||||
libinput::LIBINPUT_CONFIG_MIDDLE_EMULATION_STATE,
|
||||
"libinput_config_middle_emulation_state",
|
||||
)?;
|
||||
|
||||
let mut f = open("pango_tys.rs")?;
|
||||
write_ty(&mut f, pango::CAIRO_FORMATS, "cairo_format_t")?;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use {
|
|||
exec::Command,
|
||||
input::{
|
||||
FocusFollowsMouseMode, InputDevice, Seat, SwitchEvent, acceleration::AccelProfile,
|
||||
capability::Capability,
|
||||
capability::Capability, clickmethod::ClickMethod,
|
||||
},
|
||||
keyboard::{
|
||||
Keymap,
|
||||
|
|
@ -1174,6 +1174,14 @@ impl ConfigClient {
|
|||
self.send(&ClientMessage::SetDragLockEnabled { device, enabled })
|
||||
}
|
||||
|
||||
pub fn set_input_click_method(&self, device: InputDevice, method: ClickMethod) {
|
||||
self.send(&ClientMessage::SetClickMethod { device, method })
|
||||
}
|
||||
|
||||
pub fn set_input_middle_button_emulation_enabled(&self, device: InputDevice, enabled: bool) {
|
||||
self.send(&ClientMessage::SetMiddleButtonEmulationEnabled { device, enabled })
|
||||
}
|
||||
|
||||
pub fn device_name(&self, device: InputDevice) -> String {
|
||||
let res = self.send_with_response(&ClientMessage::GetDeviceName { device });
|
||||
get_response!(res, String::new(), GetDeviceName { name });
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use {
|
|||
client::{Client, ClientMatcher},
|
||||
input::{
|
||||
FocusFollowsMouseMode, InputDevice, Seat, SwitchEvent, acceleration::AccelProfile,
|
||||
capability::Capability,
|
||||
capability::Capability, clickmethod::ClickMethod,
|
||||
},
|
||||
keyboard::{Keymap, mods::Modifiers, syms::KeySym},
|
||||
logging::LogLevel,
|
||||
|
|
@ -710,6 +710,14 @@ pub enum ClientMessage<'a> {
|
|||
seat: Seat,
|
||||
key: KeySym,
|
||||
},
|
||||
SetClickMethod {
|
||||
device: InputDevice,
|
||||
method: ClickMethod,
|
||||
},
|
||||
SetMiddleButtonEmulationEnabled {
|
||||
device: InputDevice,
|
||||
enabled: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
pub mod acceleration;
|
||||
pub mod capability;
|
||||
pub mod clickmethod;
|
||||
|
||||
use {
|
||||
crate::{
|
||||
_private::{DEFAULT_SEAT_NAME, ipc::WorkspaceSource},
|
||||
Axis, Direction, ModifiedKeySym, Workspace,
|
||||
input::{acceleration::AccelProfile, capability::Capability},
|
||||
input::{acceleration::AccelProfile, capability::Capability, clickmethod::ClickMethod},
|
||||
keyboard::{Keymap, mods::Modifiers, syms::KeySym},
|
||||
video::Connector,
|
||||
window::Window,
|
||||
|
|
@ -133,6 +134,20 @@ impl InputDevice {
|
|||
get!().set_input_natural_scrolling_enabled(self, enabled);
|
||||
}
|
||||
|
||||
/// Sets the click method of the device.
|
||||
///
|
||||
/// See <https://wayland.freedesktop.org/libinput/doc/latest/configuration.html#click-method>
|
||||
pub fn set_click_method(self, method: ClickMethod) {
|
||||
get!().set_input_click_method(self, method);
|
||||
}
|
||||
|
||||
/// Sets whether middle button emulation is enabled for this device.
|
||||
///
|
||||
/// See <https://wayland.freedesktop.org/libinput/doc/latest/configuration.html#middle-button-emulation>
|
||||
pub fn set_middle_button_emulation_enabled(self, enabled: bool) {
|
||||
get!().set_input_middle_button_emulation_enabled(self, enabled);
|
||||
}
|
||||
|
||||
/// Returns the syspath of this device.
|
||||
///
|
||||
/// E.g. `/sys/devices/pci0000:00/0000:00:08.1/0000:14:00.4/usb5/5-1/5-1.1/5-1.1.3/5-1.1.3:1.0`.
|
||||
|
|
|
|||
18
jay-config/src/input/clickmethod.rs
Normal file
18
jay-config/src/input/clickmethod.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//! Constants determining the click method of a device.
|
||||
//!
|
||||
//! See the libinput documentation for details.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The click method of a device.
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct ClickMethod(pub u32);
|
||||
|
||||
/// No click method handling
|
||||
pub const CLICK_METHOD_NONE: ClickMethod = ClickMethod(0);
|
||||
|
||||
/// Button area
|
||||
pub const CLICK_METHOD_BUTTON_AREAS: ClickMethod = ClickMethod(1 << 0);
|
||||
|
||||
/// Clickfinger
|
||||
pub const CLICK_METHOD_CLICKFINGER: ClickMethod = ClickMethod(1 << 1);
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use {
|
|||
ahash::AHashMap,
|
||||
jay_config::{
|
||||
Axis, Direction, Workspace,
|
||||
input::{SwitchEvent, acceleration::AccelProfile},
|
||||
input::{SwitchEvent, acceleration::AccelProfile, clickmethod::ClickMethod},
|
||||
keyboard::{Keymap, ModifiedKeySym, mods::Modifiers, syms::KeySym},
|
||||
logging::LogLevel,
|
||||
status::MessageFormat,
|
||||
|
|
@ -362,6 +362,8 @@ pub struct Input {
|
|||
pub tap_drag_lock_enabled: Option<bool>,
|
||||
pub left_handed: Option<bool>,
|
||||
pub natural_scrolling: Option<bool>,
|
||||
pub click_method: Option<ClickMethod>,
|
||||
pub middle_button_emulation: Option<bool>,
|
||||
pub px_per_wheel_scroll: Option<f64>,
|
||||
pub transform_matrix: Option<[[f64; 2]; 2]>,
|
||||
pub keymap: Option<ConfigKeymap>,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use {
|
|||
jay_config::input::{
|
||||
SwitchEvent,
|
||||
acceleration::{ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT},
|
||||
clickmethod::{CLICK_METHOD_BUTTON_AREAS, CLICK_METHOD_CLICKFINGER, CLICK_METHOD_NONE},
|
||||
},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
|
@ -87,7 +88,9 @@ impl Parser for InputParser<'_> {
|
|||
output_val,
|
||||
remove_mapping,
|
||||
calibration_matrix,
|
||||
click_method,
|
||||
),
|
||||
(middle_button_emulation,),
|
||||
) = ext.extract((
|
||||
(
|
||||
opt(str("tag")),
|
||||
|
|
@ -111,7 +114,9 @@ impl Parser for InputParser<'_> {
|
|||
opt(val("output")),
|
||||
recover(opt(bol("remove-mapping"))),
|
||||
recover(opt(val("calibration-matrix"))),
|
||||
recover(opt(str("click-method"))),
|
||||
),
|
||||
(recover(opt(bol("middle-button-emulation"))),),
|
||||
))?;
|
||||
let accel_profile = match accel_profile {
|
||||
None => None,
|
||||
|
|
@ -124,6 +129,18 @@ impl Parser for InputParser<'_> {
|
|||
}
|
||||
},
|
||||
};
|
||||
let click_method = match click_method {
|
||||
None => None,
|
||||
Some(p) => match p.value.to_ascii_lowercase().as_str() {
|
||||
"none" => Some(CLICK_METHOD_NONE),
|
||||
"button-areas" => Some(CLICK_METHOD_BUTTON_AREAS),
|
||||
"clickfinger" => Some(CLICK_METHOD_CLICKFINGER),
|
||||
v => {
|
||||
log::warn!("Unknown click-method {v}: {}", self.cx.error3(p.span));
|
||||
None
|
||||
}
|
||||
},
|
||||
};
|
||||
let transform_matrix = match transform_matrix {
|
||||
None => None,
|
||||
Some(matrix) => match matrix.parse(&mut TransformMatrixParser) {
|
||||
|
|
@ -242,6 +259,8 @@ impl Parser for InputParser<'_> {
|
|||
tap_drag_lock_enabled: tap_drag_lock_enabled.despan(),
|
||||
left_handed: left_handed.despan(),
|
||||
natural_scrolling: natural_scrolling.despan(),
|
||||
middle_button_emulation: middle_button_emulation.despan(),
|
||||
click_method,
|
||||
px_per_wheel_scroll: px_per_wheel_scroll.despan(),
|
||||
transform_matrix,
|
||||
keymap,
|
||||
|
|
|
|||
|
|
@ -546,6 +546,12 @@ impl Input {
|
|||
if let Some(v) = self.calibration_matrix {
|
||||
c.set_calibration_matrix(v);
|
||||
}
|
||||
if let Some(v) = self.click_method {
|
||||
c.set_click_method(v);
|
||||
}
|
||||
if let Some(v) = self.middle_button_emulation {
|
||||
c.set_middle_button_emulation_enabled(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -500,6 +500,15 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"ClickMethod": {
|
||||
"type": "string",
|
||||
"description": "The click method to apply to an input device.\n\nSee the libinput documentation for more details.\n",
|
||||
"enum": [
|
||||
"none",
|
||||
"button-areas",
|
||||
"clickfinger"
|
||||
]
|
||||
},
|
||||
"ClientMatch": {
|
||||
"description": "Criteria for matching clients.\n\nIf no fields are set, all clients are matched. If multiple fields are set, all fields\nmust match the client.\n",
|
||||
"type": "object",
|
||||
|
|
@ -1173,6 +1182,14 @@
|
|||
"type": "boolean",
|
||||
"description": "Whether the device uses natural scrolling.\n\nSee the libinput documentation for more details.\n"
|
||||
},
|
||||
"middle-button-emulation": {
|
||||
"type": "boolean",
|
||||
"description": "Converts a simultaneous left and right button click into a middle button click.\n\nSee the libinput documentation for more details.\n"
|
||||
},
|
||||
"click-method": {
|
||||
"description": "Defines how button events are triggered on a clickable touchpad.\n\nSee the libinput documentation for more details.\n",
|
||||
"$ref": "#/$defs/ClickMethod"
|
||||
},
|
||||
"px-per-wheel-scroll": {
|
||||
"type": "boolean",
|
||||
"description": "The number of pixels to scroll for each scroll wheel dedent.\n"
|
||||
|
|
|
|||
|
|
@ -700,6 +700,32 @@ The string should have one of the following values:
|
|||
The brightness in cd/m^2.
|
||||
|
||||
|
||||
<a name="types-ClickMethod"></a>
|
||||
### `ClickMethod`
|
||||
|
||||
The click method to apply to an input device.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
|
||||
Values of this type should be strings.
|
||||
|
||||
The string should have one of the following values:
|
||||
|
||||
- `none`:
|
||||
|
||||
No click method handling.
|
||||
|
||||
- `button-areas`:
|
||||
|
||||
Bottom area of the touchpad is divided into a left, middle and right button area.
|
||||
|
||||
- `clickfinger`:
|
||||
|
||||
Number of fingers on the touchpad decide the button type.
|
||||
Clicking with 1, 2, 3 fingers triggers a left, right, or middle click, respectively.
|
||||
|
||||
|
||||
|
||||
<a name="types-ClientMatch"></a>
|
||||
### `ClientMatch`
|
||||
|
||||
|
|
@ -2455,6 +2481,22 @@ The table has the following fields:
|
|||
|
||||
The value of this field should be a boolean.
|
||||
|
||||
- `middle-button-emulation` (optional):
|
||||
|
||||
Converts a simultaneous left and right button click into a middle button click.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
|
||||
The value of this field should be a boolean.
|
||||
|
||||
- `click-method` (optional):
|
||||
|
||||
Defines how button events are triggered on a clickable touchpad.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
|
||||
The value of this field should be a [ClickMethod](#types-ClickMethod).
|
||||
|
||||
- `px-per-wheel-scroll` (optional):
|
||||
|
||||
The number of pixels to scroll for each scroll wheel dedent.
|
||||
|
|
|
|||
|
|
@ -1372,6 +1372,20 @@ Input:
|
|||
description: |
|
||||
Whether the device uses natural scrolling.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
middle-button-emulation:
|
||||
kind: boolean
|
||||
required: false
|
||||
description: |
|
||||
Converts a simultaneous left and right button click into a middle button click.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
click-method:
|
||||
ref: ClickMethod
|
||||
required: false
|
||||
description: |
|
||||
Defines how button events are triggered on a clickable touchpad.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
px-per-wheel-scroll:
|
||||
kind: boolean
|
||||
|
|
@ -1524,6 +1538,23 @@ AccelProfile:
|
|||
See the libinput documentation for more details.
|
||||
|
||||
|
||||
ClickMethod:
|
||||
kind: string
|
||||
values:
|
||||
- value: none
|
||||
description: No click method handling.
|
||||
- value: button-areas
|
||||
description: Bottom area of the touchpad is divided into a left, middle and right button area.
|
||||
- value: clickfinger
|
||||
description: |
|
||||
Number of fingers on the touchpad decide the button type.
|
||||
Clicking with 1, 2, 3 fingers triggers a left, right, or middle click, respectively.
|
||||
description: |
|
||||
The click method to apply to an input device.
|
||||
|
||||
See the libinput documentation for more details.
|
||||
|
||||
|
||||
LogLevel:
|
||||
kind: string
|
||||
description: A log level.
|
||||
|
|
|
|||
|
|
@ -124,6 +124,16 @@ request set_calibration_matrix (since = 4) {
|
|||
m12: pod(f32),
|
||||
}
|
||||
|
||||
request set_click_method (since = 19) {
|
||||
id: u32,
|
||||
method: i32,
|
||||
}
|
||||
|
||||
request set_middle_button_emulation (since = 19) {
|
||||
id: u32,
|
||||
enabled: u32,
|
||||
}
|
||||
|
||||
# events
|
||||
|
||||
event seat {
|
||||
|
|
@ -177,3 +187,11 @@ event calibration_matrix (since = 4) {
|
|||
m11: pod(f32),
|
||||
m12: pod(f32),
|
||||
}
|
||||
|
||||
event click_method (since = 19) {
|
||||
click_method: i32,
|
||||
}
|
||||
|
||||
event middle_button_emulation (since = 19) {
|
||||
middle_button_emulation_enabled: u32,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue