mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
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:
@@ -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 },
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user