mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-17 13:04:44 +00:00
Closes https://github.com/zed-industries/zed/issues/60595 cc Anthony-Eid since you did an initial pass on this. # Objective Currenly on macOs there is no way right now after the following regression to use window management short keys to move them around. This worked before, but was regressed initially in https://github.com/zed-industries/zed/pull/59836 that tried fixing a macos 27 clicking delay issue on the titlebar. That accidentally set the `native_window.setMovable_(is_movable as BOOL)` to false. Because of this mocos detects this and disables the window managements actions because it thinks the window can/should not be able to move. ## Solution The macOS 27 click delay actually comes from AppKit's native titlebar dragging, not from `NSWindow.isMovable`. The problem is that `is_movable` is also what enables the Window menu's tiling options, and #59836 used it to turn off dragging, which disabled the tiling menu as a side effect. To fix this, I restored `is_movable` to its real meaning so the tiling menu works again, and added a separate `WindowOptions::app_owns_titlebar_drag` flag for windows that draw their own titlebar and handle dragging via `Window::start_window_move`. On macOS this tells AppKit to stop owning titlebar drags (removing the click delay) without affecting `is_movable`. Zed's main window now sets both `is_movable: true` and `app_owns_titlebar_drag: true`, so the tiling menu stays enabled, the click delay is gone. I also added a `window_movable` gpui example to make this behavior easy to test manually. ## Testing I added a gpui test example that helps testing this bug. You can run the newly added gpui example with 4 different window configurations that should confirm that this change is the right one for all of the window types that we have. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase **After** (note this now shows the window managements entries as they were greyed out.) https://github.com/user-attachments/assets/192cc0e1-15d8-486f-b788-a92bb51fb7d1 **GPUI** (test examples with different window configurations.) https://github.com/user-attachments/assets/c9e0f4d3-606b-4cd7-b4d8-a5bb16508164 --- Release Notes: - Fix macos window management controlls were grayed out/not working
125 lines
3.5 KiB
Rust
125 lines
3.5 KiB
Rust
#![cfg_attr(target_family = "wasm", no_main)]
|
|
|
|
use gpui::{
|
|
App, Bounds, Context, FocusHandle, Window, WindowBounds, WindowOptions, div, prelude::*, px,
|
|
rgb, size,
|
|
};
|
|
use gpui::{SharedString, TitlebarOptions};
|
|
use gpui_platform::application;
|
|
|
|
struct ExampleWindow {
|
|
label: SharedString,
|
|
focus_handle: FocusHandle,
|
|
}
|
|
|
|
impl Render for ExampleWindow {
|
|
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
div()
|
|
.track_focus(&self.focus_handle)
|
|
.flex()
|
|
.flex_col()
|
|
.gap_3()
|
|
.bg(rgb(0x2e2e2e))
|
|
.size_full()
|
|
.justify_center()
|
|
.items_center()
|
|
.p_8()
|
|
.text_lg()
|
|
.text_color(rgb(0xffffff))
|
|
.child(self.label.clone())
|
|
.child(
|
|
div()
|
|
.text_sm()
|
|
.text_color(rgb(0xb0b0b0))
|
|
.child("Try to drag the titlebar, and check the Window menu."),
|
|
)
|
|
}
|
|
}
|
|
|
|
fn open_test_window(
|
|
cx: &mut App,
|
|
bounds: Bounds<gpui::Pixels>,
|
|
label: &str,
|
|
is_movable: bool,
|
|
appears_transparent: bool,
|
|
app_owns_titlebar_drag: bool,
|
|
) {
|
|
let label = SharedString::from(format!(
|
|
"{label}\nis_movable: {is_movable}\n\
|
|
appears_transparent: {appears_transparent}\n\
|
|
app_owns_titlebar_drag: {app_owns_titlebar_drag}"
|
|
));
|
|
|
|
cx.open_window(
|
|
WindowOptions {
|
|
window_bounds: Some(WindowBounds::Windowed(bounds)),
|
|
is_movable,
|
|
app_owns_titlebar_drag,
|
|
titlebar: Some(TitlebarOptions {
|
|
title: Some(label.clone()),
|
|
appears_transparent,
|
|
..Default::default()
|
|
}),
|
|
..Default::default()
|
|
},
|
|
|window, cx| {
|
|
cx.new(|cx| {
|
|
let focus_handle = cx.focus_handle();
|
|
focus_handle.focus(window, cx);
|
|
ExampleWindow {
|
|
label,
|
|
focus_handle,
|
|
}
|
|
})
|
|
},
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn run_example() {
|
|
application().run(|cx: &mut App| {
|
|
let window_size = size(px(420.), px(280.0));
|
|
let base = Bounds::centered(None, window_size, cx);
|
|
|
|
// (label, is_movable, appears_transparent, app_owns_titlebar_drag, col, row)
|
|
let windows = [
|
|
("Native titlebar, movable", true, false, false, 0.0, 0.0),
|
|
(
|
|
"Native titlebar, NOT movable",
|
|
false,
|
|
false,
|
|
false,
|
|
1.0,
|
|
0.0,
|
|
),
|
|
("Custom titlebar, movable", true, true, false, 0.0, 1.0),
|
|
("Custom titlebar, NOT movable", false, true, false, 1.0, 1.0),
|
|
];
|
|
|
|
for (label, is_movable, appears_transparent, app_owns_titlebar_drag, col, row) in windows {
|
|
let mut bounds = base;
|
|
bounds.origin.x += window_size.width * col;
|
|
bounds.origin.y += window_size.height * row;
|
|
open_test_window(
|
|
cx,
|
|
bounds,
|
|
label,
|
|
is_movable,
|
|
appears_transparent,
|
|
app_owns_titlebar_drag,
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
#[cfg(not(target_family = "wasm"))]
|
|
fn main() {
|
|
run_example();
|
|
}
|
|
|
|
#[cfg(target_family = "wasm")]
|
|
#[wasm_bindgen::prelude::wasm_bindgen(start)]
|
|
pub fn start() {
|
|
gpui_platform::web_init();
|
|
run_example();
|
|
}
|