autocommit 2022-03-30 22:27:19 CEST
This commit is contained in:
parent
a8136ed88c
commit
ab4ac883ee
19 changed files with 434 additions and 76 deletions
|
|
@ -24,6 +24,10 @@ pub trait InputDevice {
|
|||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
||||
fn grab(&self, grab: bool);
|
||||
fn has_capability(&self, cap: InputDeviceCapability) -> bool;
|
||||
fn set_left_handed(&self, left_handed: bool);
|
||||
fn set_accel_profile(&self, profile: InputDeviceAccelProfile);
|
||||
fn set_accel_speed(&self, speed: f64);
|
||||
fn set_transform_matrix(&self, matrix: [[f64; 2]; 2]);
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
|
@ -37,6 +41,12 @@ pub enum InputDeviceCapability {
|
|||
Switch,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum InputDeviceAccelProfile {
|
||||
Flat,
|
||||
Adaptive,
|
||||
}
|
||||
|
||||
pub enum BackendEvent {
|
||||
NewOutput(Rc<dyn Output>),
|
||||
NewInputDevice(Rc<dyn InputDevice>),
|
||||
|
|
|
|||
|
|
@ -3,11 +3,19 @@ mod monitor;
|
|||
mod video;
|
||||
|
||||
use crate::async_engine::{AsyncError, AsyncFd};
|
||||
use crate::backend::{Backend, InputDevice, InputDeviceCapability, InputDeviceId, InputEvent};
|
||||
use crate::backend::{
|
||||
Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent,
|
||||
};
|
||||
use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice};
|
||||
use crate::dbus::DbusError;
|
||||
use crate::drm::drm::DrmError;
|
||||
use crate::drm::gbm::GbmError;
|
||||
use crate::libinput::consts::{
|
||||
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE, LIBINPUT_DEVICE_CAP_KEYBOARD, LIBINPUT_DEVICE_CAP_POINTER,
|
||||
LIBINPUT_DEVICE_CAP_SWITCH, LIBINPUT_DEVICE_CAP_TABLET_PAD, LIBINPUT_DEVICE_CAP_TABLET_TOOL,
|
||||
LIBINPUT_DEVICE_CAP_TOUCH,
|
||||
};
|
||||
use crate::libinput::device::RegisteredDevice;
|
||||
use crate::libinput::{LibInput, LibInputAdapter, LibInputError};
|
||||
use crate::logind::{LogindError, Session};
|
||||
|
|
@ -25,7 +33,6 @@ use std::future::pending;
|
|||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use uapi::{c, OwnedFd};
|
||||
use crate::libinput::consts::{LIBINPUT_DEVICE_CAP_GESTURE, LIBINPUT_DEVICE_CAP_KEYBOARD, LIBINPUT_DEVICE_CAP_POINTER, LIBINPUT_DEVICE_CAP_SWITCH, LIBINPUT_DEVICE_CAP_TABLET_PAD, LIBINPUT_DEVICE_CAP_TABLET_TOOL, LIBINPUT_DEVICE_CAP_TOUCH};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MetalError {
|
||||
|
|
@ -189,6 +196,12 @@ struct MetalInputDevice {
|
|||
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||
hscroll: Cell<f64>,
|
||||
vscroll: Cell<f64>,
|
||||
|
||||
// config
|
||||
left_handed: Cell<Option<bool>>,
|
||||
accel_profile: Cell<Option<AccelProfile>>,
|
||||
accel_speed: Cell<Option<f64>>,
|
||||
transform_matrix: Cell<Option<[[f64; 2]; 2]>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -223,6 +236,24 @@ impl LibInputAdapter for DeviceHolder {
|
|||
}
|
||||
}
|
||||
|
||||
impl MetalInputDevice {
|
||||
fn apply_config(&self) {
|
||||
let dev = match self.inputdev.get() {
|
||||
Some(dev) => dev,
|
||||
_ => return,
|
||||
};
|
||||
if let Some(lh) = self.left_handed.get() {
|
||||
dev.device().set_left_handed(lh);
|
||||
}
|
||||
if let Some(profile) = self.accel_profile.get() {
|
||||
dev.device().set_accel_profile(profile);
|
||||
}
|
||||
if let Some(speed) = self.accel_speed.get() {
|
||||
dev.device().set_accel_speed(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InputDevice for MetalInputDevice {
|
||||
fn id(&self) -> InputDeviceId {
|
||||
self.id
|
||||
|
|
@ -259,6 +290,35 @@ impl InputDevice for MetalInputDevice {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_left_handed(&self, left_handed: bool) {
|
||||
self.left_handed.set(Some(left_handed));
|
||||
if let Some(dev) = self.inputdev.get() {
|
||||
dev.device().set_left_handed(left_handed);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_accel_profile(&self, profile: InputDeviceAccelProfile) {
|
||||
let profile = match profile {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_accel_speed(&self, speed: f64) {
|
||||
self.accel_speed.set(Some(speed));
|
||||
if let Some(dev) = self.inputdev.get() {
|
||||
dev.device().set_accel_speed(speed);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_transform_matrix(&self, matrix: [[f64; 2]; 2]) {
|
||||
self.transform_matrix.set(Some(matrix));
|
||||
}
|
||||
}
|
||||
|
||||
impl MetalInputDevice {
|
||||
|
|
|
|||
|
|
@ -104,26 +104,28 @@ impl MetalBackend {
|
|||
const PX_PER_SCROLL: f64 = 15.0;
|
||||
const ONE_TWENTRY: f64 = 120.0;
|
||||
let (event, dev) = unpack!(self, event, pointer_event);
|
||||
let hscroll = event.scroll_value_v120(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)
|
||||
/ ONE_TWENTRY
|
||||
+ dev.hscroll.get();
|
||||
let vscroll = event.scroll_value_v120(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) / ONE_TWENTRY
|
||||
+ dev.vscroll.get();
|
||||
let hscroll_used = (PX_PER_SCROLL * hscroll).round();
|
||||
let vscroll_used = (PX_PER_SCROLL * vscroll).round();
|
||||
dev.hscroll.set(hscroll - hscroll_used / PX_PER_SCROLL);
|
||||
dev.vscroll.set(vscroll - vscroll_used / PX_PER_SCROLL);
|
||||
if hscroll_used != 0.0 {
|
||||
dev.event(InputEvent::Scroll(
|
||||
hscroll_used as i32,
|
||||
let axes = [
|
||||
(
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||
&dev.hscroll,
|
||||
ScrollAxis::Horizontal,
|
||||
));
|
||||
}
|
||||
if vscroll_used != 0.0 {
|
||||
dev.event(InputEvent::Scroll(
|
||||
vscroll_used as i32,
|
||||
),
|
||||
(
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
&dev.vscroll,
|
||||
ScrollAxis::Vertical,
|
||||
));
|
||||
),
|
||||
];
|
||||
for (axis, val, sa) in axes {
|
||||
if !event.has_axis(axis) {
|
||||
continue;
|
||||
}
|
||||
let scroll = event.scroll_value_v120(axis) / ONE_TWENTRY + val.get();
|
||||
let scroll_used = (PX_PER_SCROLL * scroll).round();
|
||||
val.set(scroll - scroll_used / PX_PER_SCROLL);
|
||||
if scroll_used != 0.0 {
|
||||
dev.event(InputEvent::Scroll(scroll_used as i32, sa));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +141,12 @@ impl MetalBackend {
|
|||
|
||||
fn handle_pointer_motion(self: &Rc<Self>, event: LibInputEvent) {
|
||||
let (event, dev) = unpack!(self, event, pointer_event);
|
||||
dev.event(InputEvent::Motion(event.dx().into(), event.dy().into()));
|
||||
let mut dx = event.dx();
|
||||
let mut dy = event.dy();
|
||||
if let Some(matrix) = dev.transform_matrix.get() {
|
||||
dx = matrix[0][0] * dx + matrix[0][1] * dy;
|
||||
dy = matrix[1][0] * dx + matrix[1][1] * dy;
|
||||
}
|
||||
dev.event(InputEvent::Motion(dx.into(), dy.into()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ impl MetalBackend {
|
|||
};
|
||||
inputdev.device().set_slot(dev.slot);
|
||||
dev.inputdev.set(Some(inputdev));
|
||||
dev.apply_config();
|
||||
}
|
||||
|
||||
fn handle_device_removed(self: &Rc<Self>, dev: c::dev_t) {
|
||||
|
|
@ -280,6 +281,10 @@ impl MetalBackend {
|
|||
cb: Default::default(),
|
||||
hscroll: Cell::new(0.0),
|
||||
vscroll: Cell::new(0.0),
|
||||
left_handed: Default::default(),
|
||||
accel_profile: Default::default(),
|
||||
accel_speed: Default::default(),
|
||||
transform_matrix: Default::default(),
|
||||
});
|
||||
slots[slot] = Some(dev.clone());
|
||||
self.device_holder
|
||||
|
|
@ -319,6 +324,7 @@ impl MetalBackend {
|
|||
};
|
||||
inputdev.device().set_slot(slot);
|
||||
dev.inputdev.set(Some(inputdev));
|
||||
dev.apply_config();
|
||||
slf.state
|
||||
.backend_events
|
||||
.push(BackendEvent::NewInputDevice(dev.clone()));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use crate::async_engine::{Phase, SpawnedFuture};
|
||||
use crate::backend::{Backend, BackendEvent, InputDevice, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Output, OutputId, ScrollAxis};
|
||||
use crate::backend::{
|
||||
Backend, BackendEvent, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||
InputDeviceId, InputEvent, KeyState, Output, OutputId, ScrollAxis,
|
||||
};
|
||||
use crate::drm::drm::{Drm, DrmError};
|
||||
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
|
||||
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
|
||||
|
|
@ -963,6 +966,22 @@ impl InputDevice for XSeatKeyboard {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_left_handed(&self, left_handed: bool) {
|
||||
let _ = left_handed;
|
||||
}
|
||||
|
||||
fn set_accel_profile(&self, profile: InputDeviceAccelProfile) {
|
||||
let _ = profile;
|
||||
}
|
||||
|
||||
fn set_accel_speed(&self, speed: f64) {
|
||||
let _ = speed;
|
||||
}
|
||||
|
||||
fn set_transform_matrix(&self, matrix: [[f64; 2]; 2]) {
|
||||
let _ = matrix;
|
||||
}
|
||||
}
|
||||
|
||||
impl InputDevice for XSeatMouse {
|
||||
|
|
@ -992,4 +1011,20 @@ impl InputDevice for XSeatMouse {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_left_handed(&self, left_handed: bool) {
|
||||
let _ = left_handed;
|
||||
}
|
||||
|
||||
fn set_accel_profile(&self, profile: InputDeviceAccelProfile) {
|
||||
let _ = profile;
|
||||
}
|
||||
|
||||
fn set_accel_speed(&self, speed: f64) {
|
||||
let _ = speed;
|
||||
}
|
||||
|
||||
fn set_transform_matrix(&self, matrix: [[f64; 2]; 2]) {
|
||||
let _ = matrix;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ use crate::utils::numcell::NumCell;
|
|||
use crate::utils::ptr_ext::PtrExt;
|
||||
use jay_config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
|
||||
use jay_config::_private::{bincode_ops, ConfigEntry, VERSION};
|
||||
use jay_config::input::InputDevice;
|
||||
use jay_config::keyboard::ModifiedKeySym;
|
||||
use jay_config::{Seat};
|
||||
use jay_config::Seat;
|
||||
use libloading::Library;
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use jay_config::input::InputDevice;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ConfigError {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::backend;
|
||||
use crate::backend::{InputDeviceCapability, InputDeviceId};
|
||||
use crate::backend::{InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId};
|
||||
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
|
||||
use crate::state::{DeviceHandlerData, State};
|
||||
use crate::tree::walker::NodeVisitorBase;
|
||||
|
|
@ -13,6 +13,10 @@ use crate::xkbcommon::XkbKeymap;
|
|||
use bincode::error::DecodeError;
|
||||
use jay_config::_private::bincode_ops;
|
||||
use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage};
|
||||
use jay_config::input::{
|
||||
AccelProfile, Capability, InputDevice, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT, CAP_GESTURE,
|
||||
CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, CAP_TABLET_TOOL, CAP_TOUCH,
|
||||
};
|
||||
use jay_config::keyboard::keymap::Keymap;
|
||||
use jay_config::keyboard::mods::Modifiers;
|
||||
use jay_config::keyboard::syms::KeySym;
|
||||
|
|
@ -22,7 +26,6 @@ use log::Level;
|
|||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use jay_config::input::{CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, CAP_TABLET_TOOL, CAP_TOUCH, Capability, InputDevice};
|
||||
|
||||
pub(super) struct ConfigProxyHandler {
|
||||
pub client_data: Cell<*const u8>,
|
||||
|
|
@ -49,9 +52,7 @@ impl ConfigProxyHandler {
|
|||
}
|
||||
|
||||
pub fn respond(&self, msg: Response) {
|
||||
self.send(&ServerMessage::Response {
|
||||
response: msg,
|
||||
})
|
||||
self.send(&ServerMessage::Response { response: msg })
|
||||
}
|
||||
|
||||
fn id(&self) -> u64 {
|
||||
|
|
@ -207,8 +208,58 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_has_capability(&self, device: InputDevice, cap: Capability) -> Result<(), HasCapabilityError> {
|
||||
fn handle_set_left_handed(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
left_handed: bool,
|
||||
) -> Result<(), SetLeftHandedError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
dev.device.set_left_handed(left_handed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_accel_profile(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
accel_profile: AccelProfile,
|
||||
) -> Result<(), SetAccelProfileError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
let profile = match accel_profile {
|
||||
ACCEL_PROFILE_FLAT => InputDeviceAccelProfile::Flat,
|
||||
ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive,
|
||||
_ => return Err(SetAccelProfileError::UnknownAccelProfile(accel_profile)),
|
||||
};
|
||||
dev.device.set_accel_profile(profile);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_accel_speed(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
speed: f64,
|
||||
) -> Result<(), SetAccelSpeedError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
dev.device.set_accel_speed(speed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_transform_matrix(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
matrix: [[f64; 2]; 2],
|
||||
) -> Result<(), SetTransformMatrixError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
dev.device.set_transform_matrix(matrix);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_has_capability(
|
||||
&self,
|
||||
device: InputDevice,
|
||||
cap: Capability,
|
||||
) -> Result<(), HasCapabilityError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
let mut is_unknown = false;
|
||||
let has_cap = 'has_cap: {
|
||||
let cap = match cap {
|
||||
CAP_KEYBOARD => InputDeviceCapability::Keyboard,
|
||||
|
|
@ -218,14 +269,19 @@ impl ConfigProxyHandler {
|
|||
CAP_TABLET_PAD => InputDeviceCapability::TabletPad,
|
||||
CAP_GESTURE => InputDeviceCapability::Gesture,
|
||||
CAP_SWITCH => InputDeviceCapability::Switch,
|
||||
_ => break 'has_cap false,
|
||||
_ => {
|
||||
is_unknown = true;
|
||||
break 'has_cap false;
|
||||
}
|
||||
};
|
||||
dev.device.has_capability(cap)
|
||||
};
|
||||
self.respond(Response::HasCapability {
|
||||
has: has_cap,
|
||||
});
|
||||
Ok(())
|
||||
self.respond(Response::HasCapability { has: has_cap });
|
||||
if is_unknown {
|
||||
Err(HasCapabilityError::UnknownCapability(cap))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_get_mono(&self, seat: Seat) -> Result<(), GetMonoError> {
|
||||
|
|
@ -510,7 +566,22 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::ToggleFloating { seat } => self.handle_toggle_floating(seat)?,
|
||||
ClientMessage::Quit => self.handle_quit(),
|
||||
ClientMessage::SwitchTo { vtnr } => self.handle_switch_to(vtnr),
|
||||
ClientMessage::HasCapability { device, cap } => self.handle_has_capability(device, cap)?,
|
||||
ClientMessage::HasCapability { device, cap } => {
|
||||
self.handle_has_capability(device, cap)?
|
||||
}
|
||||
ClientMessage::SetLeftHanded {
|
||||
device,
|
||||
left_handed,
|
||||
} => self.handle_set_left_handed(device, left_handed)?,
|
||||
ClientMessage::SetAccelProfile { device, profile } => {
|
||||
self.handle_set_accel_profile(device, profile)?
|
||||
}
|
||||
ClientMessage::SetAccelSpeed { device, speed } => {
|
||||
self.handle_set_accel_speed(device, speed)?
|
||||
}
|
||||
ClientMessage::SetTransformMatrix { device, matrix } => {
|
||||
self.handle_set_transform_matrix(device, matrix)?
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -560,6 +631,14 @@ enum CphError {
|
|||
SetBorderWidthError(#[from] SetBorderWidthError),
|
||||
#[error("Could not process a `has_capability` request")]
|
||||
HasCapabilityError(#[from] HasCapabilityError),
|
||||
#[error("Could not process a `set_left_handed` request")]
|
||||
SetLeftHandedError(#[from] SetLeftHandedError),
|
||||
#[error("Could not process a `set_accel_profile` request")]
|
||||
SetAccelProfileError(#[from] SetAccelProfileError),
|
||||
#[error("Could not process a `set_accel_speed` request")]
|
||||
SetAccelSpeedError(#[from] SetAccelSpeedError),
|
||||
#[error("Could not process a `set_transform_matrix` request")]
|
||||
SetTransformMatrixError(#[from] SetTransformMatrixError),
|
||||
#[error("Device {0:?} does not exist")]
|
||||
DeviceDoesNotExist(InputDevice),
|
||||
#[error("Device {0:?} does not exist")]
|
||||
|
|
@ -585,10 +664,42 @@ enum SetSeatError {
|
|||
}
|
||||
efrom!(SetSeatError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum SetLeftHandedError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
}
|
||||
efrom!(SetLeftHandedError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum SetAccelProfileError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
#[error("Tried to set an unknown accel profile: {}", (.0).0)]
|
||||
UnknownAccelProfile(AccelProfile),
|
||||
}
|
||||
efrom!(SetAccelProfileError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum SetAccelSpeedError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
}
|
||||
efrom!(SetAccelSpeedError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum SetTransformMatrixError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
}
|
||||
efrom!(SetTransformMatrixError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum HasCapabilityError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
#[error("Queried unknown capability: {}", (.0).0)]
|
||||
UnknownCapability(Capability),
|
||||
}
|
||||
efrom!(HasCapabilityError, CphError);
|
||||
|
||||
|
|
|
|||
|
|
@ -150,3 +150,19 @@ cenum! {
|
|||
LIBINPUT_EVENT_GESTURE_HOLD_END = 807,
|
||||
LIBINPUT_EVENT_SWITCH_TOGGLE = 900,
|
||||
}
|
||||
|
||||
cenum! {
|
||||
ConfigStatus, LIBINPUT_CONFIG_STATUS;
|
||||
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS = 0,
|
||||
LIBINPUT_CONFIG_STATUS_UNSUPPORTED = 1,
|
||||
LIBINPUT_CONFIG_STATUS_INVALID = 2,
|
||||
}
|
||||
|
||||
cenum! {
|
||||
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE;
|
||||
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_NONE = 0,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT = 1 << 0,
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE = 1 << 1,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
use crate::libinput::sys::{libinput_device, libinput_device_get_user_data, libinput_device_has_capability, libinput_device_set_user_data, libinput_device_unref, libinput_path_remove_device};
|
||||
use crate::libinput::consts::{AccelProfile, DeviceCapability};
|
||||
use crate::libinput::sys::{
|
||||
libinput_device, libinput_device_config_accel_set_profile,
|
||||
libinput_device_config_accel_set_speed, libinput_device_config_left_handed_set,
|
||||
libinput_device_get_user_data, libinput_device_has_capability, libinput_device_set_user_data,
|
||||
libinput_device_unref, libinput_path_remove_device,
|
||||
};
|
||||
use crate::libinput::LibInput;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use crate::libinput::consts::{DeviceCapability};
|
||||
|
||||
pub struct LibInputDevice<'a> {
|
||||
pub(super) dev: *mut libinput_device,
|
||||
|
|
@ -42,6 +47,24 @@ impl<'a> LibInputDevice<'a> {
|
|||
let res = unsafe { libinput_device_has_capability(self.dev, cap.raw() as _) };
|
||||
res != 0
|
||||
}
|
||||
|
||||
pub fn set_left_handed(&self, left_handed: bool) {
|
||||
unsafe {
|
||||
libinput_device_config_left_handed_set(self.dev, left_handed as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_accel_profile(&self, profile: AccelProfile) {
|
||||
unsafe {
|
||||
libinput_device_config_accel_set_profile(self.dev, profile.raw() as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_accel_speed(&self, speed: f64) {
|
||||
unsafe {
|
||||
libinput_device_config_accel_set_speed(self.dev, speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisteredDevice {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::libinput::sys::{
|
|||
libinput_event_pointer, libinput_event_pointer_get_button,
|
||||
libinput_event_pointer_get_button_state, libinput_event_pointer_get_dx,
|
||||
libinput_event_pointer_get_dy, libinput_event_pointer_get_scroll_value_v120,
|
||||
libinput_event_pointer_get_time_usec,
|
||||
libinput_event_pointer_get_time_usec, libinput_event_pointer_has_axis,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
|
@ -108,6 +108,10 @@ impl<'a> LibInputEventPointer<'a> {
|
|||
unsafe { libinput_event_pointer_get_scroll_value_v120(self.event, axis.raw() as _) }
|
||||
}
|
||||
|
||||
pub fn has_axis(&self, axis: PointerAxis) -> bool {
|
||||
unsafe { libinput_event_pointer_has_axis(self.event, axis.raw() as _) != 0 }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn time_usec(&self) -> u64 {
|
||||
unsafe { libinput_event_pointer_get_time_usec(self.event) }
|
||||
|
|
|
|||
|
|
@ -38,7 +38,22 @@ extern "C" {
|
|||
path: *const c::c_char,
|
||||
) -> *mut libinput_device;
|
||||
pub fn libinput_path_remove_device(device: *mut libinput_device);
|
||||
pub fn libinput_device_has_capability(device: *mut libinput_device, cap: libinput_device_capability) -> c::c_int;
|
||||
pub fn libinput_device_has_capability(
|
||||
device: *mut libinput_device,
|
||||
cap: libinput_device_capability,
|
||||
) -> 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_set_profile(
|
||||
device: *mut libinput_device,
|
||||
profile: libinput_config_accel_profile,
|
||||
) -> libinput_config_status;
|
||||
pub fn libinput_device_config_accel_set_speed(
|
||||
device: *mut libinput_device,
|
||||
speed: f64,
|
||||
) -> libinput_config_status;
|
||||
|
||||
pub fn libinput_event_destroy(event: *mut libinput_event);
|
||||
pub fn libinput_event_get_type(event: *mut libinput_event) -> libinput_event_type;
|
||||
|
|
@ -67,6 +82,10 @@ extern "C" {
|
|||
event: *mut libinput_event_pointer,
|
||||
axis: libinput_pointer_axis,
|
||||
) -> f64;
|
||||
pub fn libinput_event_pointer_has_axis(
|
||||
event: *mut libinput_event_pointer,
|
||||
axis: libinput_pointer_axis,
|
||||
) -> c::c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
|
|||
|
|
@ -551,6 +551,7 @@ impl ContainerNode {
|
|||
fn compute_render_data(&self) {
|
||||
self.compute_render_data_scheduled.set(false);
|
||||
let mut rd = self.render_data.borrow_mut();
|
||||
let rd = rd.deref_mut();
|
||||
let theme = &self.state.theme;
|
||||
let th = theme.title_height.get();
|
||||
let bw = theme.border_width.get();
|
||||
|
|
@ -564,6 +565,19 @@ impl ContainerNode {
|
|||
rd.active_title_rects.clear();
|
||||
rd.border_rects.clear();
|
||||
rd.underline_rects.clear();
|
||||
let mut render_title = |title: &str, width: i32, x: i32, y: i32| {
|
||||
if th == 0 || width == 0 || title.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(ctx) = &ctx {
|
||||
match text::render(ctx, width, th, &font, title, Color::GREY) {
|
||||
Ok(t) => rd.titles.push(ContainerTitle { x, y, tex: t }),
|
||||
Err(e) => {
|
||||
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if self.mono_child.get().is_some() {
|
||||
let content_width = self.width.get().sub(bw * (num_children - 1)).max(0);
|
||||
let space_per_child = content_width / num_children;
|
||||
|
|
@ -585,19 +599,8 @@ impl ContainerNode {
|
|||
} else {
|
||||
rd.title_rects.push(rect);
|
||||
}
|
||||
if let Some(ctx) = &ctx {
|
||||
let title = c.title.borrow_mut();
|
||||
match text::render(ctx, width, th, &font, &title, Color::GREY) {
|
||||
Ok(t) => rd.titles.push(ContainerTitle {
|
||||
x: pos,
|
||||
y: 0,
|
||||
tex: t,
|
||||
}),
|
||||
Err(e) => {
|
||||
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
let title = c.title.borrow_mut();
|
||||
render_title(&title, width, pos, 0);
|
||||
pos += width + bw;
|
||||
}
|
||||
rd.underline_rects
|
||||
|
|
@ -623,19 +626,8 @@ impl ContainerNode {
|
|||
}
|
||||
let rect = Rect::new_sized(body.x1(), body.y1() - 1, body.width(), 1).unwrap();
|
||||
rd.underline_rects.push(rect);
|
||||
if let Some(ctx) = &ctx {
|
||||
let title = c.title.borrow_mut();
|
||||
match text::render(ctx, body.width(), th, &font, &title, Color::GREY) {
|
||||
Ok(t) => rd.titles.push(ContainerTitle {
|
||||
x: body.x1(),
|
||||
y: body.y1() - th - 1,
|
||||
tex: t,
|
||||
}),
|
||||
Err(e) => {
|
||||
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
let title = c.title.borrow_mut();
|
||||
render_title(&title, body.width(), body.x1(), body.y1() - th - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ impl FloatNode {
|
|||
let title = self.title.borrow_mut();
|
||||
self.title_texture.set(None);
|
||||
let pos = self.position.get();
|
||||
if pos.width() <= 2 * bw {
|
||||
if pos.width() <= 2 * bw || th == 0 || title.is_empty() {
|
||||
return;
|
||||
}
|
||||
let ctx = match self.state.render_ctx.get() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue