@@ -80,7 +80,7 @@ use crate::{
size,
};
use crate::{
- KeyboardState, SharedString,
+ SharedString,
platform::linux::{
LinuxClient, get_xkb_compose_state, is_within_click_distance, open_uri_internal, read_fd,
reveal_path_internal,
@@ -213,10 +213,9 @@ pub(crate) struct WaylandClientState {
// Output to scale mapping
outputs: HashMap<ObjectId, Output>,
in_progress_outputs: HashMap<ObjectId, InProgressOutput>,
- keyboard_layout: LinuxKeyboardLayout,
keymap_state: Option<State>,
compose_state: Option<xkb::compose::State>,
- keyboard_layout: Box<LinuxKeyboardLayout>,
+ keyboard_layout: LinuxKeyboardLayout,
keyboard_mapper: Option<Rc<LinuxKeyboardMapper>>,
keyboard_mapper_cache: HashMap<String, Rc<LinuxKeyboardMapper>>,
drag: DragState,
@@ -368,6 +367,13 @@ impl WaylandClientStatePtr {
changed
};
if changed {
+ let id = state.keyboard_layout.id().to_string();
+ let mapper = state
+ .keyboard_mapper_cache
+ .entry(id)
+ .or_insert(Rc::new(LinuxKeyboardMapper::new(0, 0, 0)))
+ .clone();
+ state.keyboard_mapper = Some(mapper);
if let Some(mut callback) = state.common.callbacks.keyboard_layout_change.take() {
drop(state);
callback();
@@ -455,7 +461,7 @@ impl WaylandClient {
pub(crate) fn new() -> Self {
let conn = Connection::connect_to_env().unwrap();
- let keyboard_layout = Box::new(LinuxKeyboardLayout::unknown());
+ let keyboard_layout = LinuxKeyboardLayout::new(UNKNOWN_KEYBOARD_LAYOUT_NAME);
let (globals, mut event_queue) =
registry_queue_init::<WaylandClientStatePtr>(&conn).unwrap();
let qh = event_queue.handle();
@@ -576,12 +582,11 @@ impl WaylandClient {
in_progress_outputs,
windows: HashMap::default(),
common,
- keyboard_layout: LinuxKeyboardLayout::new(UNKNOWN_KEYBOARD_LAYOUT_NAME),
keymap_state: None,
compose_state: None,
+ keyboard_layout,
keyboard_mapper: None,
keyboard_mapper_cache: HashMap::default(),
- keyboard_layout,
drag: DragState {
data_offer: None,
window: None,
@@ -1222,11 +1227,8 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
.flatten()
.expect("Failed to create keymap")
};
- let keymap_state = xkb::State::new(&keymap);
- let keyboard_layout = LinuxKeyboardLayout::new(&keymap_state);
- state.keymap_state = Some(keymap_state);
+ state.keymap_state = Some(xkb::State::new(&keymap));
state.compose_state = get_xkb_compose_state(&xkb_context);
- update_keyboard_mapper(&mut state, keyboard_layout, 0);
drop(state);
this.handle_keyboard_layout_change();
@@ -1271,8 +1273,8 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
keymap_state.serialize_layout(xkbcommon::xkb::STATE_LAYOUT_EFFECTIVE);
keymap_state.update_mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
state.modifiers = Modifiers::from_xkb(keymap_state);
- state.capslock = Capslock::from_xkb(&keymap_state);
let keymap_state = state.keymap_state.as_mut().unwrap();
+ state.capslock = Capslock::from_xkb(keymap_state);
let input = PlatformInput::ModifiersChanged(ModifiersChangedEvent {
modifiers: state.modifiers,
@@ -2179,19 +2181,3 @@ impl Dispatch<zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1, ()>
}
}
}
-
-fn update_keyboard_mapper(
- client: &mut WaylandClientState,
- keyboard_layout: LinuxKeyboardLayout,
- group: u32,
-) {
- let id = keyboard_layout.id().to_string();
- let mapper = client
- .keyboard_mapper_cache
- .entry(id)
- .or_insert(Rc::new(LinuxKeyboardMapper::new(0, 0, group)))
- .clone();
-
- client.keyboard_mapper = Some(mapper);
- client.keyboard_layout = Box::new(keyboard_layout);
-}
@@ -203,12 +203,11 @@ pub struct X11ClientState {
pub(crate) windows: HashMap<xproto::Window, WindowRef>,
pub(crate) mouse_focused_window: Option<xproto::Window>,
pub(crate) keyboard_focused_window: Option<xproto::Window>,
- pub(crate) xkb: State,
+ pub(crate) xkb: xkbc::State,
previous_xkb_state: XKBStateNotiy,
keyboard_layout: LinuxKeyboardLayout,
- pub(crate) keyboard_layout: Box<LinuxKeyboardLayout>,
- pub(crate) keyboard_mapper: Rc<LinuxKeyboardMapper>,
- pub(crate) keyboard_mapper_cache: HashMap<String, Rc<LinuxKeyboardMapper>>,
+ keyboard_mapper: Rc<LinuxKeyboardMapper>,
+ keyboard_mapper_cache: HashMap<String, Rc<LinuxKeyboardMapper>>,
pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
pub(crate) xim_handler: Option<XimHandler>,
pub modifiers: Modifiers,
@@ -428,7 +427,6 @@ impl X11Client {
.layout_get_name(layout_idx)
.to_string();
let keyboard_layout = LinuxKeyboardLayout::new(layout_name.into());
- let keyboard_layout = Box::new(LinuxKeyboardLayout::new(&xkb_state));
let keyboard_mapper = Rc::new(LinuxKeyboardMapper::new(0, 0, 0));
let keyboard_mapper_cache = HashMap::default();
@@ -984,17 +982,9 @@ impl X11Client {
latched_layout,
locked_layout,
};
- let keyboard_layout = LinuxKeyboardLayout::new(&xkb_state);
state.xkb = xkb_state;
drop(state);
- self.handle_keyboard_layout_change();
- update_keyboard_mapper(
- &mut state,
- keyboard_layout,
- depressed_layout,
- latched_layout,
- locked_layout,
- );
+ self.handle_keyboard_layout_change(depressed_layout, latched_layout, locked_layout);
}
Event::XkbStateNotify(event) => {
let mut state = self.0.borrow_mut();
@@ -1017,8 +1007,8 @@ impl X11Client {
locked_layout: locked_group,
};
- let modifiers = Modifiers::from_xkb(&state.keyboard_state.state);
- let capslock = Capslock::from_xkb(&state.keyboard_state.state);
+ let modifiers = Modifiers::from_xkb(&state.xkb);
+ let capslock = Capslock::from_xkb(&state.xkb);
if state.last_modifiers_changed_event == modifiers
&& state.last_capslock_changed_event == capslock
{
@@ -1041,7 +1031,7 @@ impl X11Client {
}
if new_layout != old_layout {
- self.handle_keyboard_layout_change();
+ self.handle_keyboard_layout_change(base_group, latched_group, locked_group);
}
}
Event::KeyPress(event) => {
@@ -1447,13 +1437,28 @@ impl X11Client {
Some(())
}
- fn handle_keyboard_layout_change(&self) {
+ fn handle_keyboard_layout_change(
+ &self,
+ base_group: u32,
+ latched_group: u32,
+ locked_group: u32,
+ ) {
let mut state = self.0.borrow_mut();
let layout_idx = state.xkb.serialize_layout(STATE_LAYOUT_EFFECTIVE);
let keymap = state.xkb.get_keymap();
let layout_name = keymap.layout_get_name(layout_idx);
if layout_name != state.keyboard_layout.name() {
state.keyboard_layout = LinuxKeyboardLayout::new(layout_name.to_string().into());
+ let mapper = state
+ .keyboard_mapper_cache
+ .entry(layout_name.to_string())
+ .or_insert(Rc::new(LinuxKeyboardMapper::new(
+ base_group,
+ latched_group,
+ locked_group,
+ )))
+ .clone();
+ state.keyboard_mapper = mapper;
if let Some(mut callback) = state.common.callbacks.keyboard_layout_change.take() {
drop(state);
callback();
@@ -2307,25 +2312,3 @@ fn create_invisible_cursor(
xcb_flush(connection);
Ok(cursor)
}
-
-fn update_keyboard_mapper(
- client: &mut X11ClientState,
- keyboard_layout: LinuxKeyboardLayout,
- base_group: u32,
- latched_group: u32,
- locked_group: u32,
-) {
- let id = keyboard_layout.id().to_string();
- let mapper = client
- .keyboard_mapper_cache
- .entry(id)
- .or_insert(Rc::new(LinuxKeyboardMapper::new(
- base_group,
- latched_group,
- locked_group,
- )))
- .clone();
-
- client.keyboard_mapper = mapper;
- client.keyboard_layout = Box::new(keyboard_layout);
-}