fix(webview2): scale native bounds for fractional DPI

This commit is contained in:
2026-09-18 15:15:12 +08:00
parent 419eb0d005
commit 60c087d7aa
+16 -3
View File
@@ -152,19 +152,32 @@ class WebView2View(QtWidgets.QWidget):
# ---------- 几何同步 ---------- # ---------- 几何同步 ----------
def _dpr(self): def _dpr(self):
try: try:
d = self.dpr() d = float(self.devicePixelRatioF())
return d if d > 0 else 1.0 return d if d > 0 else 1.0
except Exception: except Exception:
return 1.0 return 1.0
@staticmethod
def _physical_bounds(x, y, width, height, dpr):
"""按矩形边界换算物理像素,避免分数 DPR 产生相邻白缝。"""
def pixel(value):
scaled = value * dpr
return int(scaled + 0.5) if scaled >= 0 else int(scaled - 0.5)
left = pixel(x)
top = pixel(y)
right = pixel(x + width)
bottom = pixel(y + height)
return left, top, max(1, right - left), max(1, bottom - top)
def sync_bounds(self): def sync_bounds(self):
if not self.isVisible() or not self._session.child_hwnd: if not self.isVisible() or not self._session.child_hwnd:
return return
top = self.window() top = self.window()
p = self.mapTo(top, QtCore.QPoint(0, 0)) p = self.mapTo(top, QtCore.QPoint(0, 0))
d = self._dpr() d = self._dpr()
L, T = p.x() * d, p.y() * d L, T, W, H = self._physical_bounds(
W, H = max(1, self.width() * d), max(1, self.height() * d) p.x(), p.y(), self.width(), self.height(), d)
# 去重:值没变就不发跨进程 COM(移动窗口时避免主线程被 WebView2 阻塞 → 整窗黑屏) # 去重:值没变就不发跨进程 COM(移动窗口时避免主线程被 WebView2 阻塞 → 整窗黑屏)
# 注:旧版 resize hold(放大时钳制旧尺寸→露白边)已移除 —— # 注:旧版 resize hold(放大时钳制旧尺寸→露白边)已移除 ——
# 拖动黑边的真凶是假异步 JS 泵(已修真异步),高频 SetBounds 实测 Chromium 完全跟得上; # 拖动黑边的真凶是假异步 JS 泵(已修真异步),高频 SetBounds 实测 Chromium 完全跟得上;