diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index 6cff977128ec594d683085e5f2cc24683c9e9ba7..ac40f551b75bc7469726c6fc2a6ef6a1ad00a1f9 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -141,13 +141,6 @@ impl From for EventHandlerError { } } -#[derive(Debug, Default, Clone)] -struct XKBStateNotiy { - depressed_layout: LayoutIndex, - latched_layout: LayoutIndex, - locked_layout: LayoutIndex, -} - #[derive(Debug, Default)] pub struct Xdnd { other_window: xproto::Window, @@ -200,7 +193,6 @@ pub struct X11ClientState { pub(crate) mouse_focused_window: Option, pub(crate) keyboard_focused_window: Option, pub(crate) xkb: xkbc::State, - previous_xkb_state: XKBStateNotiy, keyboard_layout: LinuxKeyboardLayout, pub(crate) ximc: Option>>, pub(crate) xim_handler: Option, @@ -507,7 +499,6 @@ impl X11Client { mouse_focused_window: None, keyboard_focused_window: None, xkb: xkb_state, - previous_xkb_state: XKBStateNotiy::default(), keyboard_layout, ximc, xim_handler, @@ -959,14 +950,6 @@ impl X11Client { state.xkb_device_id, ) }; - let depressed_layout = xkb_state.serialize_layout(xkbc::STATE_LAYOUT_DEPRESSED); - let latched_layout = xkb_state.serialize_layout(xkbc::STATE_LAYOUT_LATCHED); - let locked_layout = xkb_state.serialize_layout(xkbc::ffi::XKB_STATE_LAYOUT_LOCKED); - state.previous_xkb_state = XKBStateNotiy { - depressed_layout, - latched_layout, - locked_layout, - }; state.xkb = xkb_state; drop(state); self.handle_keyboard_layout_change(); @@ -983,12 +966,6 @@ impl X11Client { event.latched_group as u32, event.locked_group.into(), ); - state.previous_xkb_state = XKBStateNotiy { - depressed_layout: event.base_group as u32, - latched_layout: event.latched_group as u32, - locked_layout: event.locked_group.into(), - }; - let modifiers = Modifiers::from_xkb(&state.xkb); let capslock = Capslock::from_xkb(&state.xkb); if state.last_modifiers_changed_event == modifiers @@ -1021,24 +998,41 @@ impl X11Client { let mut state = self.0.borrow_mut(); let modifiers = modifiers_from_state(event.state); - state.modifiers = modifiers; + state.modifiers = modifiers; // i think we should remove this too state.pre_key_char_down.take(); let keystroke = { let code = event.detail.into(); - let xkb_state = state.previous_xkb_state.clone(); - state.xkb.update_mask( - event.state.bits() as ModMask, - 0, - 0, - xkb_state.depressed_layout, - xkb_state.latched_layout, - xkb_state.locked_layout, - ); - let mut keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code); - let keysym = state.xkb.key_get_one_sym(code); + let keysym = { + let temp_xkb = xkbc::x11::state_new_from_device( + state.xkb.get_keymap(), + &state.xcb_connection, + state.xkb_device_id, + ); + let mask = event.state.bits() as xkbc::ModMask; + let depressed = temp_xkb.serialize_mods(xkbc::STATE_MODS_DEPRESSED) & mask; + let latched = temp_xkb.serialize_mods(xkbc::STATE_MODS_LATCHED) & mask; + let locked = temp_xkb.serialize_mods(xkbc::STATE_MODS_LOCKED) & mask; + let unassigned = mask & ~(depressed | latched | locked); + let depressed = depressed | unassigned; + let group = ((event.state >> 13) & 3) as u32; + temp_xkb.update_mask( + depressed, + latched, + locked, + 0, + 0, + group, + ); + temp_xkb.key_get_one_sym(code) + }; + if keysym.is_modifier_key() { return Some(()); } + + let mut keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code); + keystroke.key = xkbc::keysym_get_name(keysym).to_string(); + if let Some(mut compose_state) = state.compose_state.take() { compose_state.feed(keysym); match compose_state.status() { @@ -1089,25 +1083,37 @@ impl X11Client { let mut state = self.0.borrow_mut(); let modifiers = modifiers_from_state(event.state); - state.modifiers = modifiers; + state.modifiers = modifiers; // we should remove this too let keystroke = { let code = event.detail.into(); - let xkb_state = state.previous_xkb_state.clone(); - state.xkb.update_mask( - event.state.bits() as ModMask, + let temp_xkb = xkbc::x11::state_new_from_device( + state.xkb.get_keymap(), + &state.xcb_connection, + state.xkb_device_id, + ); + let mask = event.state.bits() as xkbc::ModMask; + let depressed = temp_xkb.serialize_mods(xkbc::STATE_MODS_DEPRESSED) & mask; + let latched = temp_xkb.serialize_mods(xkbc::STATE_MODS_LATCHED) & mask; + let locked = temp_xkb.serialize_mods(xkbc::STATE_MODS_LOCKED) & mask; + let unassigned = mask & ~(depressed | latched | locked); + let depressed = depressed | unassigned; + + let group = ((event.state >> 13) & 3) as u32; + + temp_xkb.update_mask( + depressed, + latched, + locked, 0, 0, - xkb_state.depressed_layout, - xkb_state.latched_layout, - xkb_state.locked_layout, + group, ); - let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code); let keysym = state.xkb.key_get_one_sym(code); if keysym.is_modifier_key() { return Some(()); } - keystroke + crate::Keystroke::from_xkb(&state.xkb, modifiers, code) }; drop(state); window.handle_input(PlatformInput::KeyUp(crate::KeyUpEvent { keystroke }));