mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
Fix WlKeyboard reference cycles
This commit is contained in:
parent
ac7c22af58
commit
077205065e
2 changed files with 18 additions and 5 deletions
|
@ -18,6 +18,8 @@ pub use xkbcommon::xkb::{self, keysyms, Keycode, Keysym};
|
|||
|
||||
use super::{GrabStatus, Seat, SeatHandler};
|
||||
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
use wayland_server::Weak;
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
mod keymap_file;
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
|
@ -167,7 +169,7 @@ unsafe impl<D: SeatHandler> Send for KbdInternal<D> {}
|
|||
|
||||
impl<D: SeatHandler + 'static> KbdInternal<D> {
|
||||
fn new(xkb_config: XkbConfig<'_>, repeat_rate: i32, repeat_delay: i32) -> Result<KbdInternal<D>, ()> {
|
||||
// we create a new contex for each keyboard because libxkbcommon is actually NOT threadsafe
|
||||
// we create a new context for each keyboard because libxkbcommon is actually NOT threadsafe
|
||||
// so confining it inside the KbdInternal allows us to use Rusts mutability rules to make
|
||||
// sure nothing goes wrong.
|
||||
//
|
||||
|
@ -280,7 +282,7 @@ pub(crate) struct KbdRc<D: SeatHandler> {
|
|||
#[cfg(feature = "wayland_frontend")]
|
||||
pub(crate) keymap: Mutex<KeymapFile>,
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
pub(crate) known_kbds: Mutex<Vec<wayland_server::protocol::wl_keyboard::WlKeyboard>>,
|
||||
pub(crate) known_kbds: Mutex<Vec<Weak<wayland_server::protocol::wl_keyboard::WlKeyboard>>>,
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
pub(crate) last_enter: Mutex<Option<Serial>>,
|
||||
pub(crate) span: tracing::Span,
|
||||
|
@ -695,6 +697,10 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
|
|||
// Update keymap for every wl_keyboard.
|
||||
let known_kbds = &self.arc.known_kbds;
|
||||
for kbd in &*known_kbds.lock().unwrap() {
|
||||
let Ok(kbd) = kbd.upgrade() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let res = keymap_file.with_fd(kbd.version() >= 7, |fd, size| {
|
||||
kbd.keymap(KeymapFormat::XkbV1, fd.as_fd(), size as u32)
|
||||
});
|
||||
|
@ -1042,13 +1048,16 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
|
|||
guard.repeat_rate = rate;
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
for kbd in &*self.arc.known_kbds.lock().unwrap() {
|
||||
let Ok(kbd) = kbd.upgrade() else {
|
||||
continue;
|
||||
};
|
||||
kbd.repeat_info(rate, delay);
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the [`Serial`] of the last `keyboard_enter` event, if that focus is still active.
|
||||
///
|
||||
/// In other words this will return `None` again, once a `keyboard_leave` occured.
|
||||
/// In other words this will return `None` again, once a `keyboard_leave` occurred.
|
||||
#[cfg(feature = "wayland_frontend")]
|
||||
pub fn last_enter(&self) -> Option<Serial> {
|
||||
*self.arc.last_enter.lock().unwrap()
|
||||
|
@ -1175,7 +1184,7 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
|
|||
keyboard_handle.send_keymap(data, &Some(focus), &keymap_file, mods);
|
||||
}
|
||||
|
||||
// key event must be sent before modifers event for libxkbcommon
|
||||
// key event must be sent before modifiers event for libxkbcommon
|
||||
// to process them correctly
|
||||
let key = KeysymHandle {
|
||||
keycode: (keycode + 8).into(),
|
||||
|
|
|
@ -78,7 +78,7 @@ where
|
|||
);
|
||||
}
|
||||
}
|
||||
self.arc.known_kbds.lock().unwrap().push(kbd);
|
||||
self.arc.known_kbds.lock().unwrap().push(kbd.downgrade());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +141,10 @@ pub(crate) fn for_each_focused_kbds<D: SeatHandler + 'static>(
|
|||
if let Some(keyboard) = seat.get_keyboard() {
|
||||
let inner = keyboard.arc.known_kbds.lock().unwrap();
|
||||
for kbd in &*inner {
|
||||
let Ok(kbd) = kbd.upgrade() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if kbd.id().same_client_as(&surface.id()) {
|
||||
f(kbd.clone())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue