From 2eeede1efb939fa9f5710c58df5462748d7f0b36 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Tue, 19 Aug 2025 21:21:01 -0700 Subject: [PATCH] Oh no, focus is hard --- crates/gpui/src/interactive.rs | 8 ++++++++ crates/onboarding/src/editing_page.rs | 1 + crates/ui_input/src/numeric_stepper.rs | 24 ++++++++++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/interactive.rs b/crates/gpui/src/interactive.rs index 218ae5fcdf..dafe623dfa 100644 --- a/crates/gpui/src/interactive.rs +++ b/crates/gpui/src/interactive.rs @@ -259,6 +259,14 @@ impl ClickEvent { ClickEvent::Mouse(event) => event.up.click_count, } } + + /// Returns whether the click event is generated by a keyboard event + pub fn is_keyboard(&self) -> bool { + match self { + ClickEvent::Mouse(_) => false, + ClickEvent::Keyboard(_) => true, + } + } } /// An enum representing the keyboard button that was pressed for a click event. diff --git a/crates/onboarding/src/editing_page.rs b/crates/onboarding/src/editing_page.rs index ce509ea843..f248ee6bdb 100644 --- a/crates/onboarding/src/editing_page.rs +++ b/crates/onboarding/src/editing_page.rs @@ -445,6 +445,7 @@ fn font_picker_stepper( optimistic_font_size.write(cx, Some(*new_value)); write_font_size(Pixels::from(*new_value), cx); }) + .format(|value| format!("{value}px")) .style(ui_input::NumericStepperStyle::Outlined) .tab_index({ *tab_index += 2; diff --git a/crates/ui_input/src/numeric_stepper.rs b/crates/ui_input/src/numeric_stepper.rs index 382c344fba..8601840368 100644 --- a/crates/ui_input/src/numeric_stepper.rs +++ b/crates/ui_input/src/numeric_stepper.rs @@ -278,14 +278,13 @@ impl RenderOnce for NumericStepper { let decrement_handler = { let value = self.value.clone(); let on_change = self.on_change.clone(); - let focus = self.focus_handle.clone(); let min = self.min_value; move |click: &ClickEvent, window: &mut Window, cx: &mut App| { let step = get_step(click.modifiers()); let new_value = value - step; let new_value = if new_value < min { min } else { new_value }; on_change(&new_value, window, cx); - window.focus(&focus); + window.focus_prev(); } }; @@ -332,11 +331,16 @@ impl RenderOnce for NumericStepper { NumericStepperMode::Read => div() .id("numeric_stepper_label") .child(Label::new((self.format)(&self.value)).mx_3()) + .when_some(tab_index.as_mut(), |this, tab_index| { + *tab_index += 1; + this.tab_index(*tab_index - 1).focus(|style| { + style.bg(cx.theme().colors().element_hover) + }) + }) .on_click({ let mode = self.mode.clone(); - move |click, _, cx| { - if click.click_count() == 2 { + if click.click_count() == 2 || click.is_keyboard() { mode.write(cx, NumericStepperMode::Edit); } } @@ -348,6 +352,7 @@ impl RenderOnce for NumericStepper { NumericStepperMode::Edit => div() .child(window.use_state(cx, { |window, cx| { + let previous_focus_handle = window.focused(cx); let mut editor = Editor::single_line(window, cx); editor.set_text(format!("{}", self.value), window, cx); @@ -368,6 +373,11 @@ impl RenderOnce for NumericStepper { new_value }; + if let Some(previous) = + previous_focus_handle.as_ref() + { + window.focus(previous); + } on_change(&new_value, window, cx); }; mode.write(cx, NumericStepperMode::Read); @@ -381,9 +391,8 @@ impl RenderOnce for NumericStepper { } })) .on_action::({ - let focus = self.focus_handle.clone(); move |_, window, _| { - window.focus(&focus); + window.blur(); } }) .size_full() @@ -396,7 +405,6 @@ impl RenderOnce for NumericStepper { .map(|increment| { let increment_handler = { let value = self.value.clone(); - let focus = self.focus_handle.clone(); let on_change = self.on_change.clone(); let max = self.max_value; move |click: &ClickEvent, window: &mut Window, cx: &mut App| { @@ -404,7 +412,7 @@ impl RenderOnce for NumericStepper { let new_value = value + step; let new_value = if new_value > max { max } else { new_value }; on_change(&new_value, window, cx); - window.focus(&focus); + // window.focus(&focus); } };