mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-16 04:24:31 +00:00
gpui: Avoid redundant group hover redraws (#61118)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Anonymous elements with group hover styles have no persistent hover state. The prepaint mouse handler treated missing state as unhovered and notified the current view for every pointer movement within the group. This made controls such as switches redraw continuously while the pointer moved over them. Let anonymous elements use the existing paint-time hover transition handler. Only elements with persistent hover state now update that state and notify from prepaint. Add regression coverage for entering, moving within, and leaving an anonymous hover group. Signed-off-by: Daan De Meyer <daan@amutable.com> Release Notes: - N/A Signed-off-by: Daan De Meyer <daan@amutable.com>
This commit is contained in:
parent
b05f40c554
commit
ae3bbdeb2d
1 changed files with 102 additions and 3 deletions
|
|
@ -2669,8 +2669,8 @@ impl Interactivity {
|
|||
if phase == DispatchPhase::Capture && group_hovered != was_group_hovered {
|
||||
if let Some(hover_state) = &hover_state {
|
||||
hover_state.borrow_mut().group = group_hovered;
|
||||
cx.notify(current_view);
|
||||
}
|
||||
cx.notify(current_view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -4114,9 +4114,108 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::{
|
||||
AnyWindowHandle, AppContext as _, Context, InputEvent, Keystroke, MouseMoveEvent,
|
||||
TestAppContext, util::FluentBuilder as _,
|
||||
TestAppContext, canvas, util::FluentBuilder as _,
|
||||
};
|
||||
use std::rc::Weak;
|
||||
use std::{cell::Cell, rc::Weak};
|
||||
|
||||
struct GroupHoverTestView {
|
||||
render_count: Rc<Cell<usize>>,
|
||||
anonymous_paint_count: Rc<Cell<usize>>,
|
||||
stateful_width: Rc<Cell<Pixels>>,
|
||||
}
|
||||
|
||||
impl Render for GroupHoverTestView {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
self.render_count.set(self.render_count.get() + 1);
|
||||
let anonymous_paint_count = self.anonymous_paint_count.clone();
|
||||
let stateful_width = self.stateful_width.clone();
|
||||
div().size_full().child(
|
||||
div()
|
||||
.ml(px(20.))
|
||||
.mt(px(20.))
|
||||
.size(px(50.))
|
||||
.relative()
|
||||
.group("hover-group")
|
||||
.child(
|
||||
div()
|
||||
.absolute()
|
||||
.size_full()
|
||||
.invisible()
|
||||
.group_hover("hover-group", |style| style.visible())
|
||||
.child(canvas(
|
||||
|_, _, _| {},
|
||||
move |_, _, _, _| {
|
||||
anonymous_paint_count.set(anonymous_paint_count.get() + 1)
|
||||
},
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("stateful-group-hover-target")
|
||||
.absolute()
|
||||
.top_0()
|
||||
.left_0()
|
||||
.size(px(10.))
|
||||
.group_hover("hover-group", |style| style.size(px(20.)))
|
||||
.child(canvas(
|
||||
move |bounds, _, _| stateful_width.set(bounds.size.width),
|
||||
|_, _, _, _| {},
|
||||
)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn group_hover_styles_update_only_on_transitions(cx: &mut TestAppContext) {
|
||||
let render_count = Rc::new(Cell::new(0));
|
||||
let anonymous_paint_count = Rc::new(Cell::new(0));
|
||||
let stateful_width = Rc::new(Cell::new(px(0.)));
|
||||
let window = cx.add_window({
|
||||
let render_count = render_count.clone();
|
||||
let anonymous_paint_count = anonymous_paint_count.clone();
|
||||
let stateful_width = stateful_width.clone();
|
||||
move |_, _| GroupHoverTestView {
|
||||
render_count,
|
||||
anonymous_paint_count,
|
||||
stateful_width,
|
||||
}
|
||||
});
|
||||
let window = AnyWindowHandle::from(window);
|
||||
|
||||
cx.update_window(window, |_, window, cx| window.draw(cx).clear())
|
||||
.unwrap();
|
||||
assert_eq!(anonymous_paint_count.get(), 0);
|
||||
assert_eq!(stateful_width.get(), px(10.));
|
||||
|
||||
let move_mouse = |cx: &mut TestAppContext, position| {
|
||||
cx.update_window(window, |_, window, cx| {
|
||||
window.simulate_mouse_move(position, cx)
|
||||
})
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
let initial_render_count = render_count.get();
|
||||
move_mouse(cx, point(px(25.), px(25.)));
|
||||
assert_eq!(render_count.get(), initial_render_count + 1);
|
||||
assert_eq!(anonymous_paint_count.get(), 1);
|
||||
assert_eq!(stateful_width.get(), px(20.));
|
||||
|
||||
move_mouse(cx, point(px(30.), px(30.)));
|
||||
assert_eq!(render_count.get(), initial_render_count + 1);
|
||||
assert_eq!(anonymous_paint_count.get(), 1);
|
||||
assert_eq!(stateful_width.get(), px(20.));
|
||||
|
||||
move_mouse(cx, point(px(5.), px(5.)));
|
||||
assert_eq!(render_count.get(), initial_render_count + 2);
|
||||
assert_eq!(anonymous_paint_count.get(), 1);
|
||||
assert_eq!(stateful_width.get(), px(10.));
|
||||
|
||||
move_mouse(cx, point(px(10.), px(10.)));
|
||||
assert_eq!(render_count.get(), initial_render_count + 2);
|
||||
assert_eq!(anonymous_paint_count.get(), 1);
|
||||
assert_eq!(stateful_width.get(), px(10.));
|
||||
}
|
||||
|
||||
struct TestTooltipView;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue