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,