TitleBar: a press its buttons claim never moves the window
The drag area armed a window move on every press, buttons included, so a click on Linux's drawn buttons that moved a pixel started a move and the compositor kept the release. It now arms only on unclaimed presses. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
13642424e7
commit
3eb4d346fe
3 files changed
+80
-2
No files matched your search
+5
-2
@@ -21,8 +21,11 @@ pub fn drag_region(id: impl Into<ElementId>, window: &mut Window, cx: &mut App)
|
|||||||
div()
|
div()
|
||||||
.id(id)
|
.id(id)
|
||||||
.window_control_area(WindowControlArea::Drag)
|
.window_control_area(WindowControlArea::Drag)
|
||||||
.on_mouse_down(MouseButton::Left, move |_, _, cx| {
|
.on_mouse_down(MouseButton::Left, move |_, window, cx| {
|
||||||
down.update(cx, |pressed, _| *pressed = true)
|
// A button inside claims its own press.
|
||||||
|
if !window.default_prevented() {
|
||||||
|
down.update(cx, |pressed, _| *pressed = true)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.on_mouse_move(move |_, window, cx| {
|
.on_mouse_move(move |_, window, cx| {
|
||||||
if *moved.read(cx) {
|
if *moved.read(cx) {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ mod switcher;
|
|||||||
mod tabs;
|
mod tabs;
|
||||||
#[cfg(all(test, feature = "test-support"))]
|
#[cfg(all(test, feature = "test-support"))]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
#[cfg(all(test, feature = "test-support"))]
|
||||||
|
mod title_tests;
|
||||||
mod update;
|
mod update;
|
||||||
mod vibrancy;
|
mod vibrancy;
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
use gpui::{
|
||||||
|
Context, IntoElement, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
|
||||||
|
ParentElement, Point, Render, TestAppContext, Window, div, point, prelude::*, px,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::TitleBar;
|
||||||
|
use crate::theme::{Platform, Theme};
|
||||||
|
|
||||||
|
struct Bar {
|
||||||
|
closes: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for Bar {
|
||||||
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let view = cx.entity();
|
||||||
|
div().w(px(600.0)).child(
|
||||||
|
TitleBar::new("bar")
|
||||||
|
.platform(Platform::Linux)
|
||||||
|
.on_close(move |_, cx| view.update(cx, |bar, _| bar.closes += 1)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Presses at `at`, moves two pixels, releases.
|
||||||
|
fn wobble(at: Point<gpui::Pixels>, cx: &mut gpui::VisualTestContext) {
|
||||||
|
let moved = at + point(px(2.0), px(1.0));
|
||||||
|
cx.simulate_event(MouseDownEvent {
|
||||||
|
button: MouseButton::Left,
|
||||||
|
position: at,
|
||||||
|
modifiers: Modifiers::none(),
|
||||||
|
click_count: 1,
|
||||||
|
first_mouse: false,
|
||||||
|
});
|
||||||
|
cx.simulate_event(MouseMoveEvent {
|
||||||
|
position: moved,
|
||||||
|
pressed_button: Some(MouseButton::Left),
|
||||||
|
modifiers: Modifiers::none(),
|
||||||
|
});
|
||||||
|
cx.simulate_event(MouseUpEvent {
|
||||||
|
button: MouseButton::Left,
|
||||||
|
position: moved,
|
||||||
|
modifiers: Modifiers::none(),
|
||||||
|
click_count: 1,
|
||||||
|
});
|
||||||
|
cx.run_until_parked();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A press that wobbles on Linux's close button still closes; it never moves the window.
|
||||||
|
#[gpui::test]
|
||||||
|
fn a_wobbling_press_on_a_linux_button_clicks_it(cx: &mut TestAppContext) {
|
||||||
|
cx.update(Theme::init);
|
||||||
|
let (view, cx) = cx.add_window_view(|_, _| Bar { closes: 0 });
|
||||||
|
cx.run_until_parked();
|
||||||
|
let controls = cx
|
||||||
|
.debug_bounds("titlebar-controls")
|
||||||
|
.expect("drawn controls");
|
||||||
|
// Close is the last of the round buttons.
|
||||||
|
wobble(point(controls.right() - px(8.0), controls.center().y), cx);
|
||||||
|
assert_eq!(view.read_with(cx, |bar, _| bar.closes), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The bar's empty space still moves the window (the test window panics on a move).
|
||||||
|
#[gpui::test]
|
||||||
|
#[should_panic(expected = "not implemented")]
|
||||||
|
fn a_wobbling_press_on_the_bar_moves_the_window(cx: &mut TestAppContext) {
|
||||||
|
cx.update(Theme::init);
|
||||||
|
let (_, cx) = cx.add_window_view(|_, _| Bar { closes: 0 });
|
||||||
|
cx.run_until_parked();
|
||||||
|
let controls = cx
|
||||||
|
.debug_bounds("titlebar-controls")
|
||||||
|
.expect("drawn controls");
|
||||||
|
wobble(point(controls.left() - px(200.0), controls.center().y), cx);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user