seat: after keymap change, only send keymap to focused surface
This commit is contained in:
parent
8d43eebc3d
commit
225995eb2f
5 changed files with 45 additions and 30 deletions
|
|
@ -163,6 +163,7 @@ pub struct WlSeatGlobal {
|
||||||
constraint: CloneCell<Option<Rc<SeatConstraint>>>,
|
constraint: CloneCell<Option<Rc<SeatConstraint>>>,
|
||||||
idle_notifications: CopyHashMap<(ClientId, ExtIdleNotificationV1Id), Rc<ExtIdleNotificationV1>>,
|
idle_notifications: CopyHashMap<(ClientId, ExtIdleNotificationV1Id), Rc<ExtIdleNotificationV1>>,
|
||||||
last_input_usec: Cell<u64>,
|
last_input_usec: Cell<u64>,
|
||||||
|
keymap_version: NumCell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||||
|
|
@ -219,6 +220,7 @@ impl WlSeatGlobal {
|
||||||
idle_notifications: Default::default(),
|
idle_notifications: Default::default(),
|
||||||
last_input_usec: Cell::new(now_usec()),
|
last_input_usec: Cell::new(now_usec()),
|
||||||
wlr_data_devices: Default::default(),
|
wlr_data_devices: Default::default(),
|
||||||
|
keymap_version: NumCell::new(1),
|
||||||
});
|
});
|
||||||
state.add_cursor_size(*DEFAULT_CURSOR_SIZE);
|
state.add_cursor_size(*DEFAULT_CURSOR_SIZE);
|
||||||
let seat = slf.clone();
|
let seat = slf.clone();
|
||||||
|
|
@ -513,24 +515,12 @@ impl WlSeatGlobal {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
self.keyboard_node.get().node_on_unfocus(self);
|
||||||
self.kb_map.set(keymap.clone());
|
self.kb_map.set(keymap.clone());
|
||||||
*self.kb_state.borrow_mut() = state;
|
*self.kb_state.borrow_mut() = state;
|
||||||
let bindings = self.bindings.borrow_mut();
|
self.keymap_version.fetch_add(1);
|
||||||
for (id, client) in bindings.iter() {
|
self.pressed_keys.borrow_mut().clear();
|
||||||
for seat in client.values() {
|
self.keyboard_node.get().node_on_focus(self);
|
||||||
let kbs = seat.keyboards.lock();
|
|
||||||
for kb in kbs.values() {
|
|
||||||
let fd = match seat.keymap_fd(keymap) {
|
|
||||||
Ok(fd) => fd,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("Could not creat a file descriptor to transfer the keymap to client {}: {}", id, ErrorFmt(e));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
kb.send_keymap(wl_keyboard::XKB_V1, fd, keymap.map_len as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_for_lock(self: &Rc<Self>) {
|
pub fn prepare_for_lock(self: &Rc<Self>) {
|
||||||
|
|
@ -1180,12 +1170,13 @@ impl WlSeatRequestHandler for WlSeat {
|
||||||
track!(self.client, p);
|
track!(self.client, p);
|
||||||
self.client.add_client_obj(&p)?;
|
self.client.add_client_obj(&p)?;
|
||||||
self.keyboards.set(req.id, p.clone());
|
self.keyboards.set(req.id, p.clone());
|
||||||
let keymap = self.global.kb_map.get();
|
p.send_keymap();
|
||||||
p.send_keymap(
|
if let Some(surface) = self.global.keyboard_node.get().node_into_surface() {
|
||||||
wl_keyboard::XKB_V1,
|
if surface.client.id == self.client.id {
|
||||||
self.keymap_fd(&keymap)?,
|
let serial = self.client.next_serial();
|
||||||
keymap.map_len as _,
|
p.send_enter(serial, surface.id, &self.global.pressed_keys.borrow())
|
||||||
);
|
}
|
||||||
|
}
|
||||||
if self.version >= REPEAT_INFO_SINCE {
|
if self.version >= REPEAT_INFO_SINCE {
|
||||||
let (rate, delay) = self.global.repeat_rate.get();
|
let (rate, delay) = self.global.repeat_rate.get();
|
||||||
p.send_repeat_info(rate, delay);
|
p.send_repeat_info(rate, delay);
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,11 @@ use {
|
||||||
ifs::wl_seat::WlSeat,
|
ifs::wl_seat::WlSeat,
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
utils::oserror::OsError,
|
utils::{errorfmt::ErrorFmt, numcell::NumCell, oserror::OsError},
|
||||||
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
|
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
uapi::OwnedFd,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const REPEAT_INFO_SINCE: Version = Version(4);
|
pub const REPEAT_INFO_SINCE: Version = Version(4);
|
||||||
|
|
@ -24,6 +23,7 @@ pub(super) const PRESSED: u32 = 1;
|
||||||
pub struct WlKeyboard {
|
pub struct WlKeyboard {
|
||||||
id: WlKeyboardId,
|
id: WlKeyboardId,
|
||||||
seat: Rc<WlSeat>,
|
seat: Rc<WlSeat>,
|
||||||
|
pub(super) keymap_version: NumCell<u32>,
|
||||||
pub tracker: Tracker<Self>,
|
pub tracker: Tracker<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,20 +32,38 @@ impl WlKeyboard {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
seat: seat.clone(),
|
seat: seat.clone(),
|
||||||
|
keymap_version: NumCell::new(0),
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_keymap(self: &Rc<Self>, format: u32, fd: Rc<OwnedFd>, size: u32) {
|
pub fn send_keymap(&self) {
|
||||||
|
let map = self.seat.global.kb_map.get();
|
||||||
|
let fd = match self.seat.keymap_fd(&map) {
|
||||||
|
Ok(fd) => fd,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!(
|
||||||
|
"Could not creat a file descriptor to transfer the keymap to client {}: {}",
|
||||||
|
self.seat.client.id,
|
||||||
|
ErrorFmt(e)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
self.seat.client.event(Keymap {
|
self.seat.client.event(Keymap {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
format,
|
format: XKB_V1,
|
||||||
fd,
|
fd,
|
||||||
size,
|
size: map.map_len as _,
|
||||||
})
|
});
|
||||||
|
self.keymap_version
|
||||||
|
.set(self.seat.global.keymap_version.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_enter(self: &Rc<Self>, serial: u32, surface: WlSurfaceId, keys: &[u32]) {
|
pub fn send_enter(self: &Rc<Self>, serial: u32, surface: WlSurfaceId, keys: &[u32]) {
|
||||||
|
if self.keymap_version.get() != self.seat.global.keymap_version.get() {
|
||||||
|
self.send_keymap();
|
||||||
|
}
|
||||||
self.seat.client.event(Enter {
|
self.seat.client.event(Enter {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
serial,
|
serial,
|
||||||
|
|
|
||||||
|
|
@ -1399,7 +1399,7 @@ impl Node for WlSurface {
|
||||||
seat.scroll_surface(&self, event);
|
seat.scroll_surface(&self, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_on_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
fn node_on_focus(self: Rc<Self>, seat: &WlSeatGlobal) {
|
||||||
if let Some(tl) = self.toplevel.get() {
|
if let Some(tl) = self.toplevel.get() {
|
||||||
tl.tl_data().focus_node.insert(seat.id(), self.clone());
|
tl.tl_data().focus_node.insert(seat.id(), self.clone());
|
||||||
tl.tl_on_activate();
|
tl.tl_on_activate();
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ pub trait Node: 'static {
|
||||||
let _ = event;
|
let _ = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_on_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
fn node_on_focus(self: Rc<Self>, seat: &WlSeatGlobal) {
|
||||||
let _ = seat;
|
let _ = seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,12 @@ impl<T> Deref for VecSet<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> VecSet<T> {
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.vec.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> VecSet<T> {
|
impl<T: PartialEq> VecSet<T> {
|
||||||
pub fn insert(&mut self, val: T) -> bool {
|
pub fn insert(&mut self, val: T) -> bool {
|
||||||
if self.vec.contains(&val) {
|
if self.vec.contains(&val) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue