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}
- )}
+