Handle locks (Caps/Num/Scroll)

Assume server is authoritative re ModifiersEvent
This commit is contained in:
VassiliDev
2024-11-26 16:30:01 -05:00
committed by Ferdinand Schober
parent 345804355a
commit 68d6d89510

View File

@@ -223,7 +223,12 @@ impl VirtualInput {
if mods.from_key_event(key, state) { if mods.from_key_event(key, state) {
log::trace!("Key triggers modifier change"); log::trace!("Key triggers modifier change");
log::trace!("Modifiers: {:?}", mods); log::trace!("Modifiers: {:?}", mods);
self.keyboard.modifiers(mods.bits(), 0, 0, 0); self.keyboard.modifiers(
mods.mask_pressed().bits(),
0,
mods.mask_locks().bits(),
0,
);
} }
} }
} }
@@ -233,6 +238,11 @@ impl VirtualInput {
locked: mods_locked, locked: mods_locked,
group, group,
} => { } => {
// Synchronize internal modifier state, assuming server is authoritative
if let Ok(mut mods) = self.modifiers.lock() {
mods.from_mods_event(e);
log::trace!("Modifiers: {:?}", mods);
}
self.keyboard self.keyboard
.modifiers(mods_depressed, mods_latched, mods_locked, group); .modifiers(mods_depressed, mods_latched, mods_locked, group);
} }
@@ -311,29 +321,58 @@ bitflags! {
} }
impl XMods { impl XMods {
fn from_mods_event(&mut self, evt: KeyboardEvent) {
match evt {
KeyboardEvent::Modifiers {
depressed, locked, ..
} => {
*self = XMods::from_bits_truncate(depressed) | XMods::from_bits_truncate(locked);
}
_ => {}
}
}
fn from_key_event(&mut self, key: u32, state: u8) -> bool { fn from_key_event(&mut self, key: u32, state: u8) -> bool {
if let Ok(key) = scancode::Linux::try_from(key) { if let Ok(key) = scancode::Linux::try_from(key) {
log::trace!("Attempting to process modifier from: {:#?}", key); log::trace!("Attempting to process modifier from: {:#?}", key);
let mask = match key { let pressed_mask = match key {
scancode::Linux::KeyLeftShift | scancode::Linux::KeyRightShift => XMods::ShiftMask, scancode::Linux::KeyLeftShift | scancode::Linux::KeyRightShift => XMods::ShiftMask,
scancode::Linux::KeyCapsLock => XMods::LockMask,
scancode::Linux::KeyLeftCtrl | scancode::Linux::KeyRightCtrl => XMods::ControlMask, scancode::Linux::KeyLeftCtrl | scancode::Linux::KeyRightCtrl => XMods::ControlMask,
scancode::Linux::KeyLeftAlt | scancode::Linux::KeyRightalt => XMods::Mod1Mask, scancode::Linux::KeyLeftAlt | scancode::Linux::KeyRightalt => XMods::Mod1Mask,
scancode::Linux::KeyLeftMeta | scancode::Linux::KeyRightmeta => XMods::Mod4Mask, scancode::Linux::KeyLeftMeta | scancode::Linux::KeyRightmeta => XMods::Mod4Mask,
_ => XMods::empty(), _ => XMods::empty(),
}; };
let locked_mask = match key {
scancode::Linux::KeyCapsLock => XMods::LockMask,
scancode::Linux::KeyNumlock => XMods::Mod2Mask,
scancode::Linux::KeyScrollLock => XMods::Mod3Mask,
_ => XMods::empty(),
};
// unchanged // unchanged
if mask.is_empty() { if pressed_mask.is_empty() && locked_mask.is_empty() {
log::trace!("{:#?} is not a modifier key", key); log::trace!("{:#?} is not a modifier key", key);
return false; return false;
} }
match state { match state {
1 => self.insert(mask), 1 => self.insert(pressed_mask),
_ => self.remove(mask), _ => {
self.remove(pressed_mask);
self.toggle(locked_mask);
}
} }
true true
} else { } else {
false false
} }
} }
fn mask_locks(&self) -> XMods {
*self & (XMods::LockMask | XMods::Mod2Mask | XMods::Mod3Mask)
}
fn mask_pressed(&self) -> XMods {
*self & (XMods::ShiftMask | XMods::ControlMask | XMods::Mod1Mask | XMods::Mod4Mask)
}
} }