diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index d18bc4b277..31b53e29d4 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -824,7 +824,7 @@ impl X11Client { Event::XkbStateNotify(event) => { let mut state = self.0.borrow_mut(); state.xkb.update_mask( - event.base_mods.into(), + dbg!(event).base_mods.into(), event.latched_mods.into(), event.locked_mods.into(), event.base_group as u32, @@ -836,7 +836,7 @@ impl X11Client { latched_layout: event.latched_group as u32, locked_layout: event.locked_group.into(), }; - let modifiers = Modifiers::from_xkb(&state.xkb); + let modifiers = dbg!(Modifiers::from_xkb(&state.xkb)); if state.modifiers == modifiers { drop(state); } else { @@ -919,7 +919,7 @@ impl X11Client { })); } Event::KeyRelease(event) => { - let window = self.get_window(event.event)?; + let window = self.get_window(dbg!(event).event)?; let mut state = self.0.borrow_mut(); let modifiers = modifiers_from_state(event.state); diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 2d896f2ee8..d86cf3ae8b 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -3216,24 +3216,11 @@ impl<'a> WindowContext<'a> { self.draw(); } - let node_id = self - .window - .focus - .and_then(|focus_id| { - self.window - .rendered_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id()); - let dispatch_path = self .window .rendered_frame .dispatch_tree - .dispatch_path(node_id); - - let mut keystroke: Option = None; + .dispatch_path(self.focused_node_id()); if let Some(event) = event.downcast_ref::() { if event.modifiers.number_of_modifiers() == 0 @@ -3249,30 +3236,36 @@ impl<'a> WindowContext<'a> { _ => None, }; if let Some(key) = key { - keystroke = Some(Keystroke { + let keystroke = Keystroke { key: key.to_string(), ime_key: None, modifiers: Modifiers::default(), - }); + }; + self.finish_dispatch_keystroke(keystroke, &dispatch_path); } } if self.window.pending_modifier.modifiers.number_of_modifiers() == 0 && event.modifiers.number_of_modifiers() == 1 { - self.window.pending_modifier.saw_keystroke = false + self.window.pending_modifier.saw_keystroke = false; } - self.window.pending_modifier.modifiers = event.modifiers + self.window.pending_modifier.modifiers = event.modifiers; + + self.finish_dispatch_key_event(event, &dispatch_path); } else if let Some(key_down_event) = event.downcast_ref::() { self.window.pending_modifier.saw_keystroke = true; - keystroke = Some(key_down_event.keystroke.clone()); + self.finish_dispatch_keystroke(key_down_event.keystroke.clone(), &dispatch_path); + } else { + self.finish_dispatch_key_event(event, &dispatch_path); } + } - let Some(keystroke) = keystroke else { - self.finish_dispatch_key_event(event, dispatch_path); - return; - }; - + fn finish_dispatch_keystroke( + &self, + keystroke: Keystroke, + dispatch_path: &SmallVec<[DispatchNodeId; 32]>, + ) { let mut currently_pending = self.window.pending_input.take().unwrap_or_default(); if currently_pending.focus.is_some() && currently_pending.focus != self.window.focus { currently_pending = PendingInput::default(); @@ -3306,7 +3299,8 @@ impl<'a> WindowContext<'a> { .window .rendered_frame .dispatch_tree - .dispatch_path(node_id); + // FIXME: valid? + .dispatch_path(cx.focused_node_id()); let to_replay = cx .window @@ -3334,13 +3328,13 @@ impl<'a> WindowContext<'a> { } } - self.finish_dispatch_key_event(event, dispatch_path) + self.finish_dispatch_key_event(event, &dispatch_path) } fn finish_dispatch_key_event( &mut self, event: &dyn Any, - dispatch_path: SmallVec<[DispatchNodeId; 32]>, + dispatch_path: &SmallVec<[DispatchNodeId; 32]>, ) { self.dispatch_key_down_up_event(event, &dispatch_path); if !self.propagate_event { diff --git a/crates/tab_switcher/src/tab_switcher.rs b/crates/tab_switcher/src/tab_switcher.rs index 8c961dc54d..a4cd6f9a55 100644 --- a/crates/tab_switcher/src/tab_switcher.rs +++ b/crates/tab_switcher/src/tab_switcher.rs @@ -372,7 +372,7 @@ impl PickerDelegate for TabSwitcherDelegate { icon.color(git_status_color.unwrap_or_default()) }); - let indicator = render_item_indicator(tab_match.item.boxed_clone(), cx); + let indicator = render_item_indicator(tab_match.item.boxed_clone(), None, cx); let indicator_color = if let Some(ref indicator) = indicator { indicator.color } else { diff --git a/crates/ui/src/components/indicator.rs b/crates/ui/src/components/indicator.rs index 009fe44dfe..ec18ea821e 100644 --- a/crates/ui/src/components/indicator.rs +++ b/crates/ui/src/components/indicator.rs @@ -7,6 +7,7 @@ enum IndicatorKind { Dot, Bar, Icon(AnyIcon), + Character(char), } #[derive(IntoElement)] @@ -37,12 +38,18 @@ impl Indicator { } } + pub fn character(character: char) -> Self { + Self { + kind: IndicatorKind::Character(character), + color: Color::Default, + } + } + pub fn color(mut self, color: Color) -> Self { self.color = color; self } } - impl RenderOnce for Indicator { fn render(self, cx: &mut WindowContext) -> impl IntoElement { let container = div().flex_none(); @@ -60,6 +67,9 @@ impl RenderOnce for Indicator { .h_1p5() .rounded_t_md() .bg(self.color.color(cx)), + IndicatorKind::Character(character) => container + .text_color(self.color.color(cx)) + .child(character.to_string()), } } } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index c205f2a8e5..4dea589c0b 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1835,6 +1835,18 @@ impl Pane { focus_handle: &FocusHandle, cx: &mut ViewContext<'_, Pane>, ) -> impl IntoElement { + let pending_keystrokes = cx.pending_input_keystrokes().unwrap_or(&[]); + let char_to_type = cx.bindings_for_action(&ActivateItem(ix)).iter().find_map( + |keybinding| match keybinding.remaining_keystrokes(pending_keystrokes) { + Some([keystroke]) + if keystroke.modifiers == cx.modifiers() && keystroke.key.len() == 1 => + { + keystroke.key.chars().next() + } + _ => None, + }, + ); + let project_path = item.project_path(cx); let is_active = ix == self.active_item_index; @@ -1866,7 +1878,7 @@ impl Pane { let icon = item.tab_icon(cx); let close_side = &ItemSettings::get_global(cx).close_position; - let indicator = render_item_indicator(item.boxed_clone(), cx); + let indicator = render_item_indicator(item.boxed_clone(), char_to_type, cx); let item_id = item.item_id(); let is_first_item = ix == 0; let is_last_item = ix == self.items.len() - 1; @@ -2997,16 +3009,22 @@ pub fn tab_details(items: &[Box], cx: &AppContext) -> Vec tab_details } -pub fn render_item_indicator(item: Box, cx: &WindowContext) -> Option { - maybe!({ - let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) { - (true, _) => Color::Warning, - (_, true) => Color::Accent, - (false, false) => return None, - }; +pub fn render_item_indicator( + item: Box, + char_to_type: Option, + cx: &WindowContext, +) -> Option { + if let Some(char) = char_to_type { + return Some(Indicator::character(char)); + } - Some(Indicator::dot().color(indicator_color)) - }) + let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) { + (true, _) => Color::Warning, + (_, true) => Color::Accent, + (false, false) => return None, + }; + + Some(Indicator::dot().color(indicator_color)) } impl Render for DraggedTab {