From 0025019db431ab7671079baaabaf0de872730160 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 6 Aug 2025 06:15:30 +0800 Subject: [PATCH] gpui: Press `enter`, `space` to trigger click to focused element (#35075) Release Notes: - N/A > Any user interaction that is equivalent to a click, such as pressing the Space key or Enter key while the element is focused. Note that this only applies to elements with a default key event handler, and therefore, excludes other elements that have been made focusable by setting the [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/tabindex) attribute. https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event --------- Co-authored-by: Anthony Co-authored-by: Mikayla Maki Co-authored-by: Umesh Yadav <23421535+imumesh18@users.noreply.github.com> --- crates/agent_ui/src/context_strip.rs | 2 +- crates/collab_ui/src/collab_panel.rs | 2 +- .../src/session/running/variable_list.rs | 2 +- crates/editor/src/editor.rs | 10 +- crates/editor/src/element.rs | 24 ++-- crates/gpui/examples/tab_stop.rs | 20 ++- crates/gpui/examples/window_shadow.rs | 4 +- crates/gpui/src/elements/div.rs | 60 +++++++-- crates/gpui/src/interactive.rs | 123 ++++++++++++++++-- crates/gpui/src/window.rs | 2 + .../src/markdown_preview_view.rs | 2 +- crates/outline_panel/src/outline_panel.rs | 4 +- crates/project_panel/src/project_panel.rs | 16 ++- crates/recent_projects/src/remote_servers.rs | 2 +- crates/settings_ui/src/keybindings.rs | 2 +- crates/settings_ui/src/ui_components/table.rs | 4 +- crates/title_bar/src/platform_title_bar.rs | 4 +- .../ui/src/components/button/button_like.rs | 7 +- crates/workspace/src/pane.rs | 4 +- 19 files changed, 231 insertions(+), 63 deletions(-) diff --git a/crates/agent_ui/src/context_strip.rs b/crates/agent_ui/src/context_strip.rs index 080ffd2ea0..369964f165 100644 --- a/crates/agent_ui/src/context_strip.rs +++ b/crates/agent_ui/src/context_strip.rs @@ -504,7 +504,7 @@ impl Render for ContextStrip { ) .on_click({ Rc::new(cx.listener(move |this, event: &ClickEvent, window, cx| { - if event.down.click_count > 1 { + if event.click_count() > 1 { this.open_context(&context, window, cx); } else { this.focused_index = Some(i); diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index 689591df12..bae5dcfdb5 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -2605,7 +2605,7 @@ impl CollabPanel { let contact = contact.clone(); move |this, event: &ClickEvent, window, cx| { this.deploy_contact_context_menu( - event.down.position, + event.position(), contact.clone(), window, cx, diff --git a/crates/debugger_ui/src/session/running/variable_list.rs b/crates/debugger_ui/src/session/running/variable_list.rs index 906e482687..efbc72e8cf 100644 --- a/crates/debugger_ui/src/session/running/variable_list.rs +++ b/crates/debugger_ui/src/session/running/variable_list.rs @@ -1107,7 +1107,7 @@ impl VariableList { let variable_value = value.clone(); this.on_click(cx.listener( move |this, click: &ClickEvent, window, cx| { - if click.down.click_count < 2 { + if click.click_count() < 2 { return; } let editor = Self::create_variable_editor( diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ff9b703d66..30feca7402 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8183,7 +8183,7 @@ impl Editor { editor.set_breakpoint_context_menu( row, Some(position), - event.down.position, + event.position(), window, cx, ); @@ -8350,7 +8350,11 @@ impl Editor { .icon_color(color) .toggle_state(is_active) .on_click(cx.listener(move |editor, e: &ClickEvent, window, cx| { - let quick_launch = e.down.button == MouseButton::Left; + let quick_launch = match e { + ClickEvent::Keyboard(_) => true, + ClickEvent::Mouse(e) => e.down.button == MouseButton::Left, + }; + window.focus(&editor.focus_handle(cx)); editor.toggle_code_actions( &ToggleCodeActions { @@ -8362,7 +8366,7 @@ impl Editor { ); })) .on_right_click(cx.listener(move |editor, event: &ClickEvent, window, cx| { - editor.set_breakpoint_context_menu(row, position, event.down.position, window, cx); + editor.set_breakpoint_context_menu(row, position, event.position(), window, cx); })) } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 268855ab61..e1647215bc 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -43,11 +43,11 @@ use gpui::{ Bounds, ClickEvent, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero, Keystroke, Length, - ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, - ParentElement, Pixels, ScrollDelta, ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString, - Size, StatefulInteractiveElement, Style, Styled, TextRun, TextStyleRefinement, WeakEntity, - Window, anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px, - quad, relative, size, solid_background, transparent_black, + ModifiersChangedEvent, MouseButton, MouseClickEvent, MouseDownEvent, MouseMoveEvent, + MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollHandle, ScrollWheelEvent, + ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled, TextRun, + TextStyleRefinement, WeakEntity, Window, anchored, deferred, div, fill, linear_color_stop, + linear_gradient, outline, point, px, quad, relative, size, solid_background, transparent_black, }; use itertools::Itertools; use language::language_settings::{ @@ -949,8 +949,12 @@ impl EditorElement { let hovered_link_modifier = Editor::multi_cursor_modifier(false, &event.modifiers(), cx); - if !pending_nonempty_selections && hovered_link_modifier && text_hitbox.is_hovered(window) { - let point = position_map.point_for_position(event.up.position); + if let Some(mouse_position) = event.mouse_position() + && !pending_nonempty_selections + && hovered_link_modifier + && text_hitbox.is_hovered(window) + { + let point = position_map.point_for_position(mouse_position); editor.handle_click_hovered_link(point, event.modifiers(), window, cx); editor.selection_drag_state = SelectionDragState::None; @@ -3735,7 +3739,7 @@ impl EditorElement { move |editor, e: &ClickEvent, window, cx| { editor.open_excerpts_common( Some(jump_data.clone()), - e.down.modifiers.secondary(), + e.modifiers().secondary(), window, cx, ); @@ -6882,10 +6886,10 @@ impl EditorElement { // Fire click handlers during the bubble phase. DispatchPhase::Bubble => editor.update(cx, |editor, cx| { if let Some(mouse_down) = captured_mouse_down.take() { - let event = ClickEvent { + let event = ClickEvent::Mouse(MouseClickEvent { down: mouse_down, up: event.clone(), - }; + }); Self::click(editor, &event, &position_map, window, cx); } }), diff --git a/crates/gpui/examples/tab_stop.rs b/crates/gpui/examples/tab_stop.rs index 1f6500f3e6..8dbcbeccb7 100644 --- a/crates/gpui/examples/tab_stop.rs +++ b/crates/gpui/examples/tab_stop.rs @@ -111,8 +111,24 @@ impl Render for Example { .flex_row() .gap_3() .items_center() - .child(button("el1").tab_index(4).child("Button 1")) - .child(button("el2").tab_index(5).child("Button 2")), + .child( + button("el1") + .tab_index(4) + .child("Button 1") + .on_click(cx.listener(|this, _, _, cx| { + this.message = "You have clicked Button 1.".into(); + cx.notify(); + })), + ) + .child( + button("el2") + .tab_index(5) + .child("Button 2") + .on_click(cx.listener(|this, _, _, cx| { + this.message = "You have clicked Button 2.".into(); + cx.notify(); + })), + ), ) } } diff --git a/crates/gpui/examples/window_shadow.rs b/crates/gpui/examples/window_shadow.rs index 06dde91133..469017da79 100644 --- a/crates/gpui/examples/window_shadow.rs +++ b/crates/gpui/examples/window_shadow.rs @@ -165,8 +165,8 @@ impl Render for WindowShadow { }, ) .on_click(|e, window, _| { - if e.down.button == MouseButton::Right { - window.show_window_menu(e.up.position); + if e.is_right_click() { + window.show_window_menu(e.position()); } }) .text_color(black()) diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index fa47758581..09afbff929 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -19,10 +19,10 @@ use crate::{ Action, AnyDrag, AnyElement, AnyTooltip, AnyView, App, Bounds, ClickEvent, DispatchPhase, Element, ElementId, Entity, FocusHandle, Global, GlobalElementId, Hitbox, HitboxBehavior, HitboxId, InspectorElementId, IntoElement, IsZero, KeyContext, KeyDownEvent, KeyUpEvent, - LayoutId, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, - Overflow, ParentElement, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, Style, - StyleRefinement, Styled, Task, TooltipId, Visibility, Window, WindowControlArea, point, px, - size, + KeyboardButton, KeyboardClickEvent, LayoutId, ModifiersChangedEvent, MouseButton, + MouseClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Overflow, ParentElement, Pixels, + Point, Render, ScrollWheelEvent, SharedString, Size, Style, StyleRefinement, Styled, Task, + TooltipId, Visibility, Window, WindowControlArea, point, px, size, }; use collections::HashMap; use refineable::Refineable; @@ -484,10 +484,9 @@ impl Interactivity { where Self: Sized, { - self.click_listeners - .push(Box::new(move |event, window, cx| { - listener(event, window, cx) - })); + self.click_listeners.push(Rc::new(move |event, window, cx| { + listener(event, window, cx) + })); } /// On drag initiation, this callback will be used to create a new view to render the dragged value for a @@ -1156,7 +1155,7 @@ pub(crate) type MouseMoveListener = pub(crate) type ScrollWheelListener = Box; -pub(crate) type ClickListener = Box; +pub(crate) type ClickListener = Rc; pub(crate) type DragListener = Box, &mut Window, &mut App) -> AnyView + 'static>; @@ -1950,6 +1949,12 @@ impl Interactivity { window: &mut Window, cx: &mut App, ) { + let is_focused = self + .tracked_focus_handle + .as_ref() + .map(|handle| handle.is_focused(window)) + .unwrap_or(false); + // If this element can be focused, register a mouse down listener // that will automatically transfer focus when hitting the element. // This behavior can be suppressed by using `cx.prevent_default()`. @@ -2113,6 +2118,39 @@ impl Interactivity { } }); + if is_focused { + // Press enter, space to trigger click, when the element is focused. + window.on_key_event({ + let click_listeners = click_listeners.clone(); + let hitbox = hitbox.clone(); + move |event: &KeyUpEvent, phase, window, cx| { + if phase.bubble() && !window.default_prevented() { + let stroke = &event.keystroke; + let keyboard_button = if stroke.key.eq("enter") { + Some(KeyboardButton::Enter) + } else if stroke.key.eq("space") { + Some(KeyboardButton::Space) + } else { + None + }; + + if let Some(button) = keyboard_button + && !stroke.modifiers.modified() + { + let click_event = ClickEvent::Keyboard(KeyboardClickEvent { + button, + bounds: hitbox.bounds, + }); + + for listener in &click_listeners { + listener(&click_event, window, cx); + } + } + } + } + }); + } + window.on_mouse_event({ let mut captured_mouse_down = None; let hitbox = hitbox.clone(); @@ -2138,10 +2176,10 @@ impl Interactivity { // Fire click handlers during the bubble phase. DispatchPhase::Bubble => { if let Some(mouse_down) = captured_mouse_down.take() { - let mouse_click = ClickEvent { + let mouse_click = ClickEvent::Mouse(MouseClickEvent { down: mouse_down, up: event.clone(), - }; + }); for listener in &click_listeners { listener(&mouse_click, window, cx); } diff --git a/crates/gpui/src/interactive.rs b/crates/gpui/src/interactive.rs index edd807da11..46af946e69 100644 --- a/crates/gpui/src/interactive.rs +++ b/crates/gpui/src/interactive.rs @@ -1,6 +1,6 @@ use crate::{ - Capslock, Context, Empty, IntoElement, Keystroke, Modifiers, Pixels, Point, Render, Window, - point, seal::Sealed, + Bounds, Capslock, Context, Empty, IntoElement, Keystroke, Modifiers, Pixels, Point, Render, + Window, point, seal::Sealed, }; use smallvec::SmallVec; use std::{any::Any, fmt::Debug, ops::Deref, path::PathBuf}; @@ -141,7 +141,7 @@ impl MouseEvent for MouseUpEvent {} /// A click event, generated when a mouse button is pressed and released. #[derive(Clone, Debug, Default)] -pub struct ClickEvent { +pub struct MouseClickEvent { /// The mouse event when the button was pressed. pub down: MouseDownEvent, @@ -149,18 +149,119 @@ pub struct ClickEvent { pub up: MouseUpEvent, } +/// A click event that was generated by a keyboard button being pressed and released. +#[derive(Clone, Debug)] +pub struct KeyboardClickEvent { + /// The keyboard button that was pressed to trigger the click. + pub button: KeyboardButton, + + /// The bounds of the element that was clicked. + pub bounds: Bounds, +} + +/// A click event, generated when a mouse button or keyboard button is pressed and released. +#[derive(Clone, Debug)] +pub enum ClickEvent { + /// A click event trigger by a mouse button being pressed and released. + Mouse(MouseClickEvent), + /// A click event trigger by a keyboard button being pressed and released. + Keyboard(KeyboardClickEvent), +} + impl ClickEvent { - /// Returns the modifiers that were held down during both the - /// mouse down and mouse up events + /// Returns the modifiers that were held during the click event + /// + /// `Keyboard`: The keyboard click events never have modifiers. + /// `Mouse`: Modifiers that were held during the mouse key up event. pub fn modifiers(&self) -> Modifiers { - Modifiers { - control: self.up.modifiers.control && self.down.modifiers.control, - alt: self.up.modifiers.alt && self.down.modifiers.alt, - shift: self.up.modifiers.shift && self.down.modifiers.shift, - platform: self.up.modifiers.platform && self.down.modifiers.platform, - function: self.up.modifiers.function && self.down.modifiers.function, + match self { + // Click events are only generated from keyboard events _without any modifiers_, so we know the modifiers are always Default + ClickEvent::Keyboard(_) => Modifiers::default(), + // Click events on the web only reflect the modifiers for the keyup event, + // tested via observing the behavior of the `ClickEvent.shiftKey` field in Chrome 138 + // under various combinations of modifiers and keyUp / keyDown events. + ClickEvent::Mouse(event) => event.up.modifiers, } } + + /// Returns the position of the click event + /// + /// `Keyboard`: The bottom left corner of the clicked hitbox + /// `Mouse`: The position of the mouse when the button was released. + pub fn position(&self) -> Point { + match self { + ClickEvent::Keyboard(event) => event.bounds.bottom_left(), + ClickEvent::Mouse(event) => event.up.position, + } + } + + /// Returns the mouse position of the click event + /// + /// `Keyboard`: None + /// `Mouse`: The position of the mouse when the button was released. + pub fn mouse_position(&self) -> Option> { + match self { + ClickEvent::Keyboard(_) => None, + ClickEvent::Mouse(event) => Some(event.up.position), + } + } + + /// Returns if this was a right click + /// + /// `Keyboard`: false + /// `Mouse`: Whether the right button was pressed and released + pub fn is_right_click(&self) -> bool { + match self { + ClickEvent::Keyboard(_) => false, + ClickEvent::Mouse(event) => { + event.down.button == MouseButton::Right && event.up.button == MouseButton::Right + } + } + } + + /// Returns whether the click was a standard click + /// + /// `Keyboard`: Always true + /// `Mouse`: Left button pressed and released + pub fn standard_click(&self) -> bool { + match self { + ClickEvent::Keyboard(_) => true, + ClickEvent::Mouse(event) => { + event.down.button == MouseButton::Left && event.up.button == MouseButton::Left + } + } + } + + /// Returns whether the click focused the element + /// + /// `Keyboard`: false, keyboard clicks only work if an element is already focused + /// `Mouse`: Whether this was the first focusing click + pub fn first_focus(&self) -> bool { + match self { + ClickEvent::Keyboard(_) => false, + ClickEvent::Mouse(event) => event.down.first_mouse, + } + } + + /// Returns the click count of the click event + /// + /// `Keyboard`: Always 1 + /// `Mouse`: Count of clicks from MouseUpEvent + pub fn click_count(&self) -> usize { + match self { + ClickEvent::Keyboard(_) => 1, + ClickEvent::Mouse(event) => event.up.click_count, + } + } +} + +/// An enum representing the keyboard button that was pressed for a click event. +#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)] +pub enum KeyboardButton { + /// Enter key was clicked + Enter, + /// Space key was clicked + Space, } /// An enum representing the mouse button that was pressed. diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 9e4c1c26c5..8610993994 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -79,11 +79,13 @@ pub enum DispatchPhase { impl DispatchPhase { /// Returns true if this represents the "bubble" phase. + #[inline] pub fn bubble(self) -> bool { self == DispatchPhase::Bubble } /// Returns true if this represents the "capture" phase. + #[inline] pub fn capture(self) -> bool { self == DispatchPhase::Capture } diff --git a/crates/markdown_preview/src/markdown_preview_view.rs b/crates/markdown_preview/src/markdown_preview_view.rs index 03cfd7ee82..96e92de19c 100644 --- a/crates/markdown_preview/src/markdown_preview_view.rs +++ b/crates/markdown_preview/src/markdown_preview_view.rs @@ -261,7 +261,7 @@ impl MarkdownPreviewView { .group("markdown-block") .on_click(cx.listener( move |this, event: &ClickEvent, window, cx| { - if event.down.click_count == 2 { + if event.click_count() == 2 { if let Some(source_range) = this .contents .as_ref() diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index ad96670db9..1cda3897ec 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -2570,11 +2570,11 @@ impl OutlinePanel { .on_click({ let clicked_entry = rendered_entry.clone(); cx.listener(move |outline_panel, event: &gpui::ClickEvent, window, cx| { - if event.down.button == MouseButton::Right || event.down.first_mouse { + if event.is_right_click() || event.first_focus() { return; } - let change_focus = event.down.click_count > 1; + let change_focus = event.click_count() > 1; outline_panel.toggle_expanded(&clicked_entry, window, cx); outline_panel.scroll_editor_to_entry( diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 05e6bfe4df..048b9e73d0 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -4157,13 +4157,12 @@ impl ProjectPanel { ) .on_click( cx.listener(move |this, event: &gpui::ClickEvent, window, cx| { - if event.down.button == MouseButton::Right - || event.down.first_mouse + if event.is_right_click() || event.first_focus() || show_editor { return; } - if event.down.button == MouseButton::Left { + if event.standard_click() { this.mouse_down = false; } cx.stop_propagation(); @@ -4203,7 +4202,7 @@ impl ProjectPanel { this.marked_entries.insert(clicked_entry); } } else if event.modifiers().secondary() { - if event.down.click_count > 1 { + if event.click_count() > 1 { this.split_entry(entry_id, cx); } else { this.selection = Some(selection); @@ -4237,7 +4236,7 @@ impl ProjectPanel { } } else { let preview_tabs_enabled = PreviewTabsSettings::get_global(cx).enabled; - let click_count = event.up.click_count; + let click_count = event.click_count(); let focus_opened_item = !preview_tabs_enabled || click_count > 1; let allow_preview = preview_tabs_enabled && click_count == 1; this.open_entry(entry_id, focus_opened_item, allow_preview, cx); @@ -5138,7 +5137,10 @@ impl Render for ProjectPanel { this.hide_scrollbar(window, cx); } })) - .on_click(cx.listener(|this, _event, _, cx| { + .on_click(cx.listener(|this, event, _, cx| { + if matches!(event, gpui::ClickEvent::Keyboard(_)) { + return; + } cx.stop_propagation(); this.selection = None; this.marked_entries.clear(); @@ -5179,7 +5181,7 @@ impl Render for ProjectPanel { .on_action(cx.listener(Self::paste)) .on_action(cx.listener(Self::duplicate)) .on_click(cx.listener(|this, event: &gpui::ClickEvent, window, cx| { - if event.up.click_count > 1 { + if event.click_count() > 1 { if let Some(entry_id) = this.last_worktree_root_id { let project = this.project.read(cx); diff --git a/crates/recent_projects/src/remote_servers.rs b/crates/recent_projects/src/remote_servers.rs index 655e24860a..354434a7fc 100644 --- a/crates/recent_projects/src/remote_servers.rs +++ b/crates/recent_projects/src/remote_servers.rs @@ -953,7 +953,7 @@ impl RemoteServerProjects { ) .child(Label::new(project.paths.join(", "))) .on_click(cx.listener(move |this, e: &ClickEvent, window, cx| { - let secondary_confirm = e.down.modifiers.platform; + let secondary_confirm = e.modifiers().platform; callback(this, secondary_confirm, window, cx) })) .when(is_from_zed, |server_list_item| { diff --git a/crates/settings_ui/src/keybindings.rs b/crates/settings_ui/src/keybindings.rs index 70afe1729c..81c461fed6 100644 --- a/crates/settings_ui/src/keybindings.rs +++ b/crates/settings_ui/src/keybindings.rs @@ -1855,7 +1855,7 @@ impl Render for KeymapEditor { .on_click(cx.listener( move |this, event: &ClickEvent, window, cx| { this.select_index(row_index, None, window, cx); - if event.up.click_count == 2 { + if event.click_count() == 2 { this.open_edit_keybinding_modal( false, window, cx, ); diff --git a/crates/settings_ui/src/ui_components/table.rs b/crates/settings_ui/src/ui_components/table.rs index 3c9992bd68..2b3e815f36 100644 --- a/crates/settings_ui/src/ui_components/table.rs +++ b/crates/settings_ui/src/ui_components/table.rs @@ -248,7 +248,7 @@ impl TableInteractionState { .cursor_col_resize() .when_some(columns.clone(), |this, columns| { this.on_click(move |event, window, cx| { - if event.down.click_count >= 2 { + if event.click_count() >= 2 { columns.update(cx, |columns, _| { columns.on_double_click( column_ix, @@ -997,7 +997,7 @@ pub fn render_header( |this, (column_widths, resizables, initial_sizes)| { if resizables[header_idx].is_resizable() { this.on_click(move |event, window, cx| { - if event.down.click_count > 1 { + if event.click_count() > 1 { column_widths .update(cx, |column, _| { column.on_double_click( diff --git a/crates/title_bar/src/platform_title_bar.rs b/crates/title_bar/src/platform_title_bar.rs index 30b1b4c3f8..ef6ef93eed 100644 --- a/crates/title_bar/src/platform_title_bar.rs +++ b/crates/title_bar/src/platform_title_bar.rs @@ -106,14 +106,14 @@ impl Render for PlatformTitleBar { // Note: On Windows the title bar behavior is handled by the platform implementation. .when(self.platform_style == PlatformStyle::Mac, |this| { this.on_click(|event, window, _| { - if event.up.click_count == 2 { + if event.click_count() == 2 { window.titlebar_double_click(); } }) }) .when(self.platform_style == PlatformStyle::Linux, |this| { this.on_click(|event, window, _| { - if event.up.click_count == 2 { + if event.click_count() == 2 { window.zoom_window(); } }) diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs index 15ab00e7e5..35c78fbb5d 100644 --- a/crates/ui/src/components/button/button_like.rs +++ b/crates/ui/src/components/button/button_like.rs @@ -1,7 +1,8 @@ use documented::Documented; use gpui::{ AnyElement, AnyView, ClickEvent, CursorStyle, DefiniteLength, Hsla, MouseButton, - MouseDownEvent, MouseUpEvent, Rems, StyleRefinement, relative, transparent_black, + MouseClickEvent, MouseDownEvent, MouseUpEvent, Rems, StyleRefinement, relative, + transparent_black, }; use smallvec::SmallVec; @@ -620,7 +621,7 @@ impl RenderOnce for ButtonLike { MouseButton::Right, move |event, window, cx| { cx.stop_propagation(); - let click_event = ClickEvent { + let click_event = ClickEvent::Mouse(MouseClickEvent { down: MouseDownEvent { button: MouseButton::Right, position: event.position, @@ -634,7 +635,7 @@ impl RenderOnce for ButtonLike { modifiers: event.modifiers, click_count: 1, }, - }; + }); (on_right_click)(&click_event, window, cx) }, ) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 2062255f4b..fff15d2b52 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -2945,7 +2945,7 @@ impl Pane { this.handle_external_paths_drop(paths, window, cx) })) .on_click(cx.listener(move |this, event: &ClickEvent, window, cx| { - if event.up.click_count == 2 { + if event.click_count() == 2 { window.dispatch_action( this.double_click_dispatch_action.boxed_clone(), cx, @@ -3640,7 +3640,7 @@ impl Render for Pane { .justify_center() .on_click(cx.listener( move |this, event: &ClickEvent, window, cx| { - if event.up.click_count == 2 { + if event.click_count() == 2 { window.dispatch_action( this.double_click_dispatch_action.boxed_clone(), cx,