From f269887fe7b81b9c6399217af52dc525822445ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Wed, 8 Jul 2026 14:52:52 +0800 Subject: [PATCH] fix: float browser preview zoom controls (#952) Move the preview zoom control out of the address toolbar and into a bottom-right floating control area inside the browser preview stage. Keep the native WebContentsView bounds clear of the control strip so the DOM control remains interactive on high-DPI Windows displays. Tested: cd desktop && bun run test -- src/components/browser/BrowserSurface.test.tsx Tested: cd desktop && bun run lint Tested: cd desktop && bun run build Not-tested: Windows high-DPI real-device smoke. Confidence: medium Scope-risk: narrow --- .../browser/BrowserSurface.test.tsx | 9 ++++-- .../src/components/browser/BrowserSurface.tsx | 28 +++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/desktop/src/components/browser/BrowserSurface.test.tsx b/desktop/src/components/browser/BrowserSurface.test.tsx index bde22b24..f20294e9 100644 --- a/desktop/src/components/browser/BrowserSurface.test.tsx +++ b/desktop/src/components/browser/BrowserSurface.test.tsx @@ -182,16 +182,19 @@ describe('BrowserSurface', () => { expect(bridge.message).toHaveBeenLastCalledWith({ v: 1, type: 'exit-picker' }) }) - it('renders toolbar preview zoom controls that update the native preview zoom', async () => { + it('renders floating preview zoom controls that update the native preview zoom', async () => { useBrowserPanelStore.getState().open('s1', 'http://localhost:5173/') useBrowserPanelStore.getState().setReady('s1') render() const controls = screen.getByTestId('browser-zoom-controls') const actions = screen.getByTestId('browser-toolbar-actions') + const floatingControls = screen.getByTestId('browser-preview-floating-controls') expect(controls).toHaveTextContent('100%') - expect(actions).toContainElement(controls) - expect(controls.compareDocumentPosition(screen.getByTestId('preview-host')) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy() + expect(actions).not.toContainElement(controls) + expect(floatingControls).toContainElement(controls) + expect(screen.getByTestId('browser-preview-stage')).toContainElement(floatingControls) + expect(screen.getByTestId('preview-host').compareDocumentPosition(floatingControls) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy() fireEvent.click(screen.getByLabelText('缩小预览')) expect(useBrowserPanelStore.getState().bySession['s1']!.zoom).toBe(0.9) diff --git a/desktop/src/components/browser/BrowserSurface.tsx b/desktop/src/components/browser/BrowserSurface.tsx index e7a25b0a..1dbffaf7 100644 --- a/desktop/src/components/browser/BrowserSurface.tsx +++ b/desktop/src/components/browser/BrowserSurface.tsx @@ -208,7 +208,7 @@ export function BrowserSurface({ sessionId }: { sessionId: string }) { } const zoomButtonClass = [ - 'inline-flex h-7 w-7 items-center justify-center rounded-full transition-colors', + 'inline-flex h-8 w-8 items-center justify-center rounded-full transition-colors', 'text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-container-low)] hover:text-[var(--color-text-primary)]', 'disabled:cursor-default disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-[var(--color-text-secondary)]', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)]', @@ -217,7 +217,9 @@ export function BrowserSurface({ sessionId }: { sessionId: string }) { const zoomControls = (
- {zoomControls} ) @@ -317,12 +318,23 @@ export function BrowserSurface({ sessionId }: { sessionId: string }) { rightActions={previewActions} />
-
- {session.loading && ( -
- +
+ {/* WebContentsView renders above DOM, so keep the floating controls outside its bounds. */} +
+ {session.loading && ( +
+ +
+ )} +
+
+
+ {zoomControls}
- )} +