diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 78876bbf0..cbbd520e1 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -19,6 +19,8 @@ "goToTab9": "Go to last tab", "goToTabNext": "Go to next tab", "goToTabPrev": "Go to previous tab", + "goToEditTabNext": "Go to next edited tab", + "goToEditTabPrev": "Go to previous edited tab", "createdTime": "Created time", "updatedTime": "Updated time", "removeBookmark": "Remove bookmark from ${x}?", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 992ac0459..3680c5bfa 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -19,6 +19,8 @@ "goToTab9": "Ir a la última pestaña", "goToTabNext": "Ir a la siguiente pestaña", "goToTabPrev": "Ir a la pestaña anterior", + "goToEditTabNext": "Ir a la siguiente pestaña editada", + "goToEditTabPrev": "Ir a la pestaña editada anteriormente", "createdTime": "Hora de creación", "updatedTime": "Hora actualizada", "removeBookmark": "¿Eliminar marcador de ${x}?", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 7e163ebd1..6d6dafb0d 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -19,6 +19,8 @@ "goToTab9": "Aller au dernier onglet", "goToTabNext": "Aller à l'onglet suivant", "goToTabPrev": "Aller à l'onglet précédent", + "goToEditTabNext": "Aller à l'onglet modifié suivant", + "goToEditTabPrev": "Aller à l'onglet modifié précédent", "createdTime": "Heure de création", "updatedTime": "Heure mise à jour", "removeBookmark": "Supprimer le signet de ${x} ?", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 5357c4985..0f1633aca 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -19,6 +19,8 @@ "goToTab9": "跳到最後一個頁籤", "goToTabNext": "跳到下一個頁籤", "goToTabPrev": "跳到上一個頁籤", + "goToEditTabNext": "跳到下一個編輯頁籤", + "goToEditTabPrev": "跳到上一個編輯頁籤", "createdTime": "建立時間", "updatedTime": "更新時間", "removeBookmark": "移除 ${x} 中的書籤?", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 878836035..a7d5c6a78 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -19,6 +19,8 @@ "goToTab9": "跳转到最后一个页签", "goToTabNext": "跳转到下一个页签", "goToTabPrev": "跳转到上一个页签", + "goToEditTabNext": "跳转到下一个编辑页签", + "goToEditTabPrev": "跳转到上一个编辑页签", "createdTime": "创建时间", "updatedTime": "更新时间", "removeBookmark": "移除 ${x} 中的书签?", diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index e6b27f40a..59b3df925 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -6,7 +6,7 @@ import { updateHotkeyTip, writeText } from "../../protyle/util/compatibility"; -import {matchHotKey} from "../../protyle/util/hotKey"; +import {matchAuxiliaryHotKey, matchHotKey} from "../../protyle/util/hotKey"; import {openSearch} from "../../search/spread"; import { hasClosestBlock, @@ -1055,8 +1055,10 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => { } } - // mac 中只能使用 ⌃ - if (switchDialog && event.ctrlKey && !event.metaKey && event.key.startsWith("Arrow")) { + if (switchDialog && + (matchAuxiliaryHotKey(window.siyuan.config.keymap.general.goToEditTabNext.custom, event) || + matchAuxiliaryHotKey(window.siyuan.config.keymap.general.goToEditTabPrev.custom, event)) + && event.key.startsWith("Arrow")) { dialogArrow(app, switchDialog.element, event); return; } @@ -1068,7 +1070,8 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => { } const isTabWindow = isWindow(); - if (event.ctrlKey && !event.metaKey && event.key === "Tab") { + if (matchHotKey(window.siyuan.config.keymap.general.goToEditTabNext.custom, event) || + matchHotKey(window.siyuan.config.keymap.general.goToEditTabPrev.custom, event)) { if (switchDialog && switchDialog.element.parentElement) { return; } @@ -1126,7 +1129,7 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => {
`, }); - switchDialog.element.setAttribute("data-key", "⌃⇥"); + switchDialog.element.setAttribute("data-key", window.siyuan.config.keymap.general.goToEditTabNext.custom); // 需移走光标,否则编辑器会继续监听并执行按键操作 switchDialog.element.querySelector("input").focus(); if (isMac()) { diff --git a/app/src/boot/globalEvent/keyup.ts b/app/src/boot/globalEvent/keyup.ts index 3bf74b198..5a05b5719 100644 --- a/app/src/boot/globalEvent/keyup.ts +++ b/app/src/boot/globalEvent/keyup.ts @@ -4,21 +4,24 @@ import {openCard} from "../../card/openCard"; import {getDockByType} from "../../layout/tabUtil"; import {getAllTabs} from "../../layout/getAll"; import {App} from "../../index"; +import {Constants} from "../../constants"; +import {matchHotKey} from "../../protyle/util/hotKey"; -export const windowKeyUp = (app: App,event:KeyboardEvent) => { +export const windowKeyUp = (app: App, event: KeyboardEvent) => { window.siyuan.ctrlIsPressed = false; window.siyuan.shiftIsPressed = false; window.siyuan.altIsPressed = false; const switchDialog = window.siyuan.dialogs.find(item => { - if (item.element.getAttribute("data-key") === "⌃⇥") { + if (item.element.getAttribute("data-key") === window.siyuan.config.keymap.general.goToEditTabNext.custom) { return true; } }); if (switchDialog && switchDialog.element.parentElement) { - if (event.key === "Tab") { + if (window.siyuan.config.keymap.general.goToEditTabNext.custom.endsWith(Constants.KEYCODELIST[event.keyCode]) || + window.siyuan.config.keymap.general.goToEditTabPrev.custom.endsWith(Constants.KEYCODELIST[event.keyCode])) { let currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus"); currentLiElement.classList.remove("b3-list-item--focus"); - if (event.shiftKey) { + if (matchHotKey(window.siyuan.config.keymap.general.goToEditTabPrev.custom, event)) { if (currentLiElement.previousElementSibling) { currentLiElement.previousElementSibling.classList.add("b3-list-item--focus"); } else if (currentLiElement.getAttribute("data-original")) { @@ -73,12 +76,14 @@ export const windowKeyUp = (app: App,event:KeyboardEvent) => { if (originalElement) { originalElement.removeAttribute("data-original"); } - } else if (event.key === "Control") { + } else if (window.siyuan.config.keymap.general.goToEditTabNext.custom.startsWith(Constants.KEYCODELIST[event.keyCode]) || + window.siyuan.config.keymap.general.goToEditTabPrev.custom.startsWith(Constants.KEYCODELIST[event.keyCode])) { let currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus"); // 快速切换时,不触发 Tab if (currentLiElement.getAttribute("data-original")) { currentLiElement.classList.remove("b3-list-item--focus"); - if (event.shiftKey) { + if (matchHotKey(window.siyuan.config.keymap.general.goToEditTabPrev.custom, event)) { + // 上一个 if (currentLiElement.previousElementSibling) { currentLiElement.previousElementSibling.classList.add("b3-list-item--focus"); } else { diff --git a/app/src/config/keymap.ts b/app/src/config/keymap.ts index d11969775..e97e14084 100644 --- a/app/src/config/keymap.ts +++ b/app/src/config/keymap.ts @@ -382,7 +382,10 @@ export const keymap = { } let hasConflict = false; if (["⌘", "⇧", "⌥", "⌃"].includes(keymapStr.substr(keymapStr.length - 1, 1)) || - ["⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D", "⌃⇧⇥", "⌃⇥", "⌘⇥", "⇧⌘⇥", "⇧⌘→", "⇧⌘←", "⌘Home", "⌘End", "⇧↩", "↩", "PageUp", "PageDown", "⌫", "⌦"].includes(keymapStr)) { + ["⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D", "⌘⇥", "⇧⌘⇥", "⇧⌘→", "⇧⌘←", "⌘Home", "⌘End", "⇧↩", "↩", "PageUp", "PageDown", "⌫", "⌦"].includes(keymapStr) || + // 跳转到下/上一个编辑页签不能包含 ctrl, 否则不能监听到 keyup + (keys[0] === "general" && ["goToEditTabNext", "goToEditTabPrev"].includes(keys[1]) && keymapStr.includes("⌘")) + ) { showMessage(`${window.siyuan.languages.invalid} [${adoptKeymapStr}]`); hasConflict = true; } diff --git a/app/src/constants.ts b/app/src/constants.ts index 13a9d84df..f92f27ba8 100644 --- a/app/src/constants.ts +++ b/app/src/constants.ts @@ -221,7 +221,7 @@ export abstract class Constants { }; // 冲突不使用 "⌘S/Q" // "⌘", "⇧", "⌥", "⌃" - // "⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D","⌃⇧⇥", "⌃⇥", "⌘⇥", "⇧⌘⇥", "⇧⌘→", "⇧⌘←", + // "⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D", "⌘⇥", "⇧⌘⇥", "⇧⌘→", "⇧⌘←", // "⌘Home", "⌘End", "⇧↩", "↩", "PageUp", "PageDown", "⌫", "⌦" 不可自定义 public static readonly SIYUAN_KEYMAP: IKeymap = { general: { @@ -265,6 +265,8 @@ export abstract class Constants { goToTab9: {default: "⌘9", custom: "⌘9"}, goToTabNext: {default: "⇧⌘]", custom: "⇧⌘]"}, goToTabPrev: {default: "⇧⌘[", custom: "⇧⌘["}, + goToEditTabNext: {default: "⌃⇥", custom: "⌃⇥"}, + goToEditTabPrev: {default: "⌃⇧⇥", custom: "⌃⇧⇥"}, move: {default: "", custom: ""}, selectOpen1: {default: "", custom: ""}, toggleDock: {default: "", custom: ""}, diff --git a/app/src/protyle/util/hotKey.ts b/app/src/protyle/util/hotKey.ts index f4fea7195..73433f12b 100644 --- a/app/src/protyle/util/hotKey.ts +++ b/app/src/protyle/util/hotKey.ts @@ -1,7 +1,47 @@ -import {isNotCtrl, isOnlyMeta} from "./compatibility"; +import {isMac, isNotCtrl, isOnlyMeta} from "./compatibility"; import {Constants} from "../../constants"; -// 是否匹配 ⇧⌘[] / ⌘[] / ⌥[] / ⌥⌘[] / ⌥⇧[] / ⌥⇧⌘[] / ⇧[] / [] +// 是否匹配辅助键 ⌃⌥⇧⌘ +export const matchAuxiliaryHotKey = (hotKey: string, event: KeyboardEvent) => { + if (hotKey.includes("⌃")) { + if (!event.ctrlKey) { + return false; + } + } else { + if (event.ctrlKey) { + return false; + } + } + if (hotKey.includes("⌥")) { + if (!event.altKey) { + return false; + } + } else { + if (event.altKey) { + return false; + } + } + if (hotKey.includes("⇧")) { + if (!event.shiftKey) { + return false; + } + } else { + if (event.shiftKey) { + return false; + } + } + if (hotKey.includes("⌘")) { + if (isMac() ? !event.metaKey : !event.ctrlKey) { + return false; + } + } else { + if (isMac() ? event.metaKey : event.ctrlKey) { + return false; + } + } + return true; +}; + export const matchHotKey = (hotKey: string, event: KeyboardEvent) => { if (!hotKey) { return false; @@ -41,7 +81,6 @@ export const matchHotKey = (hotKey: string, event: KeyboardEvent) => { if (hotKeys.length === 4) { keyCode = hotKeys[3]; } - const isMatchKey = keyCode === Constants.KEYCODELIST[event.keyCode]; // 是否匹配 ⌥[] / ⌥⌘[] if (isMatchKey && event.altKey && !event.shiftKey &&