From ad3d44119a5fad347aa813b6281b0cf102b6841a Mon Sep 17 00:00:00 2001 From: Junkui Zhang <364772080@qq.com> Date: Thu, 22 May 2025 14:20:22 +0800 Subject: [PATCH] fix all --- crates/gpui/src/platform/linux/platform.rs | 12 +++---- .../gpui/src/platform/linux/wayland/client.rs | 28 +++++++++++---- crates/gpui/src/platform/linux/x11/client.rs | 34 +++++++++++++++++-- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/crates/gpui/src/platform/linux/platform.rs b/crates/gpui/src/platform/linux/platform.rs index 0786fdd5c96b6d8070455b27ab077e9e9508a26a..95abb557a1bacd91ad4a3629ac24789e0fddc57a 100644 --- a/crates/gpui/src/platform/linux/platform.rs +++ b/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(); diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index d485202c6949be3fc9ce15e840fab5a77d7a5931..32b4f1bbeb87365a4a8239baf46252346c1bfffd 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/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, compose_state: Option, + keyboard_mapper: Option, 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 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 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 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) { diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index 0f572596608f670a7ebbad251ce9d9f5f547b6b8..a01df9da6735fb5e871f61a63c4c6ab0a4c40432 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/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>>, pub(crate) xim_handler: Option, 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(), ));