diff --git a/src/public/app/desktop.js b/src/public/app/desktop.js index 835624d35..bad74c698 100644 --- a/src/public/app/desktop.js +++ b/src/public/app/desktop.js @@ -8,6 +8,7 @@ import macInit from './services/mac_init.js'; import electronContextMenu from "./menus/electron_context_menu.js"; import glob from "./services/glob.js"; import { t } from "./services/i18n.js"; +import options from "./services/options.js"; await appContext.earlyInit(); @@ -30,8 +31,7 @@ bundleService.getWidgetBundlesByParent().then(async widgetBundles => { glob.setupGlobs(); if (utils.isElectron()) { - utils.dynamicRequire('electron').ipcRenderer.on('globalShortcut', - async (event, actionName) => appContext.triggerCommand(actionName)); + initOnElectron(); } macInit.init(); @@ -43,3 +43,40 @@ noteAutocompleteService.init(); if (utils.isElectron()) { electronContextMenu.setupContextMenu(); } + +function initOnElectron() { + const electron = utils.dynamicRequire('electron'); + electron.ipcRenderer.on('globalShortcut', async (event, actionName) => appContext.triggerCommand(actionName)); + + if (options.get("nativeTitleBarVisible") !== "true") { + initTitleBarButtons(); + } +} + +function initTitleBarButtons() { + const electronRemote = utils.dynamicRequire("@electron/remote"); + const currentWindow = electronRemote.getCurrentWindow(); + const style = window.getComputedStyle(document.body); + + if (window.glob.platform === "win32") { + const applyWindowsOverlay = () => { + const color = style.getPropertyValue("--native-titlebar-background"); + const symbolColor = style.getPropertyValue("--native-titlebar-foreground"); + if (color && symbolColor) { + currentWindow.setTitleBarOverlay({ color, symbolColor }); + } + }; + + applyWindowsOverlay(); + + // Register for changes to the native title bar colors. + window.matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", applyWindowsOverlay); + } + + if (window.glob.platform === "darwin") { + const xOffset = parseInt(style.getPropertyValue("--native-titlebar-darwin-x-offset"), 10); + const yOffset = parseInt(style.getPropertyValue("--native-titlebar-darwin-y-offset"), 10); + currentWindow.setWindowButtonPosition({ x: xOffset, y: yOffset }); + } +} diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 995654f4c..8d0a667a1 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -84,6 +84,7 @@ import CopyImageReferenceButton from "../widgets/floating_buttons/copy_image_ref import ScrollPaddingWidget from "../widgets/scroll_padding.js"; import ClassicEditorToolbar from "../widgets/ribbon_widgets/classic_editor_toolbar.js"; import options from "../services/options.js"; +import utils from "../services/utils.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -95,15 +96,27 @@ export default class DesktopLayout { const launcherPaneIsHorizontal = (options.get("layoutOrientation") === "horizontal"); const launcherPane = this.#buildLauncherPane(launcherPaneIsHorizontal); + const isElectron = (utils.isElectron()); + const isMac = (window.glob.platform === "darwin"); + const isWindows = (window.glob.platform === "win32"); + const hasNativeTitleBar = (window.glob.hasNativeTitleBar); - return new RootContainer(launcherPaneIsHorizontal) + /** + * If true, the tab bar is displayed above the launcher pane with full width; if false (default), the tab bar is displayed in the rest pane. + * On macOS we need to force the full-width tab bar on Electron in order to allow the semaphore (window controls) enough space. + */ + const fullWidthTabBar = (launcherPaneIsHorizontal || (isElectron && !hasNativeTitleBar && isMac)); + const customTitleBarButtons = (hasNativeTitleBar && !isMac && !isWindows); + + return new RootContainer(true) .setParent(appContext) .class((launcherPaneIsHorizontal ? "horizontal" : "vertical") + "-layout") - .optChild(launcherPaneIsHorizontal, new FlexContainer('row') + .optChild(fullWidthTabBar, new FlexContainer('row') .class("tab-row-container") - .child(new LeftPaneToggleWidget(true)) + .child(new FlexContainer( "row").id("tab-row-left-spacer")) + .optChild(launcherPaneIsHorizontal, new LeftPaneToggleWidget(true)) .child(new TabRowWidget().class("full-width")) - .child(new TitleBarButtonsWidget()) + .optChild(customTitleBarButtons, new TitleBarButtonsWidget()) .css('height', '40px') .css('background-color', 'var(--launcher-pane-background-color)') .setParent(appContext) @@ -120,9 +133,9 @@ export default class DesktopLayout { .child(new FlexContainer('column') .id('rest-pane') .css("flex-grow", "1") - .optChild(!launcherPaneIsHorizontal, new FlexContainer('row') + .optChild(!fullWidthTabBar, new FlexContainer('row') .child(new TabRowWidget()) - .child(new TitleBarButtonsWidget()) + .optChild(customTitleBarButtons, new TitleBarButtonsWidget()) .css('height', '40px') ) .child(new FlexContainer('row') diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index 9ee235a45..6607c0182 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -143,6 +143,11 @@ const TPL = ` + +