From 943faf2e62c162089db81645b9b975ab44ea8fe6 Mon Sep 17 00:00:00 2001 From: BREW <81044362+b-re-w@users.noreply.github.com> Date: Tue, 10 Nov 2026 05:50:07 +0900 Subject: [PATCH] Fix: Lay the non-client view out with the frame view when the appbar changes width The client view takes its bounds from the frame view only when the non-client view above both lays out. On Brave the page stayed under the appbar after it showed again, as only the frame view and the browser view were laid out. Co-Authored-By: Claude Opus 5.5 --- rivet/runtime/windows/src/chromium/view.rs | 14 ++++++++++++++ rivet/runtime/windows/src/features/frame_layout.rs | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/rivet/runtime/windows/src/chromium/view.rs b/rivet/runtime/windows/src/chromium/view.rs index 3e3faa7..b8001c0 100644 --- a/rivet/runtime/windows/src/chromium/view.rs +++ b/rivet/runtime/windows/src/chromium/view.rs @@ -39,6 +39,20 @@ impl View { } } +/// The parent of a live view of the loaded build, when its parent pointer holds a view of the +/// browser module: an object whose first word points into the module. `None` for a root, an +/// unreadable place or a build that records no bounds offset. +pub(crate) unsafe fn parent_of(view: usize) -> Option { + let offset = View::parent_offset(crate::builds::get().layout.view_bounds_offset)?; + if !crate::chromium::memory::readable(view.checked_add(offset)?, 8) { + return None; + } + let parent = View::at(view).parent_address(offset); + let image = crate::chromium::image::recorded()?; + let table = crate::chromium::memory::read_word(parent)?; + (table > image.base && table < image.base + image.size).then_some(parent) +} + #[cfg(test)] mod tests { use super::*; diff --git a/rivet/runtime/windows/src/features/frame_layout.rs b/rivet/runtime/windows/src/features/frame_layout.rs index 6cd592e..875faeb 100644 --- a/rivet/runtime/windows/src/features/frame_layout.rs +++ b/rivet/runtime/windows/src/features/frame_layout.rs @@ -1018,6 +1018,11 @@ pub unsafe fn relayout(window: HWND) -> bool { let layout_immediately: unsafe extern "system" fn(*mut c_void) = std::mem::transmute(base + bv().layout_immediately); layout_immediately(view as *mut c_void); + // The non-client view above the frame view gives the client view the bounds the frame + // view leaves it, so a new appbar width moves the page only when it lays out too. + if let Some(parent) = crate::chromium::view::parent_of(view) { + layout_immediately(parent as *mut c_void); + } true } None => false,