fix: connect toolbar double clicks to native window zoom
Verify Tessera GUI / verify (push) Failing after 1m33s
Verify Tessera GUI / verify (push) Failing after 1m33s
This commit is contained in:
+2
-2
@@ -21,8 +21,8 @@ winit = "0.30.13"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc2 = "0.5.2"
|
||||
objc2-app-kit = { version = "0.2.2", default-features = false, features = ["NSButton", "NSView", "NSWindow"] }
|
||||
objc2-foundation = { version = "0.2.2", default-features = false, features = ["NSGeometry"] }
|
||||
objc2-app-kit = { version = "0.2.2", default-features = false, features = ["NSApplication", "NSButton", "NSEvent", "NSView", "NSWindow"] }
|
||||
objc2-foundation = { version = "0.2.2", default-features = false, features = ["NSGeometry", "NSString", "NSUserDefaults"] }
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
|
||||
@@ -201,3 +201,32 @@ selection changes to the clicked tab and idle separators return after leaving.
|
||||
The capture API does not establish frame-accurate 160 ms timing. Offline
|
||||
all-target Clippy, formatting, release bundling and whitespace checks passed;
|
||||
no cargo test, automated smoke script or Docker task was run.
|
||||
|
||||
|
||||
### Native toolbar double-click — 2026-10-25
|
||||
|
||||
The custom row previously called only winit's native window-drag operation;
|
||||
a manual double-click in its empty area did not resize the window. The same
|
||||
empty-area hit test now consults AppKit's current NSEvent clickCount before
|
||||
starting a drag. On the second press it calls NSWindow.performZoom, preserving
|
||||
AppKit's standard/user frame toggle and avoiding a hand-built resize animation.
|
||||
Tabs, close buttons and + remain excluded from this handler.
|
||||
|
||||
The adapter reads AppleActionOnDoubleClick without changing system preferences:
|
||||
Minimize calls performMiniaturize; absent/Maximize calls performZoom; disabled
|
||||
or unknown values do nothing. Fill also uses the public performZoom action,
|
||||
whose standard frame fills this application's available screen in the checked
|
||||
configuration. It does not invoke the private _zoomFill selector used by Chrome.
|
||||
Consequently Fill is not claimed to reproduce every macOS tiling margin rule.
|
||||
Native fullscreen uses a different window state and is left to AppKit.
|
||||
|
||||
References: Apple's [performZoom](https://developer.apple.com/documentation/appkit/nswindow/performzoom(_:))
|
||||
and Chromium's [custom draggable-area handling](https://github.com/chromium/chromium/blob/main/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm).
|
||||
|
||||
Manual native verification: an empty-row double-click changed the Retina window
|
||||
from 2560×1600 to 3024×1888; a second double-click restored 2560×1600. Clicking
|
||||
+ and double-clicking a tab did not zoom the window. Dragging empty toolbar
|
||||
space continued to move the window. The user's double-click preference was
|
||||
absent (default zoom); other preference branches were not changed or manually
|
||||
tested. Offline all-target Clippy, formatting, release bundling and whitespace
|
||||
checks passed. No cargo test or automated smoke script was run.
|
||||
|
||||
@@ -1410,6 +1410,10 @@ impl ApplicationHandler<AppEvent> for TesseraApp {
|
||||
&& self.pointer.x >= crate::tabs::LEADING
|
||||
&& self.tab_hit().is_none()
|
||||
{
|
||||
#[cfg(target_os = "macos")]
|
||||
if crate::native_chrome::titlebar_double_click(&window) {
|
||||
return;
|
||||
}
|
||||
let _ = window.drag_window();
|
||||
}
|
||||
if self.pointer.y >= crate::tabs::height(&[]) {
|
||||
|
||||
+43
-2
@@ -1,11 +1,52 @@
|
||||
//! Keep AppKit's real window buttons aligned with the custom tab strip.
|
||||
use objc2_app_kit::{NSView, NSWindowButton, NSWindowStyleMask};
|
||||
use objc2_foundation::NSPoint;
|
||||
use objc2_app_kit::{NSApplication, NSView, NSWindowButton, NSWindowStyleMask};
|
||||
use objc2_foundation::{MainThreadMarker, NSPoint, NSString, NSUserDefaults};
|
||||
use winit::{
|
||||
raw_window_handle::{HasWindowHandle, RawWindowHandle},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
/// The custom draggable row does not receive AppKit's titlebar double-click
|
||||
/// action automatically. Use the native click count and native window actions.
|
||||
pub fn titlebar_double_click(window: &Window) -> bool {
|
||||
let Some(main_thread) = MainThreadMarker::new() else {
|
||||
return false;
|
||||
};
|
||||
let Ok(handle) = window.window_handle() else {
|
||||
return false;
|
||||
};
|
||||
let RawWindowHandle::AppKit(handle) = handle.as_raw() else {
|
||||
return false;
|
||||
};
|
||||
// SAFETY: called on the event-loop thread during a left-button press, with
|
||||
// a live winit-owned NSView. No native object outlives the Window borrow.
|
||||
unsafe {
|
||||
let Some(event) = NSApplication::sharedApplication(main_thread).currentEvent() else {
|
||||
return false;
|
||||
};
|
||||
if event.clickCount() != 2 {
|
||||
return false;
|
||||
}
|
||||
let view = &*handle.ns_view.as_ptr().cast::<NSView>();
|
||||
let Some(native) = view.window() else {
|
||||
return false;
|
||||
};
|
||||
if native.styleMask().contains(NSWindowStyleMask::FullScreen) {
|
||||
return true;
|
||||
}
|
||||
let action = NSUserDefaults::standardUserDefaults()
|
||||
.stringForKey(&NSString::from_str("AppleActionOnDoubleClick"))
|
||||
.map(|value| value.to_string());
|
||||
match action.as_deref() {
|
||||
Some("Minimize") => native.performMiniaturize(None),
|
||||
None | Some("Maximize" | "Fill") => native.performZoom(None),
|
||||
// Respect disabled/unrecognized system actions without moving it.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Called only on winit's main thread, after native creation and before drawing.
|
||||
/// AppKit can restore its default button positions when laying out the title bar.
|
||||
pub fn align_controls(window: &Window) {
|
||||
|
||||
Reference in New Issue
Block a user