macOS: a visible pane whose real frame drifted from the cached placement (AppKit moved it behind our back) is placed again, with a diag line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
CRTkafa 2026-10-02 01:28:03 +07:00
parent 64a37cf366
commit a6dc340747

View file

@ -929,7 +929,14 @@ pub fn place_tab<R: Runtime>(webview: &Webview<R>, rect: crate::layout::Rect, vi
if reveal {
set_tab_visible(webview, visible, parked, was_visible);
}
if changed.bounds {
// macOS: the cached placement says nothing moved, but AppKit (window animations, a monitor change, a
// restore from the Dock) can move or resize a child behind our back; the pane then shows the shell's
// black ground until relaunch. A visible pane whose real frame differs is placed again.
#[cfg(target_os = "macos")]
let drifted = visible && !changed.bounds && !reveal && native_frame_differs(webview, rect);
#[cfg(not(target_os = "macos"))]
let drifted = false;
if changed.bounds || drifted {
let (x, y, width, height) = rect;
place_child(webview, x, y, width, height);
}
@ -942,6 +949,19 @@ pub fn place_tab<R: Runtime>(webview: &Webview<R>, rect: crate::layout::Rect, vi
}
}
/// macOS: whether a child webview's real frame is off the rectangle last asked for (more than 1.5 px).
#[cfg(target_os = "macos")]
fn native_frame_differs<R: Runtime>(webview: &Webview<R>, rect: crate::layout::Rect) -> bool {
let Ok(actual) = webview.bounds() else { return false };
let (position, size) = (actual.position.to_logical::<f64>(1.0), actual.size.to_logical::<f64>(1.0));
let (x, y, width, height) = rect;
let off = (position.x - x).abs() > 1.5 || (position.y - y).abs() > 1.5 || (size.width - width).abs() > 1.5 || (size.height - height).abs() > 1.5;
if off {
crate::diag::log("host", &format!("pane {} drifted to {},{} {}x{}, placing it again", webview.label(), position.x, position.y, size.width, size.height));
}
off
}
/// A tab webview was closed: a new one with the same label is placed from scratch.
pub fn forget_tab<R: Runtime>(app: &AppHandle<R>, label: &str) {
#[cfg(windows)]