根本原因: 點穿狀態一直是 renderer 判定後再用 IPC 叫主程序切換。renderer 只要例外、 卡住或狀態錯亂(例如視窗永遠不取得焦點、Windows 對背景視窗的 capture 有限制, 放開的那一下落在視窗外就收不到 mouseup,pressed 從此卡在 true),主程序就 再也收不到切換指令,寵物永遠點不到。另外 2.0.8 起每 2 秒的置頂重宣告會在 右鍵選單開著時把寵物視窗抬到選單上面,2.0.10 改成整個方框接滑鼠後,被蓋住 的選單項目就點不到了。 影響: 偶發「不能拖曳、不能右鍵」,而且發生時沒有任何可查的狀態或紀錄。 修法: 1. 主程序每 50 ms 自己輪詢游標,對照 renderer 回報的人物方框與氣泡矩形 (pet:hit-rects)直接呼叫 setIgnoreMouseEvents;決策邏輯抽成 lib/hit-test.js。 renderer 沒回報或掛掉時用版面公式算方框當備援,並自動重載。 2. 拖曳不管因 mouseup、逾時(20 秒)或其他原因結束,都送 pet:drag-ended 讓 renderer 清掉按住/拖曳狀態。 3. 右鍵選單開著時暫停置頂重宣告。 4. /state 回傳 bounds 與 mouse 診斷(是否點穿、游標相對座標、是否在方框/ 氣泡、矩形來源、切換與輪詢次數、renderer 錯誤、拖曳結束原因);renderer 例外、拖曳開始/結束、選單開關寫入事件紀錄。 版號 2.0.11。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
40 lines
826 B
JavaScript
40 lines
826 B
JavaScript
"use strict";
|
|
const { contextBridge, ipcRenderer } = require("electron");
|
|
|
|
const SEND = new Set([
|
|
"pet:ready",
|
|
"pet:hit-rects",
|
|
"pet:drag-start",
|
|
"pet:drag-end",
|
|
"pet:context-menu",
|
|
"pet:tray-icon",
|
|
"pet:state",
|
|
"pet:log",
|
|
"pet:greeted",
|
|
]);
|
|
|
|
const ON = new Set([
|
|
"pet:init",
|
|
"pet:load",
|
|
"pet:scale",
|
|
"pet:settings",
|
|
"pet:event",
|
|
"pet:cursor",
|
|
"pet:cursor-pos",
|
|
"pet:drag-move",
|
|
"pet:drag-ended",
|
|
"pet:ignore-state",
|
|
]);
|
|
|
|
contextBridge.exposeInMainWorld("pet", {
|
|
send(channel, data) {
|
|
if (SEND.has(channel)) ipcRenderer.send(channel, data);
|
|
},
|
|
on(channel, callback) {
|
|
if (!ON.has(channel)) return () => {};
|
|
const listener = (_event, data) => callback(data);
|
|
ipcRenderer.on(channel, listener);
|
|
return () => ipcRenderer.removeListener(channel, listener);
|
|
},
|
|
});
|