diff --git a/src/input/mod.rs b/src/input/mod.rs index 3ea64652..593d5603 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -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)>>); #[derive(Default, Debug)] pub struct ModifiersShortcutQueue(RefCell>); #[derive(Default)] -pub struct Devices(RefCell>>); +pub struct Devices { + capabilities: RefCell>>, + // Used for updating keyboard leds on kms backend + keyboards: RefCell>, +} impl Default for SeatId { fn default() -> SeatId { @@ -138,9 +142,9 @@ impl ModifiersShortcutQueue { } impl Devices { - fn add_device(&self, device: &D) -> Vec { + fn add_device(&self, device: &D) -> Vec { 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::>(); map.insert(id, caps); + + if device.has_capability(DeviceCapability::Keyboard) { + if let Some(device) = ::downcast_ref::(device) { + self.keyboards.borrow_mut().push(device.clone()); + } + } + new_caps } pub fn has_device(&self, device: &D) -> bool { - self.0.borrow().contains_key(&device.id()) + self.capabilities.borrow().contains_key(&device.id()) } fn remove_device(&self, device: &D) -> Vec { 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( diff --git a/src/wayland/handlers/seat.rs b/src/wayland/handlers/seat.rs index 929c92cb..6ef87138 100644 --- a/src/wayland/handlers/seat.rs +++ b/src/wayland/handlers/seat.rs @@ -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, led_state: LedState) { + let userdata = seat.user_data(); + let devices = userdata.get::().unwrap(); + devices.update_led_state(led_state); + } } delegate_seat!(State);