diff --git a/crates/gpui/src/platform/linux/keyboard.rs b/crates/gpui/src/platform/linux/keyboard.rs index 8cb32eb9349fe834412468aebdd11991e94f0a90..1f60f8d12494dc863ae4ce6ba024ef7f33983c3b 100644 --- a/crates/gpui/src/platform/linux/keyboard.rs +++ b/crates/gpui/src/platform/linux/keyboard.rs @@ -34,12 +34,6 @@ impl LinuxKeyboardLayout { pub(crate) fn new(name: SharedString) -> Self { Self { name } } - - pub(crate) fn unknown() -> Self { - Self { - id: "unknown".to_string(), - } - } } #[cfg(any(feature = "wayland", feature = "x11"))] diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index 9f112f3603c6b96bf11a51f1366ee159886d5264..3b49ad1f47b2520eddb3a7bc21fadc298aa351bf 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -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, in_progress_outputs: HashMap, - keyboard_layout: LinuxKeyboardLayout, keymap_state: Option, compose_state: Option, - keyboard_layout: Box, + keyboard_layout: LinuxKeyboardLayout, keyboard_mapper: Option>, keyboard_mapper_cache: HashMap>, 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::(&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 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 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 } } } - -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); -} diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index 9cbdfa3c1f9f418daf07dfc9a4da3e19b6689cb3..da2fe3293805f388662b739c2bc9175a01f6062e 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -203,12 +203,11 @@ pub struct X11ClientState { pub(crate) windows: HashMap, pub(crate) mouse_focused_window: Option, pub(crate) keyboard_focused_window: Option, - pub(crate) xkb: State, + pub(crate) xkb: xkbc::State, previous_xkb_state: XKBStateNotiy, keyboard_layout: LinuxKeyboardLayout, - pub(crate) keyboard_layout: Box, - pub(crate) keyboard_mapper: Rc, - pub(crate) keyboard_mapper_cache: HashMap>, + keyboard_mapper: Rc, + keyboard_mapper_cache: HashMap>, pub(crate) ximc: Option>>, pub(crate) xim_handler: Option, 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); -}