fix all

Junkui Zhang created

Change summary

crates/gpui/src/platform/linux/platform.rs       | 12 +++---
crates/gpui/src/platform/linux/wayland/client.rs | 28 +++++++++++---
crates/gpui/src/platform/linux/x11/client.rs     | 34 ++++++++++++++++-
3 files changed, 58 insertions(+), 16 deletions(-)

Detailed changes

crates/gpui/src/platform/linux/platform.rs 🔗

@@ -712,13 +712,14 @@ pub(super) fn log_cursor_icon_warning(message: impl std::fmt::Display) {
 #[cfg(any(feature = "wayland", feature = "x11"))]
 impl crate::Keystroke {
     pub(super) fn from_xkb(
-        keyboard_state: &State,
+        state: &State,
+        keyboard_mapper: &LinuxKeyboardMapper,
         mut modifiers: crate::Modifiers,
         keycode: Keycode,
     ) -> Self {
-        let key_utf32 = keyboard_state.key_get_utf32(keycode);
-        let key_utf8 = keyboard_state.key_get_utf8(keycode);
-        let key_sym = keyboard_state.key_get_one_sym(keycode);
+        let key_utf32 = state.key_get_utf32(keycode);
+        let key_utf8 = state.key_get_utf8(keycode);
+        let key_sym = state.key_get_one_sym(keycode);
 
         let key = match key_sym {
             Keysym::space => "space".to_owned(),
@@ -770,8 +771,7 @@ impl crate::Keystroke {
             Keysym::F22 => "f22".to_owned(),
             Keysym::F23 => "f23".to_owned(),
             Keysym::F24 => "f24".to_owned(),
-            _ => keyboard_state
-                .mapper
+            _ => keyboard_mapper
                 .get_key(keycode, &mut modifiers)
                 .unwrap_or_else(|| {
                     let name = xkb::keysym_get_name(key_sym).to_lowercase();

crates/gpui/src/platform/linux/wayland/client.rs 🔗

@@ -73,10 +73,11 @@ use super::{
 use crate::{
     AnyWindowHandle, Bounds, Capslock, CursorStyle, DOUBLE_CLICK_INTERVAL, DevicePixels, DisplayId,
     FileDropEvent, ForegroundExecutor, KeyDownEvent, KeyUpEvent, Keystroke, LinuxCommon,
-    LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
-    MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay,
-    PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScaledPixels, ScrollDelta,
-    ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px, size,
+    LinuxKeyboardLayout, LinuxKeyboardMapper, Modifiers, ModifiersChangedEvent, MouseButton,
+    MouseDownEvent, MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels,
+    PlatformDisplay, PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScaledPixels,
+    ScrollDelta, ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px,
+    size,
 };
 use crate::{
     KeyboardState, SharedString,
@@ -215,6 +216,7 @@ pub(crate) struct WaylandClientState {
     keyboard_layout: LinuxKeyboardLayout,
     keymap_state: Option<State>,
     compose_state: Option<xkb::compose::State>,
+    keyboard_mapper: Option<LinuxKeyboardMapper>,
     drag: DragState,
     click: ClickState,
     repeat: KeyRepeat,
@@ -574,6 +576,7 @@ impl WaylandClient {
             keyboard_layout: LinuxKeyboardLayout::new(UNKNOWN_KEYBOARD_LAYOUT_NAME),
             keymap_state: None,
             compose_state: None,
+            keyboard_mapper: None,
             drag: DragState {
                 data_offer: None,
                 window: None,
@@ -1217,6 +1220,7 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
                 };
                 state.keymap_state = Some(xkb::State::new(&keymap));
                 state.compose_state = get_xkb_compose_state(&xkb_context);
+                state.keyboard_mapper = Some(LinuxKeyboardMapper::new());
                 drop(state);
 
                 this.handle_keyboard_layout_change();
@@ -1293,13 +1297,18 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
                 let focused_window = focused_window.clone();
 
                 let keymap_state = state.keymap_state.as_ref().unwrap();
+                let keyboard_mapper = state.keyboard_mapper.as_ref().unwrap();
                 let keycode = Keycode::from(key + MIN_KEYCODE);
                 let keysym = keymap_state.key_get_one_sym(keycode);
 
                 match key_state {
                     wl_keyboard::KeyState::Pressed if !keysym.is_modifier_key() => {
-                        let mut keystroke =
-                            Keystroke::from_xkb(&keymap_state, state.modifiers, keycode);
+                        let mut keystroke = Keystroke::from_xkb(
+                            keymap_state,
+                            keyboard_mapper,
+                            state.modifiers,
+                            keycode,
+                        );
                         println!("Wayland Before {:#?}", keystroke);
                         if let Some(mut compose) = state.compose_state.take() {
                             compose.feed(keysym);
@@ -1386,7 +1395,12 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
                     }
                     wl_keyboard::KeyState::Released if !keysym.is_modifier_key() => {
                         let input = PlatformInput::KeyUp(KeyUpEvent {
-                            keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
+                            keystroke: Keystroke::from_xkb(
+                                keymap_state,
+                                keyboard_mapper,
+                                state.modifiers,
+                                keycode,
+                            ),
                         });
 
                         if state.repeat.current_keycode == Some(keycode) {

crates/gpui/src/platform/linux/x11/client.rs 🔗

@@ -1,7 +1,9 @@
 use crate::{
-    platform::{xcb_flush, Capslock},
+    
+    LinuxKeyboardMapper, platform::{xcb_flush, Capslock},
     scap_screen_capture::scap_screen_sources,
     underlying_dead_key,
+,
 };
 use core::str;
 use std::{
@@ -204,6 +206,7 @@ pub struct X11ClientState {
     pub(crate) xkb: State,
     previous_xkb_state: XKBStateNotiy,
     keyboard_layout: LinuxKeyboardLayout,
+    pub(crate) keyboard_mapper: LinuxKeyboardMapper,
     pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
     pub(crate) xim_handler: Option<XimHandler>,
     pub modifiers: Modifiers,
@@ -423,6 +426,7 @@ impl X11Client {
             .layout_get_name(layout_idx)
             .to_string();
         let keyboard_layout = LinuxKeyboardLayout::new(layout_name.into());
+        let keyboard_mapper = LinuxKeyboardMapper::new();
 
         let gpu_context = BladeContext::new().context("Unable to init GPU context")?;
 
@@ -516,6 +520,7 @@ impl X11Client {
             xkb: xkb_state,
             previous_xkb_state: XKBStateNotiy::default(),
             keyboard_layout,
+            keyboard_mapper,
             ximc,
             xim_handler,
 
@@ -977,6 +982,18 @@ impl X11Client {
                 state.xkb = xkb_state;
                 drop(state);
                 self.handle_keyboard_layout_change();
+                state.keyboard_mapper = LinuxKeyboardMapper::new();
+                let layout_idx = state.xkb.serialize_layout(STATE_LAYOUT_EFFECTIVE);
+                let layout = LinuxKeyboardLayout::new(
+                    state
+                        .xkb
+                        .get_keymap()
+                        .layout_get_name(layout_idx)
+                        .to_string(),
+                )
+                .id()
+                .to_string();
+                println!("X11 Keyboard layout: {:#?}", layout);
             }
             Event::XkbStateNotify(event) => {
                 let mut state = self.0.borrow_mut();
@@ -1041,7 +1058,12 @@ impl X11Client {
                         xkb_state.latched_layout,
                         xkb_state.locked_layout,
                     );
-                    let mut keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
+                    let mut keystroke = crate::Keystroke::from_xkb(
+                        &state.xkb,
+                        &state.keyboard_mapper,
+                        modifiers,
+                        code,
+                    );
                     let keysym = state.xkb.key_get_one_sym(code);
                     if keysym.is_modifier_key() {
                         return Some(());
@@ -1114,7 +1136,12 @@ impl X11Client {
                         xkb_state.latched_layout,
                         xkb_state.locked_layout,
                     );
-                    let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
+                    let keystroke = crate::Keystroke::from_xkb(
+                        &state.xkb,
+                        &state.keyboard_mapper,
+                        modifiers,
+                        code,
+                    );
                     let keysym = state.xkb.key_get_one_sym(code);
                     if keysym.is_modifier_key() {
                         return Some(());
@@ -1337,6 +1364,7 @@ impl X11Client {
                 let mut state = self.0.borrow_mut();
                 state.pre_key_char_down = Some(Keystroke::from_xkb(
                     &state.xkb,
+                    &state.keyboard_mapper,
                     state.modifiers,
                     event.detail.into(),
                 ));