mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-14 21:41:28 +03:00
Keep modifier state in WLRoots input emulator
This commit is contained in:
committed by
Ferdinand Schober
parent
2e2046dc36
commit
345804355a
@@ -25,6 +25,7 @@ tokio = { version = "1.32.0", features = [
|
|||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os="macos")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os="macos")))'.dependencies]
|
||||||
|
bitflags = "2.6.0"
|
||||||
wayland-client = { version = "0.31.1", optional = true }
|
wayland-client = { version = "0.31.1", optional = true }
|
||||||
wayland-protocols = { version = "0.32.1", features = [
|
wayland-protocols = { version = "0.32.1", features = [
|
||||||
"client",
|
"client",
|
||||||
@@ -42,6 +43,8 @@ ashpd = { version = "0.10", default-features = false, features = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
reis = { version = "0.4", features = ["tokio"], optional = true }
|
reis = { version = "0.4", features = ["tokio"], optional = true }
|
||||||
|
keycode = "0.4.0"
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
bitflags = "2.6.0"
|
bitflags = "2.6.0"
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ use crate::error::EmulationError;
|
|||||||
|
|
||||||
use super::{error::WlrootsEmulationCreationError, Emulation};
|
use super::{error::WlrootsEmulationCreationError, Emulation};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use bitflags::bitflags;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::fd::{AsFd, OwnedFd};
|
use std::os::fd::{AsFd, OwnedFd};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use wayland_client::backend::WaylandError;
|
use wayland_client::backend::WaylandError;
|
||||||
use wayland_client::WEnum;
|
use wayland_client::WEnum;
|
||||||
@@ -29,7 +31,7 @@ use wayland_client::{
|
|||||||
Connection, Dispatch, EventQueue, QueueHandle,
|
Connection, Dispatch, EventQueue, QueueHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use input_event::{Event, KeyboardEvent, PointerEvent};
|
use input_event::{scancode, Event, KeyboardEvent, PointerEvent};
|
||||||
|
|
||||||
use super::error::WaylandBindError;
|
use super::error::WaylandBindError;
|
||||||
use super::EmulationHandle;
|
use super::EmulationHandle;
|
||||||
@@ -103,7 +105,11 @@ impl State {
|
|||||||
panic!("no keymap");
|
panic!("no keymap");
|
||||||
}
|
}
|
||||||
|
|
||||||
let vinput = VirtualInput { pointer, keyboard };
|
let vinput = VirtualInput {
|
||||||
|
pointer,
|
||||||
|
keyboard,
|
||||||
|
modifiers: Arc::new(Mutex::new(XMods::empty())),
|
||||||
|
};
|
||||||
|
|
||||||
self.input_for_client.insert(client, vinput);
|
self.input_for_client.insert(client, vinput);
|
||||||
}
|
}
|
||||||
@@ -174,6 +180,7 @@ impl Emulation for WlrootsEmulation {
|
|||||||
struct VirtualInput {
|
struct VirtualInput {
|
||||||
pointer: Vp,
|
pointer: Vp,
|
||||||
keyboard: Vk,
|
keyboard: Vk,
|
||||||
|
modifiers: Arc<Mutex<XMods>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VirtualInput {
|
impl VirtualInput {
|
||||||
@@ -212,6 +219,13 @@ impl VirtualInput {
|
|||||||
Event::Keyboard(e) => match e {
|
Event::Keyboard(e) => match e {
|
||||||
KeyboardEvent::Key { time, key, state } => {
|
KeyboardEvent::Key { time, key, state } => {
|
||||||
self.keyboard.key(time, key, state as u32);
|
self.keyboard.key(time, key, state as u32);
|
||||||
|
if let Ok(mut mods) = self.modifiers.lock() {
|
||||||
|
if mods.from_key_event(key, state) {
|
||||||
|
log::trace!("Key triggers modifier change");
|
||||||
|
log::trace!("Modifiers: {:?}", mods);
|
||||||
|
self.keyboard.modifiers(mods.bits(), 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
KeyboardEvent::Modifiers {
|
KeyboardEvent::Modifiers {
|
||||||
depressed: mods_depressed,
|
depressed: mods_depressed,
|
||||||
@@ -279,3 +293,47 @@ impl Dispatch<WlSeat, ()> for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From X11/X.h
|
||||||
|
bitflags! {
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
|
struct XMods: u32 {
|
||||||
|
const ShiftMask = (1<<0);
|
||||||
|
const LockMask = (1<<1);
|
||||||
|
const ControlMask = (1<<2);
|
||||||
|
const Mod1Mask = (1<<3);
|
||||||
|
const Mod2Mask = (1<<4);
|
||||||
|
const Mod3Mask = (1<<5);
|
||||||
|
const Mod4Mask = (1<<6);
|
||||||
|
const Mod5Mask = (1<<7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XMods {
|
||||||
|
fn from_key_event(&mut self, key: u32, state: u8) -> bool {
|
||||||
|
if let Ok(key) = scancode::Linux::try_from(key) {
|
||||||
|
log::trace!("Attempting to process modifier from: {:#?}", key);
|
||||||
|
let mask = match key {
|
||||||
|
scancode::Linux::KeyLeftShift | scancode::Linux::KeyRightShift => XMods::ShiftMask,
|
||||||
|
scancode::Linux::KeyCapsLock => XMods::LockMask,
|
||||||
|
scancode::Linux::KeyLeftCtrl | scancode::Linux::KeyRightCtrl => XMods::ControlMask,
|
||||||
|
scancode::Linux::KeyLeftAlt | scancode::Linux::KeyRightalt => XMods::Mod1Mask,
|
||||||
|
scancode::Linux::KeyLeftMeta | scancode::Linux::KeyRightmeta => XMods::Mod4Mask,
|
||||||
|
_ => XMods::empty(),
|
||||||
|
};
|
||||||
|
// unchanged
|
||||||
|
if mask.is_empty() {
|
||||||
|
log::trace!("{:#?} is not a modifier key", key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
match state {
|
||||||
|
1 => self.insert(mask),
|
||||||
|
_ => self.remove(mask),
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user