fix: make full titlebar strip draggable in dock and sidebar

This commit is contained in:
2026-11-09 10:04:57 +07:00
parent 7784e8d570
commit 6815585528
4 changed files with 49 additions and 37 deletions
+12 -11
View File
@@ -1085,18 +1085,19 @@ fn render_pane(
}) })
.pr(padding_x) .pr(padding_x)
.child(tabs) .child(tabs)
.child(titlebar_strip(
div()
.id(SharedString::from(format!(
"{dock_id}-pane-{}-strip",
pane.key
)))
.flex_1()
.self_stretch(),
window,
cx,
))
.when(titlebar.window_controls, |bar| { .when(titlebar.window_controls, |bar| {
bar.child(titlebar_strip( bar.child(WindowControls::new(SharedString::from(format!(
div()
.id(SharedString::from(format!(
"{dock_id}-pane-{}-strip",
pane.key
)))
.flex_1(),
window,
cx,
))
.child(WindowControls::new(SharedString::from(format!(
"{dock_id}-pane-{}-controls", "{dock_id}-pane-{}-controls",
pane.key pane.key
)))) ))))
+29 -22
View File
@@ -286,36 +286,43 @@ fn sidebar_region(
.h(strip_height) .h(strip_height)
.bg(strip_background) .bg(strip_background)
.items_center() .items_center()
.justify_end()
.map(|strip| titlebar_strip(strip, window, cx))
.map(|strip| match side { .map(|strip| match side {
Side::Left => strip.when(cfg!(target_os = "macos"), |strip| { Side::Left => strip.when(cfg!(target_os = "macos"), |strip| {
strip.pl(px(TRAFFIC_LIGHT_PAD)) strip.pl(px(TRAFFIC_LIGHT_PAD))
}), }),
Side::Right => strip.child(WindowControls::new("sidebar-window-controls")), Side::Right => strip,
}) })
.px(padding_x) .px(padding_x)
.child( .child(titlebar_strip(
Button::new(SharedString::from(format!( div()
"sidebar-toggle-{}", .id(SharedString::from(format!(
side.name() "sidebar-strip-drag-{}",
))) side.name()
.icon(side.toggle_icon()) )))
.variant(ButtonVariant::Ghost) .flex_1()
.small() .self_stretch(),
.accessibility_label(side.toggle_label()) window,
.on_click({ cx,
let state = state.clone(); ))
move |_, _, cx| match side { .map(|strip| match side {
Side::Left => { Side::Left => strip.child(
Button::new(SharedString::from(format!(
"sidebar-toggle-{}",
side.name()
)))
.icon(side.toggle_icon())
.variant(ButtonVariant::Ghost)
.small()
.accessibility_label(side.toggle_label())
.on_click({
let state = state.clone();
move |_, _, cx| {
state.update(cx, |state, cx| state.set_left_sidebar_visible(false, cx)) state.update(cx, |state, cx| state.set_left_sidebar_visible(false, cx))
} }
Side::Right => { }),
state.update(cx, |state, cx| state.set_right_sidebar_visible(false, cx)) ),
} Side::Right => strip.child(WindowControls::new("sidebar-window-controls")),
} });
}),
);
v_flex() v_flex()
.w(width) .w(width)
+1 -3
View File
@@ -166,9 +166,7 @@ pub fn maximize_on_double_click() -> impl Fn(&ClickEvent, &mut Window, &mut App)
} }
} }
/// Makes an element a titlebar strip: pressing and dragging it moves the /// Makes an element a titlebar strip.
/// window, double-clicking maximizes, and Windows keeps its native caption
/// behavior through the `Drag` control area.
pub fn titlebar_strip(this: Stateful<Div>, window: &mut Window, cx: &mut App) -> Stateful<Div> { pub fn titlebar_strip(this: Stateful<Div>, window: &mut Window, cx: &mut App) -> Stateful<Div> {
let should_move = window.use_state(cx, |_, _| false); let should_move = window.use_state(cx, |_, _| false);
this.window_control_area(WindowControlArea::Drag) this.window_control_area(WindowControlArea::Drag)
+7 -1
View File
@@ -98,8 +98,14 @@ fn the_pill_bar_pads_for_traffic_lights_when_it_leads_the_window() {
bounds(&mut visual, "test-dock-pane-0-tabs-tab-overview").expect("tab missing"); bounds(&mut visual, "test-dock-pane-0-tabs-tab-overview").expect("tab missing");
let padded_inset = padded_tab.left() - padded_bar.left(); let padded_inset = padded_tab.left() - padded_bar.left();
// The bare bar keeps the standard leading padding; the padded bar clears
// the traffic lights.
assert!( assert!(
padded_inset - bare_inset >= px(TRAFFIC_LIGHT_PAD) - px(1.), bare_inset < px(TRAFFIC_LIGHT_PAD),
"the bare bar must not reserve the traffic-light pad (bare {bare_inset:?})"
);
assert!(
padded_inset >= px(TRAFFIC_LIGHT_PAD) - px(1.),
"the pad must clear the traffic lights (bare {bare_inset:?}, padded {padded_inset:?})" "the pad must clear the traffic lights (bare {bare_inset:?}, padded {padded_inset:?})"
); );
} }