Auto-hide the menu bar in web popups and re-layout when it appears (#28388)

On Windows and Linux, Orca's app menu is attached to every window, including web popups, so it permanently takes up vertical space above the popup content. Popups now hide that menu by default, so they match a normal browser window. Alt still reveals it, but revealing it shrinks the content area without resizing the window. The origin bar and content view kept their old heights, which left a gap or clipped content. The popup now listens for `bounds-changed` on its content view and re-runs its layout, so the content fills the space under the revealed menu bar.
This commit is contained in:
Jinjing
2026-10-13 13:01:58 -07:00
committed by GitHub
parent c5d7628686
commit 06a05b2e56
2 changed files with 42 additions and 9 deletions
@@ -64,16 +64,31 @@ const { fakeElectron } = vi.hoisted(() => {
}
}
class FakeContentView {
private handlers = new Map<string, Handler[]>()
addChildView = vi.fn()
on(event: string, handler: Handler): void {
this.handlers.set(event, [...(this.handlers.get(event) ?? []), handler])
}
emit(event: string): void {
for (const handler of this.handlers.get(event) ?? []) {
handler()
}
}
}
class FakeBaseWindow {
static instances: FakeBaseWindow[] = []
options: Record<string, unknown>
private handlers = new Map<string, Handler[]>()
contentView = { addChildView: vi.fn() }
contentView = new FakeContentView()
contentSize: { width: number; height: number }
setTitle = vi.fn()
isDestroyed = vi.fn(() => false)
close = vi.fn(() => this.emit('closed'))
constructor(options: Record<string, unknown>) {
this.options = options
this.contentSize = { width: Number(options.width), height: Number(options.height) }
FakeBaseWindow.instances.push(this)
}
on(event: string, handler: Handler): void {
@@ -83,12 +98,7 @@ const { fakeElectron } = vi.hoisted(() => {
this.on(event, handler)
}
getContentBounds(): { x: number; y: number; width: number; height: number } {
return {
x: 0,
y: 0,
width: this.options.width as number,
height: this.options.height as number
}
return { x: 0, y: 0, ...this.contentSize }
}
emit(event: string, ...args: unknown[]): void {
for (const handler of this.handlers.get(event) ?? []) {
@@ -203,7 +213,8 @@ describe('openPopupWithOriginBar', () => {
expect(lastWindow().options).toMatchObject({
width: 500,
height: 400 + POPUP_ORIGIN_BAR_HEIGHT
height: 400 + POPUP_ORIGIN_BAR_HEIGHT,
autoHideMenuBar: true
})
const { bar, content } = lastViews()
expect(bar.setBounds).toHaveBeenCalledWith({
@@ -220,6 +231,24 @@ describe('openPopupWithOriginBar', () => {
})
})
it('re-lays out when the revealed menu bar shrinks the content area', () => {
openPopupWithOriginBar(
{ webContents: createFakeWebContents() as never, width: 500, height: 400 },
'https://example.com/'
)
const window = lastWindow()
const menuBarHeight = 25
window.contentSize = { width: 500, height: 400 + POPUP_ORIGIN_BAR_HEIGHT - menuBarHeight }
window.contentView.emit('bounds-changed')
expect(lastViews().content.setBounds).toHaveBeenLastCalledWith({
x: 0,
y: POPUP_ORIGIN_BAR_HEIGHT,
width: 500,
height: 400 - menuBarHeight
})
})
it('keeps the origin bar isolated with locked-down webPreferences', () => {
openPopupWithOriginBar(
{ webContents: createFakeWebContents() as never },
+5 -1
View File
@@ -155,7 +155,9 @@ export function openPopupWithOriginBar(
: {}),
minWidth: MIN_POPUP_CONTENT_WIDTH,
minHeight: MIN_POPUP_CONTENT_HEIGHT + POPUP_ORIGIN_BAR_HEIGHT,
title: initialOrigin.label
title: initialOrigin.label,
// Why: Windows/Linux attach Orca's app menu to every window, including web popups.
autoHideMenuBar: true
})
// Why: the origin bar renders only Orca's own data: URL and must stay
@@ -184,6 +186,8 @@ export function openPopupWithOriginBar(
})
}
window.on('resize', layoutViews)
// Why: Alt-revealing the auto-hidden menu bar shrinks the content area without resizing the window.
window.contentView.on('bounds-changed', layoutViews)
// Why: HTML5 fullscreen makes the whole window fullscreen. resize covers
// this on macOS, but re-pin on the explicit events too so the origin bar
// provably stays above fullscreen content on every platform.