diff --git a/plugins/hushreader/CHANGELOG.md b/plugins/hushreader/CHANGELOG.md index bf2be3752..56797d583 100644 --- a/plugins/hushreader/CHANGELOG.md +++ b/plugins/hushreader/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## [1.4.2] - 2026-09-07 + +### Fixed +- **优化隐阅窗口拖拽和拉伸逻辑%**:优化隐阅窗口拖拽和拉伸逻辑,减少粘滞感 + + ## [1.4.1](https://github.com/me1dlinger/hushreader/releases/tag/v1.4.1) - 2026-09-01 ### Added diff --git a/plugins/hushreader/package.json b/plugins/hushreader/package.json index 868302bca..6288ba550 100644 --- a/plugins/hushreader/package.json +++ b/plugins/hushreader/package.json @@ -1,7 +1,7 @@ { "name": "hushreader", "private": true, - "version": "1.4.1", + "version": "1.4.2", "type": "module", "scripts": { "dev": "vite", diff --git a/plugins/hushreader/public/hushreader.html b/plugins/hushreader/public/hushreader.html index b6e48a0da..78df9b46c 100644 --- a/plugins/hushreader/public/hushreader.html +++ b/plugins/hushreader/public/hushreader.html @@ -500,6 +500,8 @@ let pendingMove = null let currentResizeSize = null let currentMovePosition = null + let lastResizeSent = null + let lastMoveSent = null let resizeFrame = 0 let moveFrame = 0 let isAutoHidden = false @@ -757,6 +759,9 @@ const nextSize = pendingResize pendingResize = null + // 位置没变化则跳过,避免无谓的 IPC 往返 + if (lastResizeSent && nextSize.width === lastResizeSent.width && nextSize.height === lastResizeSent.height) return + lastResizeSent = nextSize sendCommand({ type: "resize-preview", width: nextSize.width, @@ -775,6 +780,7 @@ normalizeResizeSize(resizeState?.startWidth || window.innerWidth, resizeState?.startHeight || window.innerHeight) pendingResize = null currentResizeSize = null + lastResizeSent = null sendCommand({ type: "resize", width: nextSize.width, @@ -799,6 +805,9 @@ const nextPosition = pendingMove pendingMove = null + // 位置没变化则跳过,避免无谓的 IPC 往返 + if (lastMoveSent && nextPosition.x === lastMoveSent.x && nextPosition.y === lastMoveSent.y) return + lastMoveSent = nextPosition sendCommand({ type: "move-preview", x: nextPosition.x, @@ -815,6 +824,7 @@ const nextPosition = currentMovePosition || normalizeMovePosition(moveState?.startWindowX || 0, moveState?.startWindowY || 0) pendingMove = null currentMovePosition = null + lastMoveSent = null sendCommand({ type: "move", x: nextPosition.x, diff --git a/plugins/hushreader/public/plugin.json b/plugins/hushreader/public/plugin.json index 4996c2b2d..cc1a59a4a 100644 --- a/plugins/hushreader/public/plugin.json +++ b/plugins/hushreader/public/plugin.json @@ -4,7 +4,7 @@ "title": "隐阅盒", "description": "ZTools自己的摸鱼阅读,支持TXT/EPUB/MOBI格式,沉浸式阅读", "author": "meidlinger", - "version": "1.4.1", + "version": "1.4.2", "main": "index.html", "preload": "preload/services.js", "logo": "logo.png", diff --git a/plugins/hushreader/src/App.vue b/plugins/hushreader/src/App.vue index 955c5e5d6..20da22856 100644 --- a/plugins/hushreader/src/App.vue +++ b/plugins/hushreader/src/App.vue @@ -25,6 +25,8 @@ type AppBrowserWindow = { setSize?: (width: number, height: number) => void setContentSize?: (width: number, height: number) => void setContentBounds?: (bounds: HushreaderBounds) => void + setBounds?: (bounds: HushreaderBounds) => void + setResizable?: (flag: boolean) => void setPosition?: (x: number, y: number) => void setAlwaysOnTop?: (flag: boolean) => void moveTop?: () => void @@ -97,9 +99,22 @@ function clampNumber(value: number, min: number, max: number) { return Math.min(safeMax, Math.max(safeMin, Math.round(safeValue))) } -function getWorkArea() { +// 工作区(显示器可用区域)缓存:拖动/缩放预览期间不反复走 +// ztools.getPrimaryDisplay() 的 IPC,改为短 TTL 缓存,避免每帧一次跨进程查询。 +const WORK_AREA_CACHE_MS = 1000 +let cachedWorkArea: HushreaderBounds | null = null +let cachedWorkAreaAt = 0 + +function getWorkArea(): HushreaderBounds { + const now = Date.now() + if (cachedWorkArea && now - cachedWorkAreaAt < WORK_AREA_CACHE_MS) { + return cachedWorkArea + } const display = (window as any).ztools?.getPrimaryDisplay?.() - return display?.workArea ?? { x: 0, y: 0, width: window.screen.availWidth, height: window.screen.availHeight } + const area: HushreaderBounds = display?.workArea ?? { x: 0, y: 0, width: window.screen.availWidth, height: window.screen.availHeight } + cachedWorkArea = area + cachedWorkAreaAt = now + return area } function getHushreaderSizeLimits() { @@ -227,13 +242,25 @@ function getHushreaderPayload(bounds = getHushreaderWindowBounds()) { } } +// 更新隐阅窗口的位置/尺寸。 +// 关键:每帧(拖动/缩放预览)只发 1 次窗口调用,避免多方法冗余调用。 +// ztools.createBrowserWindow 返回的 Proxy 每个方法都是一次跨进程 IPC, +// 原来连调 setContentBounds / setContentSize / setSize / setPosition 四个方法(它们互相 +// 冗余,setBounds 本来就同时携带位置与尺寸),导致拖动/缩放时每帧多次 IPC 往返、严重不跟手。 +// 阅读窗每帧只发 1 条消息,主窗口只 setBounds 1 次。 +// 窗口为无边框(frame:false)+无阴影,窗口 bounds 与内容 bounds 一致,单次 setBounds 即可。 function applyHushreaderWindowBounds(bounds: HushreaderBounds, positionOnly = false) { if (!hushreaderWindow || hushreaderWindow.isDestroyed?.()) return hushreaderWindowAnchor = { x: bounds.x, y: bounds.y } - hushreaderWindow.setContentBounds?.(bounds) - hushreaderWindow.setContentSize?.(bounds.width, bounds.height) - hushreaderWindow.setSize?.(bounds.width, bounds.height) - hushreaderWindow.setPosition?.(bounds.x, bounds.y) + const rect: HushreaderBounds = { x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height } + if (hushreaderWindow.setBounds) { + hushreaderWindow.setBounds(rect) + } else if (hushreaderWindow.setContentBounds) { + hushreaderWindow.setContentBounds(rect) + } else { + hushreaderWindow.setSize?.(bounds.width, bounds.height) + hushreaderWindow.setPosition?.(bounds.x, bounds.y) + } if (!positionOnly) { hushreaderWindow.setAlwaysOnTop?.(true) hushreaderWindow.setSkipTaskbar?.(true) @@ -314,6 +341,7 @@ function ensureHushreaderWindow(options?: { skipShow?: boolean }) { focusable: true, acceptFirstMouse: true, alwaysOnTop: true, + useContentSize: true, webPreferences: { devTools: false, zoomFactor: 1,