diff --git a/app/appearance/langs/ar_SA.json b/app/appearance/langs/ar_SA.json index 829794c325d..6bec5382882 100644 --- a/app/appearance/langs/ar_SA.json +++ b/app/appearance/langs/ar_SA.json @@ -1462,6 +1462,16 @@ "recentOpened": "تم فتحها مؤخراً", "recentClosed": "تم إغلاقها مؤخراً", "recentModified": "تم تعديلها مؤخراً", + "appMenuAbout": "حول SiYuan", + "appMenuServices": "الخدمات", + "appMenuHide": "إخفاء SiYuan", + "appMenuHideOthers": "إخفاء الأخرى", + "appMenuQuit": "إنهاء SiYuan", + "appMenuPasteAndMatchStyle": "لصق ومطابقة التنسيق", + "appMenuTogglefullscreen": "ملء الشاشة", + "appMenuBringAllToFront": "إحضار الكل إلى المقدمة", + "appMenuWindow": "النافذة", + "appMenuMinimize": "تصغير", "_label": "العربية", "_time": { "albl": "من قبل", diff --git a/app/appearance/langs/de_DE.json b/app/appearance/langs/de_DE.json index 72f8207f03a..c44db0c6154 100644 --- a/app/appearance/langs/de_DE.json +++ b/app/appearance/langs/de_DE.json @@ -1462,6 +1462,16 @@ "recentOpened": "Zuletzt geöffnet", "recentClosed": "Zuletzt geschlossen", "recentModified": "Zuletzt geändert", + "appMenuAbout": "Über SiYuan", + "appMenuServices": "Dienste", + "appMenuHide": "SiYuan ausblenden", + "appMenuHideOthers": "Andere ausblenden", + "appMenuQuit": "SiYuan beenden", + "appMenuPasteAndMatchStyle": "Einsetzen und Formatierung übernehmen", + "appMenuTogglefullscreen": "Vollbild umschalten", + "appMenuBringAllToFront": "Alle nach vorne", + "appMenuWindow": "Fenster", + "appMenuMinimize": "Im Dock ablegen", "_label": "Deutsch", "_time": { "albl": "vor", diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 8df487c8457..8a362e04a7f 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1462,6 +1462,16 @@ "recentOpened": "Recently Opened", "recentClosed": "Recently Closed", "recentModified": "Recently Modified", + "appMenuAbout": "About SiYuan", + "appMenuServices": "Services", + "appMenuHide": "Hide SiYuan", + "appMenuHideOthers": "Hide Others", + "appMenuQuit": "Quit SiYuan", + "appMenuPasteAndMatchStyle": "Paste and Match Style", + "appMenuTogglefullscreen": "Toggle Full Screen", + "appMenuBringAllToFront": "Bring All to Front", + "appMenuWindow": "Window", + "appMenuMinimize": "Minimize", "_label": "English", "_time": { "albl": "ago", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 516fc92ef98..4ce7279ce42 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1462,6 +1462,16 @@ "recentOpened": "Abierto recientemente", "recentClosed": "Cerrado recientemente", "recentModified": "Modificado recientemente", + "appMenuAbout": "Acerca de SiYuan", + "appMenuServices": "Servicios", + "appMenuHide": "Ocultar SiYuan", + "appMenuHideOthers": "Ocultar otros", + "appMenuQuit": "Salir de SiYuan", + "appMenuPasteAndMatchStyle": "Pegar y combinar formato", + "appMenuTogglefullscreen": "Pantalla completa", + "appMenuBringAllToFront": "Traer todo al frente", + "appMenuWindow": "Ventana", + "appMenuMinimize": "Minimizar", "_label": "Español", "_time": { "albl": "hace", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 13925f39d53..d85d83db759 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1462,6 +1462,16 @@ "recentOpened": "Récemment ouvert", "recentClosed": "Récemment fermé", "recentModified": "Récemment modifié", + "appMenuAbout": "À propos de SiYuan", + "appMenuServices": "Services", + "appMenuHide": "Masquer SiYuan", + "appMenuHideOthers": "Masquer les autres", + "appMenuQuit": "Quitter SiYuan", + "appMenuPasteAndMatchStyle": "Coller et adapter le style", + "appMenuTogglefullscreen": "Basculer en plein écran", + "appMenuBringAllToFront": "Tout ramener au premier plan", + "appMenuWindow": "Fenêtre", + "appMenuMinimize": "Réduire", "_label": "Français", "_time": { "albl": "Précédemment", diff --git a/app/appearance/langs/he_IL.json b/app/appearance/langs/he_IL.json index d7b514d0f2f..d1ac14e2666 100644 --- a/app/appearance/langs/he_IL.json +++ b/app/appearance/langs/he_IL.json @@ -1462,6 +1462,16 @@ "recentOpened": "נפתח לאחרונה", "recentClosed": "נסגר לאחרונה", "recentModified": "שונה לאחרונה", + "appMenuAbout": "אודות SiYuan", + "appMenuServices": "שירותים", + "appMenuHide": "הסתר את SiYuan", + "appMenuHideOthers": "הסתר אחרים", + "appMenuQuit": "צא מ-SiYuan", + "appMenuPasteAndMatchStyle": "הדבק והתאם לסגנון", + "appMenuTogglefullscreen": "מסך מלא", + "appMenuBringAllToFront": "הבא את הכול לחזית", + "appMenuWindow": "חלון", + "appMenuMinimize": "מזער", "_label": "עברית", "_time": { "albl": "לפני", diff --git a/app/appearance/langs/it_IT.json b/app/appearance/langs/it_IT.json index 15b27326414..bc00f59c109 100644 --- a/app/appearance/langs/it_IT.json +++ b/app/appearance/langs/it_IT.json @@ -1462,6 +1462,16 @@ "recentOpened": "Aperto di recente", "recentClosed": "Chiuso di recente", "recentModified": "Modificato di recente", + "appMenuAbout": "Informazioni su SiYuan", + "appMenuServices": "Servizi", + "appMenuHide": "Nascondi SiYuan", + "appMenuHideOthers": "Nascondi altre app", + "appMenuQuit": "Chiudi SiYuan", + "appMenuPasteAndMatchStyle": "Incolla e mantieni formattazione", + "appMenuTogglefullscreen": "Schermo intero", + "appMenuBringAllToFront": "Porta tutto in primo piano", + "appMenuWindow": "Finestra", + "appMenuMinimize": "Contrai", "_label": "Italiano", "_time": { "albl": "fa", diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index 7b871b7b5ae..14ecc142294 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1462,6 +1462,16 @@ "recentOpened": "最近開いた", "recentClosed": "最近閉じた", "recentModified": "最近更新", + "appMenuAbout": "SiYuan について", + "appMenuServices": "サービス", + "appMenuHide": "SiYuan を隠す", + "appMenuHideOthers": "ほかを隠す", + "appMenuQuit": "SiYuan を終了", + "appMenuPasteAndMatchStyle": "スタイルを合わせてペースト", + "appMenuTogglefullscreen": "フルスクリーンの切り替え", + "appMenuBringAllToFront": "すべてを手前に移動", + "appMenuWindow": "ウィンドウ", + "appMenuMinimize": "しまう", "_label": "日本語", "_time": { "albl": "前", diff --git a/app/appearance/langs/ko_KR.json b/app/appearance/langs/ko_KR.json index 75131d29a50..ad814debef3 100644 --- a/app/appearance/langs/ko_KR.json +++ b/app/appearance/langs/ko_KR.json @@ -1462,6 +1462,16 @@ "recentOpened": "최근 열림", "recentClosed": "최근 닫힘", "recentModified": "최근 수정됨", + "appMenuAbout": "SiYuan 정보", + "appMenuServices": "서비스", + "appMenuHide": "SiYuan 숨기기", + "appMenuHideOthers": "기타 가리기", + "appMenuQuit": "SiYuan 종료", + "appMenuPasteAndMatchStyle": "스타일에 맞게 붙여넣기", + "appMenuTogglefullscreen": "전체 화면 전환", + "appMenuBringAllToFront": "모두 앞으로 가져오기", + "appMenuWindow": "윈도우", + "appMenuMinimize": "축소", "_label": "한국어", "_time": { "albl": "전", diff --git a/app/appearance/langs/pl_PL.json b/app/appearance/langs/pl_PL.json index b893cb45f52..8c60fb44754 100644 --- a/app/appearance/langs/pl_PL.json +++ b/app/appearance/langs/pl_PL.json @@ -1462,6 +1462,16 @@ "recentOpened": "Ostatnio otwarte", "recentClosed": "Ostatnio zamknięte", "recentModified": "Ostatnio modyfikowane", + "appMenuAbout": "O programie SiYuan", + "appMenuServices": "Usługi", + "appMenuHide": "Ukryj SiYuan", + "appMenuHideOthers": "Ukryj pozostałe", + "appMenuQuit": "Zakończ SiYuan", + "appMenuPasteAndMatchStyle": "Wklej i dopasuj styl", + "appMenuTogglefullscreen": "Pełny ekran", + "appMenuBringAllToFront": "Przenieś wszystkie na wierzch", + "appMenuWindow": "Okno", + "appMenuMinimize": "Minimalizuj", "_label": "Polski", "_time": { "albl": "temu", diff --git a/app/appearance/langs/pt_BR.json b/app/appearance/langs/pt_BR.json index 02d69668baf..25555efa05a 100644 --- a/app/appearance/langs/pt_BR.json +++ b/app/appearance/langs/pt_BR.json @@ -1462,6 +1462,16 @@ "recentOpened": "Aberto recentemente", "recentClosed": "Fechado recentemente", "recentModified": "Modificado recentemente", + "appMenuAbout": "Sobre o SiYuan", + "appMenuServices": "Serviços", + "appMenuHide": "Ocultar SiYuan", + "appMenuHideOthers": "Ocultar outros", + "appMenuQuit": "Encerrar SiYuan", + "appMenuPasteAndMatchStyle": "Colar e combinar estilo", + "appMenuTogglefullscreen": "Tela cheia", + "appMenuBringAllToFront": "Trazer tudo para a frente", + "appMenuWindow": "Janela", + "appMenuMinimize": "Minimizar", "_label": "Português (Brasil)", "_time": { "albl": "atrás", diff --git a/app/appearance/langs/ru_RU.json b/app/appearance/langs/ru_RU.json index 90fb14c96f5..25187ca1c33 100644 --- a/app/appearance/langs/ru_RU.json +++ b/app/appearance/langs/ru_RU.json @@ -1462,6 +1462,16 @@ "recentOpened": "Недавно открытые", "recentClosed": "Недавно закрытые", "recentModified": "Недавно изменённые", + "appMenuAbout": "О программе SiYuan", + "appMenuServices": "Службы", + "appMenuHide": "Скрыть SiYuan", + "appMenuHideOthers": "Скрыть остальные", + "appMenuQuit": "Завершить SiYuan", + "appMenuPasteAndMatchStyle": "Вставить с учётом стиля", + "appMenuTogglefullscreen": "Полноэкранный режим", + "appMenuBringAllToFront": "Все окна на передний план", + "appMenuWindow": "Окно", + "appMenuMinimize": "Свернуть", "_label": "Русский", "_time": { "albl": "назад", diff --git a/app/appearance/langs/sk_SK.json b/app/appearance/langs/sk_SK.json index 23eb6b0452d..4f8c242dda2 100644 --- a/app/appearance/langs/sk_SK.json +++ b/app/appearance/langs/sk_SK.json @@ -1462,6 +1462,16 @@ "recentOpened": "Naposledy otvorené", "recentClosed": "Naposledy zatvorené", "recentModified": "Naposledy upravené", + "appMenuAbout": "O aplikácii SiYuan", + "appMenuServices": "Služby", + "appMenuHide": "Skryť SiYuan", + "appMenuHideOthers": "Skryť ostatné", + "appMenuQuit": "Ukončiť SiYuan", + "appMenuPasteAndMatchStyle": "Vložiť a prispôsobiť štýl", + "appMenuTogglefullscreen": "Celá obrazovka", + "appMenuBringAllToFront": "Presunúť všetko dopredu", + "appMenuWindow": "Okno", + "appMenuMinimize": "Minimalizovať", "_label": "Slovenčina", "_time": { "albl": "pred", diff --git a/app/appearance/langs/tr_TR.json b/app/appearance/langs/tr_TR.json index cedc76b3842..7e1d16e418e 100644 --- a/app/appearance/langs/tr_TR.json +++ b/app/appearance/langs/tr_TR.json @@ -1462,6 +1462,16 @@ "recentOpened": "Son açılanlar", "recentClosed": "Son kapatılanlar", "recentModified": "Son değiştirilenler", + "appMenuAbout": "SiYuan Hakkında", + "appMenuServices": "Hizmetler", + "appMenuHide": "SiYuan'ı Gizle", + "appMenuHideOthers": "Diğerlerini Gizle", + "appMenuQuit": "SiYuan'dan Çık", + "appMenuPasteAndMatchStyle": "Biçimi Koruyarak Yapıştır", + "appMenuTogglefullscreen": "Tam Ekran", + "appMenuBringAllToFront": "Tümünü Öne Getir", + "appMenuWindow": "Pencere", + "appMenuMinimize": "Küçült", "_label": "Türkçe", "_time": { "albl": "önce", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 1620f0fa71b..69a0fc3c362 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1462,6 +1462,16 @@ "recentOpened": "最近開啟", "recentClosed": "最近關閉", "recentModified": "最近更新", + "appMenuAbout": "關於思源筆記", + "appMenuServices": "服務", + "appMenuHide": "隱藏思源筆記", + "appMenuHideOthers": "隱藏其他", + "appMenuQuit": "結束思源筆記", + "appMenuPasteAndMatchStyle": "貼上並符合樣式", + "appMenuTogglefullscreen": "切換全螢幕", + "appMenuBringAllToFront": "將所有視窗移到最上層", + "appMenuWindow": "視窗", + "appMenuMinimize": "最小化", "_label": "繁體中文", "_time": { "albl": "前", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 40adf3e854c..2db0cde30b4 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1462,6 +1462,16 @@ "recentOpened": "最近打开", "recentClosed": "最近关闭", "recentModified": "最近修改", + "appMenuAbout": "关于思源笔记", + "appMenuServices": "服务", + "appMenuHide": "隐藏思源笔记", + "appMenuHideOthers": "隐藏其他", + "appMenuQuit": "退出思源笔记", + "appMenuPasteAndMatchStyle": "粘贴并匹配样式", + "appMenuTogglefullscreen": "切换全屏幕", + "appMenuBringAllToFront": "前置全部窗口", + "appMenuWindow": "窗口", + "appMenuMinimize": "最小化", "_label": "简体中文", "_time": { "albl": "前", diff --git a/app/electron/main.js b/app/electron/main.js index bea584bbe87..04d2f6df38c 100644 --- a/app/electron/main.js +++ b/app/electron/main.js @@ -127,7 +127,7 @@ const windowNavigate = (currentWindow, windowType) => { } // 其他链接使用浏览器打开 event.preventDefault(); - shell.openExternal(url); + void shell.openExternal(url); }); }; @@ -492,30 +492,6 @@ const initMainWindow = () => { writeLog("Render process gone [reason=" + details.reason + ", exitCode=" + details.exitCode + "]"); }); - if (windowState.isDevToolsOpened) { - currentWindow.webContents.openDevTools({mode: "bottom"}); - } - - // 菜单 - const productName = "SiYuan"; - const template = [{ - label: productName, submenu: [{ - label: `About ${productName}`, role: "about", - }, {type: "separator"}, {role: "services"}, {type: "separator"}, { - label: `Hide ${productName}`, role: "hide", - }, {role: "hideOthers"}, {role: "unhide"}, {type: "separator"}, { - label: `Quit ${productName}`, role: "quit", - },], - }, { - role: "editMenu", submenu: [{role: "cut"}, {role: "copy"}, {role: "paste"}, { - role: "pasteAndMatchStyle", accelerator: "CmdOrCtrl+Shift+C" - }, {role: "selectAll"},], - }, { - role: "windowMenu", - submenu: [{role: "minimize"}, {role: "zoom"}, {role: "togglefullscreen"}, {type: "separator"}, {role: "toggledevtools"}, {type: "separator"}, {role: "front"},], - },]; - const menu = Menu.buildFromTemplate(template); - Menu.setApplicationMenu(menu); // 当前页面链接使用浏览器打开 windowNavigate(currentWindow, "app"); currentWindow.on("close", (event) => { @@ -537,6 +513,9 @@ const initMainWindow = () => { } else { currentWindow.unmaximize(); } + if (windowState.isDevToolsOpened) { + currentWindow.webContents.openDevTools(); // 保证开发者工具窗口在前 + } } if (bootWindow && !bootWindow.isDestroyed()) { bootWindow.destroy(); @@ -734,6 +713,9 @@ const initKernel = (workspace, port, lang) => { }; app.whenReady().then(() => { + if (process.platform === "darwin") { + Menu.setApplicationMenu(Menu.buildFromTemplate([{ role: "appMenu" }])); + } const resetTrayMenu = (tray, lang, mainWindow) => { if (!mainWindow || mainWindow.isDestroyed()) { return; @@ -745,11 +727,11 @@ app.whenReady().then(() => { }, }, { label: lang.officialWebsite, click: () => { - shell.openExternal("https://b3log.org/siyuan/"); + void shell.openExternal("https://b3log.org/siyuan/"); }, }, { label: lang.openSource, click: () => { - shell.openExternal("https://github.com/siyuan-note/siyuan"); + void shell.openExternal("https://github.com/siyuan-note/siyuan"); }, }, { label: lang.resetWindow, type: "checkbox", click: v => { @@ -802,10 +784,143 @@ app.whenReady().then(() => { resetTrayMenu(tray, lang, mainWindow); }; - - const getWindowByContentId = (id) => { - return BrowserWindow.getAllWindows().find((win) => win.webContents.id === id); + const toggleMainWindow = (mainWindow) => { + if (!mainWindow || mainWindow.isDestroyed()) { + return; + } + if (mainWindow.isMinimized()) { + mainWindow.restore(); + mainWindow.show(); // 按 `Alt+M` 后隐藏窗口,再次按 `Alt+M` 显示窗口后会卡住不能编辑 https://github.com/siyuan-note/siyuan/issues/8456 + } else if (mainWindow.isVisible()) { + if (!mainWindow.isFocused()) { + mainWindow.show(); + } else { + hideWindow(mainWindow); + } + } else { + mainWindow.show(); + } + }; + const getActiveOrFirstWindow = () => { + let wnd = BrowserWindow.getFocusedWindow(); + if (!wnd || wnd.isDestroyed()) { + wnd = BrowserWindow.getAllWindows().find((w) => !w.isDestroyed()); + } + return (wnd && !wnd.isDestroyed()) ? wnd : null; + }; + const withHotkey = (hotkey) => { + if (typeof hotkey !== "string" || !hotkey.length) { + return {}; + } + const acc = hotKey2Electron(hotkey); + return acc ? {accelerator: acc} : {}; }; + ipcMain.on("siyuan-sync-app-menu", (event, sync) => { + if ("darwin" !== process.platform) { + return; + } + if (!sync || !sync.i18n || typeof sync.i18n !== "object" || !sync.hotkey || typeof sync.hotkey !== "object") { + return; + } + /** @type {import("electron").MenuItemConstructorOptions[]} */ + const template = [{ + role: "appMenu", + label: app.name, + submenu: [ + {role: "about", label: sync.i18n.about || "About SiYuan"}, + ...(sync.readonly ? [] : [{ + label: sync.i18n.config || "Settings", + click: () => { + getActiveOrFirstWindow()?.webContents.send("siyuan-open-setting"); + }, + ...withHotkey(sync.hotkey.config), + }]), + {type: "separator"}, + {role: "services", label: sync.i18n.services || "Services"}, + {type: "separator"}, + { + label: sync.i18n.toggleMainWindow || "Hide/Show Window", + click: () => { + toggleMainWindow(getActiveOrFirstWindow()); + }, + ...withHotkey(sync.hotkey.toggleWin), + }, + {role: "hide", label: sync.i18n.hide || "Hide SiYuan"}, + {role: "hideOthers", label: sync.i18n.hideOthers || "Hide Others"}, + {role: "unhide", label: sync.i18n.showAll || "Show All"}, + {type: "separator"}, + {role: "quit", label: sync.i18n.quit || "Quit SiYuan"}, + ], + }, { + role: "editMenu", + label: sync.i18n.edit || "Edit", + submenu: [ + {role: "undo", label: sync.i18n.undo || "Undo", ...withHotkey(sync.hotkey.undo)}, + {role: "redo", label: sync.i18n.redo || "Redo", ...withHotkey(sync.hotkey.redo)}, + {type: "separator"}, + {role: "cut", label: sync.i18n.cut || "Cut"}, + {role: "copy", label: sync.i18n.copy || "Copy"}, + {role: "paste", label: sync.i18n.paste || "Paste"}, + {role: "pasteAndMatchStyle", label: sync.i18n.pasteAndMatchStyle || "Paste and Match Style"}, + {type: "separator"}, + {role: "selectAll", label: sync.i18n.selectAll || "Select All"}, + ], + }, { + role: "windowMenu", + label: sync.i18n.window || "Window", + submenu: [ + {role: "minimize", label: sync.i18n.minimize || "Minimize"}, + {role: "zoom", label: sync.i18n.zoom || "Zoom"}, + {role: "togglefullscreen", label: sync.i18n.togglefullscreen || "Toggle Full Screen"}, + {type: "separator"}, + { + label: sync.i18n.bringAllToFront || "Bring All to Front", + click: () => { + const windows = BrowserWindow.getAllWindows(); + windows.forEach(showWindow); + const target = (latestActiveWindow && !latestActiveWindow.isDestroyed() && windows.includes(latestActiveWindow)) + ? latestActiveWindow + : windows[0]; + target?.focus(); + }, + }, + ], + }, { + role: "help", + label: sync.i18n.help || "Help", + submenu: [ + ...(sync.readonly ? [] : [{ + label: sync.i18n.userGuide || "User Guide", + click: () => { + getActiveOrFirstWindow()?.webContents.send("siyuan-open-help"); + }, + }]), + { + label: sync.i18n.feedback || "Feedback", + click: () => { + const feedbackUrl = (sync.lang === "zh_CN" || sync.lang === "zh_CHT") + ? "https://ld246.com/article/1649901726096" + : "https://liuyun.io/article/1686530886208"; + void shell.openExternal(feedbackUrl); + }, + }, + { + label: sync.i18n.officialWebsite || "Visit official website", + click: () => { + void shell.openExternal("https://b3log.org/siyuan"); + }, + }, + { + label: sync.i18n.openSource || "Visit project on GitHub", + click: () => { + void shell.openExternal("https://github.com/siyuan-note/siyuan"); + }, + }, + {role: "toggledevtools", label: sync.i18n.debug || "Developer Tools"}, + ], + }]; + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + }); ipcMain.on("siyuan-context-menu", (event, langs) => { const template = [new MenuItem({ role: "undo", label: langs.undo @@ -837,6 +952,9 @@ app.whenReady().then(() => { ipcMain.on("siyuan-first-quit", () => { app.exit(); }); + const getWindowByContentId = (id) => { + return BrowserWindow.getAllWindows().find((win) => win.webContents.id === id); + }; ipcMain.handle("siyuan-get", (event, data) => { if (data.cmd === "clipboardRead") { return clipboard.read(data.format); @@ -971,10 +1089,25 @@ app.whenReady().then(() => { }); break; case "openPath": - shell.openPath(data.filePath); + void shell.openPath(data.filePath); + break; + case "openDevTools": { + /** @type {import("electron").OpenDevToolsOptions} */ + const options = {}; + if (["left", "right", "bottom", "undocked", "detach"].includes(data.mode)) { + options.mode = data.mode; + } + if (typeof data.activate === "boolean") { + options.activate = data.activate; + } + if (typeof data.title === "string") { + options.title = data.title; + } + event.sender.openDevTools(options); break; - case "openDevTools": - event.sender.openDevTools({mode: "bottom"}); + } + case "toggleDevTools": + event.sender.toggleDevTools(); break; case "unregisterGlobalShortcut": if (data.accelerator) { @@ -1276,20 +1409,7 @@ app.whenReady().then(() => { return; } const mainWindow = currentWorkspace.browserWindow; - if (mainWindow.isMinimized()) { - mainWindow.restore(); - mainWindow.show(); // 按 `Alt+M` 后隐藏窗口,再次按 `Alt+M` 显示窗口后会卡住不能编辑 https://github.com/siyuan-note/siyuan/issues/8456 - } else { - if (mainWindow.isVisible()) { - if (!mainWindow.isFocused()) { - mainWindow.show(); - } else { - hideWindow(mainWindow); - } - } else { - mainWindow.show(); - } - } + toggleMainWindow(mainWindow); if ("win32" === process.platform || "linux" === process.platform) { resetTrayMenu(currentWorkspace.tray, data.languages, mainWindow); } @@ -1518,7 +1638,7 @@ app.on("web-contents-created", (webContentsCreatedEvent, contents) => { return; } // 在编辑器内打开链接的处理,比如 iframe 上的打开链接。 - shell.openExternal(details.url); + void shell.openExternal(details.url); return {action: "deny"}; }); }); diff --git a/app/src/boot/globalEvent/commonHotkey.ts b/app/src/boot/globalEvent/commonHotkey.ts index fdc7c499126..6388c3f192b 100644 --- a/app/src/boot/globalEvent/commonHotkey.ts +++ b/app/src/boot/globalEvent/commonHotkey.ts @@ -131,11 +131,71 @@ export const correctHotkey = (app: App) => { }, () => { /// #if !BROWSER sendGlobalShortcut(app); + syncAppMenuShortcuts(); /// #endif }); } }; +let lastHotkeys: Record; + +export const syncAppMenuShortcuts = () => { + /// #if !BROWSER + if (!isMac()) { + return; + } + const appMenuHotkeyItems: Record = { + config: window.siyuan.config.keymap.general.config, + toggleWin: window.siyuan.config.keymap.general.toggleWin, + undo: window.siyuan.config.keymap.editor.general.undo, + redo: window.siyuan.config.keymap.editor.general.redo, + }; + const hotkey: Record = {}; + Object.keys(appMenuHotkeyItems).forEach(id => { + const item = appMenuHotkeyItems[id]; + hotkey[id] = item.custom || item.default || ""; + }); + if (lastHotkeys && Object.keys(appMenuHotkeyItems).every(id => lastHotkeys[id] === hotkey[id])) { + return; + } + lastHotkeys = {...hotkey}; + ipcRenderer.send(Constants.SIYUAN_SYNC_APP_MENU, { + lang: window.siyuan.config.lang, + readonly: window.siyuan.config.readonly, + hotkey, + i18n: { + config: window.siyuan.languages.config, + about: window.siyuan.languages.appMenuAbout, + services: window.siyuan.languages.appMenuServices, + toggleMainWindow: window.siyuan.languages.toggleWin, + hide: window.siyuan.languages.appMenuHide, + hideOthers: window.siyuan.languages.appMenuHideOthers, + showAll: window.siyuan.languages.showAll, + quit: window.siyuan.languages.appMenuQuit, + edit: window.siyuan.languages.edit, + undo: window.siyuan.languages.undo, + redo: window.siyuan.languages.redo, + cut: window.siyuan.languages.cut, + copy: window.siyuan.languages.copy, + paste: window.siyuan.languages.paste, + pasteAndMatchStyle: window.siyuan.languages.appMenuPasteAndMatchStyle, + selectAll: window.siyuan.languages.selectAll, + window: window.siyuan.languages.appMenuWindow, + minimize: window.siyuan.languages.appMenuMinimize, + zoom: window.siyuan.languages.zoom, + togglefullscreen: window.siyuan.languages.appMenuTogglefullscreen, + help: window.siyuan.languages.help, + userGuide: window.siyuan.languages.userGuide, + feedback: window.siyuan.languages.feedback, + debug: window.siyuan.languages.debug, + officialWebsite: window.siyuan.languages._trayMenu.officialWebsite, + openSource: window.siyuan.languages._trayMenu.openSource, + bringAllToFront: window.siyuan.languages.appMenuBringAllToFront, + }, + }); + /// #endif +}; + export const filterHotkey = (event: KeyboardEvent, app: App) => { // https://github.com/siyuan-note/siyuan/issues/9848 忘记为什么要阻止了 .av__mask 的情况,测了下没问题就先移除 if (document.getElementById("progress") || document.getElementById("errorLog") || event.isComposing) { diff --git a/app/src/boot/onGetConfig.ts b/app/src/boot/onGetConfig.ts index 93b1f93b431..f10471714f7 100644 --- a/app/src/boot/onGetConfig.ts +++ b/app/src/boot/onGetConfig.ts @@ -20,12 +20,14 @@ import {initStatus} from "../layout/status"; import {showMessage} from "../dialog/message"; import {replaceLocalPath} from "../editor/rename"; import {initBar} from "../layout/topBar"; +import {openSetting} from "../config"; +import {mountHelp} from "../util/mount"; import {openChangelog} from "./openChangelog"; import {App} from "../index"; import {initWindowEvent} from "./globalEvent/event"; import {sendGlobalShortcut} from "./globalEvent/keydown"; import {closeWindow} from "../window/closeWin"; -import {correctHotkey} from "./globalEvent/commonHotkey"; +import {correctHotkey, syncAppMenuShortcuts} from "./globalEvent/commonHotkey"; import {recordBeforeResizeTop} from "../protyle/util/resize"; import {processSYLink} from "../editor/openLink"; import {getAllEditor} from "../layout/getAll"; @@ -181,6 +183,12 @@ export const initWindow = async (app: App) => { } openFile(data); }); + ipcRenderer.on(Constants.SIYUAN_OPEN_SETTING, () => { + openSetting(app); + }); + ipcRenderer.on(Constants.SIYUAN_OPEN_HELP, () => { + mountHelp(); + }); ipcRenderer.on(Constants.SIYUAN_SAVE_CLOSE, (event, close) => { if (isWindow()) { closeWindow(app); @@ -389,6 +397,7 @@ ${response.data.replace("%pages", "").replace("%pa } }); } + syncAppMenuShortcuts(); /// #else if (!isWindow()) { document.querySelector(".toolbar").classList.add("toolbar--browser"); diff --git a/app/src/config/keymap.ts b/app/src/config/keymap.ts index e43dba12b8b..b544457109e 100644 --- a/app/src/config/keymap.ts +++ b/app/src/config/keymap.ts @@ -10,6 +10,7 @@ import {ipcRenderer} from "electron"; import {sendUnregisterGlobalShortcut} from "../boot/globalEvent/keydown"; /// #endif import {sendGlobalShortcut} from "../boot/globalEvent/keydown"; +import {syncAppMenuShortcuts} from "../boot/globalEvent/commonHotkey"; export const keymap = { element: undefined as Element, @@ -255,6 +256,7 @@ export const keymap = { }); } sendGlobalShortcut(app); + syncAppMenuShortcuts(); /// #endif }); }, diff --git a/app/src/constants.ts b/app/src/constants.ts index f18432ff808..9a26188fff1 100644 --- a/app/src/constants.ts +++ b/app/src/constants.ts @@ -39,16 +39,14 @@ export abstract class Constants { public static readonly SIYUAN_CONFIG_TRAY: string = "siyuan-config-tray"; public static readonly SIYUAN_QUIT: string = "siyuan-quit"; public static readonly SIYUAN_HOTKEY: string = "siyuan-hotkey"; + public static readonly SIYUAN_SYNC_APP_MENU: string = "siyuan-sync-app-menu"; public static readonly SIYUAN_INIT: string = "siyuan-init"; public static readonly SIYUAN_READY_TO_SHOW: string = "siyuan-ready-to-show"; public static readonly SIYUAN_SEND_WINDOWS: string = "siyuan-send-windows"; // 主窗口和各新窗口之间的通信,{cmd: "closetab"|"lockscreen"|"lockscreenByMode", data: {}}) - public static readonly SIYUAN_SAVE_CLOSE: string = "siyuan-save-close"; public static readonly SIYUAN_AUTO_LAUNCH: string = "siyuan-auto-launch"; public static readonly SIYUAN_OPEN_WORKSPACE: string = "siyuan-open-workspace"; - public static readonly SIYUAN_OPEN_URL: string = "siyuan-open-url"; public static readonly SIYUAN_OPEN_WINDOW: string = "siyuan-open-window"; - public static readonly SIYUAN_OPEN_FILE: string = "siyuan-open-file"; public static readonly SIYUAN_EXPORT_PDF: string = "siyuan-export-pdf"; public static readonly SIYUAN_EXPORT_NEWWINDOW: string = "siyuan-export-newwindow"; @@ -59,6 +57,13 @@ export abstract class Constants { public static readonly SIYUAN_SHOW_WINDOW: string = "siyuan-show-window"; + // 主进程调渲染进程 + public static readonly SIYUAN_OPEN_URL: string = "siyuan-open-url"; + public static readonly SIYUAN_OPEN_FILE: string = "siyuan-open-file"; + public static readonly SIYUAN_SAVE_CLOSE: string = "siyuan-save-close"; + public static readonly SIYUAN_OPEN_SETTING: string = "siyuan-open-setting"; + public static readonly SIYUAN_OPEN_HELP: string = "siyuan-open-help"; + // custom public static readonly CUSTOM_REMINDER_WECHAT: string = "custom-reminder-wechat"; public static readonly CUSTOM_RIFF_DECKS: string = "custom-riff-decks"; diff --git a/app/src/layout/status.ts b/app/src/layout/status.ts index b3939e3bbf9..845beb3a023 100644 --- a/app/src/layout/status.ts +++ b/app/src/layout/status.ts @@ -88,7 +88,7 @@ export const initStatus = (isWindow = false) => { label: window.siyuan.languages.debug, icon: "iconBug", click: () => { - ipcRenderer.send(Constants.SIYUAN_CMD, "openDevTools"); + ipcRenderer.send(Constants.SIYUAN_CMD, "toggleDevTools"); } }).element); /// #endif diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index effef0dff6e..e42f75b5633 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -562,7 +562,7 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { label: window.siyuan.languages.debug, icon: "iconBug", click: () => { - ipcRenderer.send(Constants.SIYUAN_CMD, "openDevTools"); + ipcRenderer.send(Constants.SIYUAN_CMD, "toggleDevTools"); } }).element); /// #endif