From 93bed6e29f8850e9d95bf169cf3aef4a3b095c54 Mon Sep 17 00:00:00 2001 From: Jeffrey Chen <78434827+TCOTC@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:40:47 +0800 Subject: [PATCH] :art: Fix focus issues on Windows after dialog interactions (#16862) https://github.com/siyuan-note/siyuan/pull/16073 https://github.com/siyuan-note/siyuan/issues/16071 https://github.com/siyuan-note/siyuan/issues/12349 --- app/electron/main.js | 14 ++++--- app/src/boot/onGetConfig.ts | 4 +- app/src/protyle/util/compatibility.ts | 58 ++++++++++++++++++--------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/app/electron/main.js b/app/electron/main.js index eecd8ebdd..b3283b8ed 100644 --- a/app/electron/main.js +++ b/app/electron/main.js @@ -948,12 +948,14 @@ app.whenReady().then(() => { event.sender.send("siyuan-event", "leave-full-screen"); }); }); - ipcMain.on("siyuan-focus-fix", (event) => { - const currentWindow = getWindowByContentId(event.sender.id); - if (currentWindow && process.platform === "win32") { - currentWindow.blur(); - currentWindow.focus(); - } + ipcMain.on("siyuan-confirm-dialog", (event, options) => { + const window = BrowserWindow.fromWebContents(event.sender); + event.returnValue = dialog.showMessageBoxSync(window || BrowserWindow.getFocusedWindow(), options); + }); + ipcMain.on("siyuan-alert-dialog", (event, options) => { + const window = BrowserWindow.fromWebContents(event.sender); + dialog.showMessageBoxSync(window || BrowserWindow.getFocusedWindow(), options); + event.returnValue = undefined; }); ipcMain.on("siyuan-cmd", (event, data) => { let cmd = data; diff --git a/app/src/boot/onGetConfig.ts b/app/src/boot/onGetConfig.ts index b0c846ccd..efd9aa0c2 100644 --- a/app/src/boot/onGetConfig.ts +++ b/app/src/boot/onGetConfig.ts @@ -7,7 +7,7 @@ import * as fs from "fs"; import * as path from "path"; import {afterExport} from "../protyle/export/util"; import {onWindowsMsg} from "../window/onWindowsMsg"; -import {initFocusFix} from "../protyle/util/compatibility"; +import {initNativeDialogOverride} from "../protyle/util/compatibility"; /// #endif import {Constants} from "../constants"; import {appearance} from "../config/appearance"; @@ -70,7 +70,7 @@ export const onGetConfig = (isStart: boolean, app: App) => { initStatus(); initWindow(app); /// #if !BROWSER - initFocusFix(); + initNativeDialogOverride(); /// #endif appearance.onSetAppearance(window.siyuan.config.appearance); initAssets(); diff --git a/app/src/protyle/util/compatibility.ts b/app/src/protyle/util/compatibility.ts index d7dbc97fa..1e4450508 100644 --- a/app/src/protyle/util/compatibility.ts +++ b/app/src/protyle/util/compatibility.ts @@ -576,35 +576,53 @@ export const setStorageVal = (key: string, val: any, cb?: () => void) => { }; /// #if !BROWSER -export const initFocusFix = () => { - if (!isWindows()) { - return; - } +export const initNativeDialogOverride = () => { const originalAlert = window.alert; const originalConfirm = window.confirm; - const fixFocusAfterDialog = () => { - ipcRenderer.send("siyuan-focus-fix"); - }; + window.alert = function (message: string) { try { - const result = originalAlert.call(this, message); - fixFocusAfterDialog(); - return result; - } catch (error) { - console.error("alert error:", error); - fixFocusAfterDialog(); + ipcRenderer.sendSync("siyuan-alert-dialog", { + title: window.siyuan?.languages?.siyuanNote || "SiYuan", + message, + buttons: [window.siyuan?.languages?.confirm || "OK"], + noLink: true, + }); + return undefined; + } catch (error) { + console.error("SiYuan alert error:", error); + try { + const result = originalAlert.call(this, message); + return result; + } catch (e) { + console.error("Original alert error:", e); + return undefined; + } } }; - window.confirm = function (message: string) { + + window.confirm = function (message: string): boolean { try { - const result = originalConfirm.call(this, message); - fixFocusAfterDialog(); - return result; + const buttonIndex = ipcRenderer.sendSync("siyuan-confirm-dialog", { + title: window.siyuan?.languages?.siyuanNote || "SiYuan", + message, + buttons: [window.siyuan?.languages?.cancel || "Cancel", window.siyuan?.languages?.confirm || "OK"], + cancelId: 0, + defaultId: 1, + noLink: true, + }); + + return buttonIndex === 1; } catch (error) { - console.error("confirm error:", error); - fixFocusAfterDialog(); - return false; + console.error("SiYuan confirm error:", error); + try { + const result = originalConfirm.call(this, message); + return result; + } catch (e) { + console.error("Original confirm error:", e); + return false; + } } }; };