Set keyboard LEDs (capslock, numlock, scrollock)
It doesn't seem there's currently a way to iterate over input devices, so this adds a `Vec` of libinput keyboard devices. When run with the kms backend. Not the most elegant solution, but it doesn't seem practical to add a type generic to `Devices` given how backends are handled, and `Device` can't be made into a trait object. Another trait could be added, but this is fine, and technically should perform better (but if it actually had to iterate over many keyboards, something has gone very wrong).
This commit is contained in:
parent
a8846ed2b8
commit
a204197e6d
2 changed files with 37 additions and 7 deletions
|
|
@ -33,7 +33,7 @@ use smithay::{
|
|||
},
|
||||
desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType},
|
||||
input::{
|
||||
keyboard::{FilterResult, KeysymHandle, XkbConfig},
|
||||
keyboard::{FilterResult, KeysymHandle, LedState, XkbConfig},
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, CursorImageStatus, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
|
||||
|
|
@ -76,7 +76,11 @@ pub struct SupressedKeys(RefCell<Vec<(Keycode, Option<RegistrationToken>)>>);
|
|||
#[derive(Default, Debug)]
|
||||
pub struct ModifiersShortcutQueue(RefCell<Option<KeyPattern>>);
|
||||
#[derive(Default)]
|
||||
pub struct Devices(RefCell<HashMap<String, Vec<DeviceCapability>>>);
|
||||
pub struct Devices {
|
||||
capabilities: RefCell<HashMap<String, Vec<DeviceCapability>>>,
|
||||
// Used for updating keyboard leds on kms backend
|
||||
keyboards: RefCell<Vec<InputDevice>>,
|
||||
}
|
||||
|
||||
impl Default for SeatId {
|
||||
fn default() -> SeatId {
|
||||
|
|
@ -138,9 +142,9 @@ impl ModifiersShortcutQueue {
|
|||
}
|
||||
|
||||
impl Devices {
|
||||
fn add_device<D: Device>(&self, device: &D) -> Vec<DeviceCapability> {
|
||||
fn add_device<D: Device + 'static>(&self, device: &D) -> Vec<DeviceCapability> {
|
||||
let id = device.id();
|
||||
let mut map = self.0.borrow_mut();
|
||||
let mut map = self.capabilities.borrow_mut();
|
||||
let caps = [
|
||||
DeviceCapability::Keyboard,
|
||||
DeviceCapability::Pointer,
|
||||
|
|
@ -156,22 +160,41 @@ impl Devices {
|
|||
.filter(|c| map.values().flatten().all(|has| *c != *has))
|
||||
.collect::<Vec<_>>();
|
||||
map.insert(id, caps);
|
||||
|
||||
if device.has_capability(DeviceCapability::Keyboard) {
|
||||
if let Some(device) = <dyn Any>::downcast_ref::<InputDevice>(device) {
|
||||
self.keyboards.borrow_mut().push(device.clone());
|
||||
}
|
||||
}
|
||||
|
||||
new_caps
|
||||
}
|
||||
|
||||
pub fn has_device<D: Device>(&self, device: &D) -> bool {
|
||||
self.0.borrow().contains_key(&device.id())
|
||||
self.capabilities.borrow().contains_key(&device.id())
|
||||
}
|
||||
|
||||
fn remove_device<D: Device>(&self, device: &D) -> Vec<DeviceCapability> {
|
||||
let id = device.id();
|
||||
let mut map = self.0.borrow_mut();
|
||||
|
||||
let mut keyboards = self.keyboards.borrow_mut();
|
||||
if let Some(idx) = keyboards.iter().position(|x| x.id() == id) {
|
||||
keyboards.remove(idx);
|
||||
}
|
||||
|
||||
let mut map = self.capabilities.borrow_mut();
|
||||
map.remove(&id)
|
||||
.unwrap_or(Vec::new())
|
||||
.into_iter()
|
||||
.filter(|c| map.values().flatten().all(|has| *c != *has))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn update_led_state(&self, led_state: LedState) {
|
||||
for keyboard in self.keyboards.borrow_mut().iter_mut() {
|
||||
keyboard.led_update(led_state.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_seat(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
input::Devices,
|
||||
shell::focus::target::{KeyboardFocusTarget, PointerFocusTarget},
|
||||
state::State,
|
||||
};
|
||||
use smithay::{
|
||||
delegate_seat,
|
||||
input::{pointer::CursorImageStatus, SeatHandler, SeatState},
|
||||
input::{keyboard::LedState, pointer::CursorImageStatus, SeatHandler, SeatState},
|
||||
reexports::wayland_server::Resource,
|
||||
wayland::{
|
||||
seat::WaylandFocus, selection::data_device::set_data_device_focus,
|
||||
|
|
@ -49,6 +50,12 @@ impl SeatHandler for State {
|
|||
set_primary_focus(dh, seat, Some(client))
|
||||
}
|
||||
}
|
||||
|
||||
fn led_state_changed(&mut self, seat: &smithay::input::Seat<Self>, led_state: LedState) {
|
||||
let userdata = seat.user_data();
|
||||
let devices = userdata.get::<Devices>().unwrap();
|
||||
devices.update_led_state(led_state);
|
||||
}
|
||||
}
|
||||
|
||||
delegate_seat!(State);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue