[Bug]: Embedded browser view renders a duplicated page and drifts over the chat pane at fractional DPI
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 40/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- rust, typescript
- Bereich
- desktop-dev, frontend
Rechercherichtung
Start in src/web-ui/src/app/scenes/browser/useEmbeddedBrowserWebview.ts, where syncWebviewBounds and the browser_webview_create and browser_webview_set_bounds calls pass CSS-pixel bounds straight to the native host, then check the presentation.isCurrent() guard and the BrowserPreview frozen-frame overlay. Reproduce by setting devicePixelRatio to 1.21 and confirming the child view rect differs from the host rect. Done when the native view matches the host rect at fractional scale and geometry keeps syncing after a lost resize event.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Summary
At a fractional Windows display scale (121%, devicePixelRatio = 1.21), the built-in browser panel renders the page twice: a live interactive view plus a second, magnified and blurred copy to its right. The live view itself is also mispositioned — it is smaller than its host and shifted toward the window origin, so it visually covers the chat pane next to the panel.
Area
Desktop app
Reproduction or evidence
Steps:
- Set the Windows display scale to a fractional value (here: 121%).
- Open the built-in browser panel — either let the agent open any URL, or use the Browser tab.
- Observe that the page is drawn twice, and that the interactive copy does not sit inside the panel.
Measurements (Win32 GetWindowRect on the child view vs. the rectangle the frontend computes for the panel host):
host rect (CSS px) 1325.6, 89.8, 397.5 x 986.2
devicePixelRatio 1.21
child view before 1044, ..., 398 x ... <- CSS numbers applied 1:1 as device pixels
child view after 1604, 109, 481 x 1193 <- expected: rect x 1.21
So the child view was rendered at 1 / 1.21 of its host and pulled toward the window origin by the same factor. At 100% scale the bug is invisible, which is why it only shows up on scaled displays.
Root cause 1 — units. getBoundingClientRect() reports CSS pixels, while browser_webview_create / browser_webview_set_bounds hand those values straight to the native host, which applies them 1:1 without multiplying by the window scale factor. At fractional DPI the child view therefore shrinks and offsets.
src/web-ui/src/app/scenes/browser/useEmbeddedBrowserWebview.ts:
await api.invoke('browser_webview_set_bounds', {
request: { label, x: bounds.left, y: bounds.top, width: bounds.width, height: bounds.height },
});
Root cause 2 — geometry sync can be blocked forever. syncWebviewBounds() returns early when presentationRef.current.isCurrent() is false. A panel that loses the presentation race still renders the visible native view, but it never syncs its geometry again, so the view stays at its creation-time size:
if (!isTauri || !target || !viewportRef.current || !mountedRef.current
|| (targetId && !presentationRef.current?.isCurrent())) return;
The presentation.run() wrapper used for the actual call has the same owner check, so it silently skips too.
Root cause 3 — the frozen frame shows through. BrowserPreview is a decorative JPEG of the native view pinned below it (captured every 5s, object-fit: fill, pointer-events: none). It is only supposed to be visible while a DOM overlay covers the native view. When the geometry above drifts, the stale frame is stretched across the gap and produces exactly the "second, blurred browser" appearance. Additionally the ResizeObserver that drives syncWebviewBounds only reports layout changes it actually witnessed — a panel that mounts at its final size never receives one.
Proposed fix (I have a patch and updated unit tests ready):
- Convert CSS → device pixels once, at the
create/set_boundsboundary:const dpr = window.devicePixelRatio || 1; x: bounds.left * dpr, y: bounds.top * dpr, width: bounds.width * dpr, height: bounds.height * dpr, - Do not gate geometry sync on presentation ownership, and add a periodic reconcile (e.g. 400 ms) so a lost
resizeevent cannot leave the view at its creation size. - Render the frozen frame only on the active panel, and hide inactive panel content (
visibility: hidden).
Happy to open a PR with the patch if that is useful.
Environment, if relevant
OpenBitFun version: 1.0.8 (frontend revision bundled-b5489663e559ac91)
OS: Windows 11 家庭中文版, build 22631
Display: 2560x1440 @ 121% scale
Mode: Desktop app, built-in browser panel (not an external browser)
- Vorherrschende Sprache
- Rust
- Sterne
- 2.3k
- Forks
- 236
- Ø Merge
- 13 Std. 3 Min.
- Gemergte PRs (30 T.)
- 351
Entwicklungsumgebung
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus GCWing/OpenBitFun
-
[Feature]: 模型服务表单缺少「图像生成」分类入口 —— 后端已支持 default_models.image_generationEvtl. vergeben @skyfireitdiy hat das vor 20 Tagen übernommen. Offen
Schwierigkeit 2/5 Ein halber Tag Anfängerfreundlichkeit 74/100
GCWing/OpenBitFun#3279 · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 45/100
GCWing/OpenBitFun#3756 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 48/100
GCWing/OpenBitFun#3744 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Feature]: 允许手动/compact 时传递后续消息Evtl. vergeben @Raing5Days hat das heute übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 25/100
GCWing/OpenBitFun#3739 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Feature]: 增加/model 触发右侧模型选择Evtl. vergeben @Raing5Days hat das heute übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 35/100
GCWing/OpenBitFun#3738 ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in GCWing/OpenBitFun
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
apache/datafusion-iceberg#100 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug]: cua-driver skill fails Agent Skills frontmatter validationEvtl. vergeben @Mearman hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 1 Tag
-
area/tools bug session-analysis
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 80/100
oracle/rust-oracledb#66 ·
-
`PrimitiveArray::validate_decimal_precision` rejects every decimal array with a negative scaleOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag