From d9efa2860fef17c58dc1f12ca2a4dd33087280ae Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 7 Jun 2025 01:06:09 +0800 Subject: [PATCH] gpui: Fix scroll area to support two-layer scrolling in different directions (#31062) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release Notes: - N/A --- This change is used to solve the problem of not being able to respond correctly in two-layer scrolling (in different directions). This is a common practical requirement. As in the example, in actual use, there may be a scene with a horizontal scroll in a vertical scroll. Before the modification, if we scroll up and down in the area that can scroll horizontally, it will not respond (because it is blocked by the horizontal scroll layer). ## Before https://github.com/user-attachments/assets/e8ea0118-52a5-44d8-b419-639d4b6c0793 ## After https://github.com/user-attachments/assets/aa14ddd7-5596-4dc5-9c6e-278aabdfef8e ---- This change may cause many side effects, causing some scrolling details to be different from before, and more testing and analysis are needed. I have tested some existing scenarios of Zed (such as opening the Branch panel on the Editor and scrolling) and it seems to be correct (but it is possible that I don’t know some interaction details). Here, the person who added this line of code before needs to evaluate the original purpose. --- crates/editor/src/hover_popover.rs | 1 + crates/gpui/examples/scrollable.rs | 60 ++++++++++++++++++++++++++++++ crates/gpui/src/elements/div.rs | 1 - 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 crates/gpui/examples/scrollable.rs diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index d962ee9f56..2411b26ff1 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -869,6 +869,7 @@ impl InfoPopover { let keyboard_grace = Rc::clone(&self.keyboard_grace); div() .id("info_popover") + .occlude() .elevation_2(cx) // Prevent a mouse down/move on the popover from being propagated to the editor, // because that would dismiss the popover. diff --git a/crates/gpui/examples/scrollable.rs b/crates/gpui/examples/scrollable.rs new file mode 100644 index 0000000000..b668c19c40 --- /dev/null +++ b/crates/gpui/examples/scrollable.rs @@ -0,0 +1,60 @@ +use gpui::{ + App, Application, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px, + size, +}; + +struct Scrollable {} + +impl Render for Scrollable { + fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { + div() + .size_full() + .id("vertical") + .p_4() + .overflow_scroll() + .bg(gpui::white()) + .child("Example for test 2 way scroll in nested layout") + .child( + div() + .h(px(5000.)) + .border_1() + .border_color(gpui::blue()) + .bg(gpui::blue().opacity(0.05)) + .p_4() + .child( + div() + .mb_5() + .w_full() + .id("horizontal") + .overflow_scroll() + .child( + div() + .w(px(2000.)) + .h(px(150.)) + .bg(gpui::green().opacity(0.1)) + .hover(|this| this.bg(gpui::green().opacity(0.2))) + .border_1() + .border_color(gpui::green()) + .p_4() + .child("Scroll Horizontal"), + ), + ) + .child("Scroll Vertical"), + ) + } +} + +fn main() { + Application::new().run(|cx: &mut App| { + let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx); + cx.open_window( + WindowOptions { + window_bounds: Some(WindowBounds::Windowed(bounds)), + ..Default::default() + }, + |_, cx| cx.new(|_| Scrollable {}), + ) + .unwrap(); + cx.activate(true); + }); +} diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index fd78591dd1..3e9d1e27a9 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -2299,7 +2299,6 @@ impl Interactivity { } scroll_offset.y += delta_y; scroll_offset.x += delta_x; - cx.stop_propagation(); if *scroll_offset != old_scroll_offset { cx.notify(current_view); }