From 137e7a06b917b8c41b02832eb12cd20e375174e6 Mon Sep 17 00:00:00 2001 From: JaeBradle Date: Sun, 21 Jan 2024 21:54:27 +0800 Subject: [PATCH] fix: Improve 'windows' OS detection of taskbar location (#307) * Improve 'windows' OS detection of taskbar location Should be helpful for the following issues https://github.com/maxogden/menubar/issues/264 https://github.com/maxogden/menubar/issues/232 * Update windows position before windows displaying Referring to the issue https://github.com/maxogden/menubar/issues/232 * Improve 'windows' OS detection of taskbar location (fix multi-monitor systems) * Fix lint issues * Removed win32 vertical optimization Trying to solve issue: https://github.com/maxogden/menubar/issues/298 Co-authored-by: Oleg Semenov --- src/Menubar.ts | 25 +++++++------------ src/util/getWindowPosition.ts | 45 +++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/Menubar.ts b/src/Menubar.ts index d8d39da..500dae8 100644 --- a/src/Menubar.ts +++ b/src/Menubar.ts @@ -138,6 +138,14 @@ export class Menubar extends EventEmitter { if (!this._browserWindow) { throw new Error('Window has been initialized just above. qed.'); } + + // 'Windows' taskbar: sync windows position each time before showing + // https://github.com/maxogden/menubar/issues/232 + if (process.platform === 'win32') { + // Fill in this._options.windowPosition when taskbar position is available + this._options.windowPosition = getWindowPosition(this.tray); + } + this.emit('show'); if (trayPos && trayPos.x !== 0) { @@ -172,26 +180,11 @@ export class Menubar extends EventEmitter { this._options.browserWindow.x !== undefined ? this._options.browserWindow.x : position.x; - let y = + const y = this._options.browserWindow.y !== undefined ? this._options.browserWindow.y : position.y; - // Multi-Taskbar: optimize vertical position - // https://github.com/maxogden/menubar/pull/217 - if (process.platform === 'win32') { - if ( - trayPos && - this._options.windowPosition && - this._options.windowPosition.startsWith('bottom') - ) { - y = - trayPos.y + - trayPos.height / 2 - - this._browserWindow.getBounds().height / 2; - } - } - // `.setPosition` crashed on non-integers // https://github.com/maxogden/menubar/issues/233 this._browserWindow.setPosition(Math.round(x), Math.round(y)); diff --git a/src/util/getWindowPosition.ts b/src/util/getWindowPosition.ts index e33f5a1..8a39027 100644 --- a/src/util/getWindowPosition.ts +++ b/src/util/getWindowPosition.ts @@ -4,7 +4,20 @@ /** */ -import { Tray } from 'electron'; +import { Rectangle, screen as electronScreen, Tray } from 'electron'; + +const trayToScreenRects = (tray: Tray): [Rectangle, Rectangle] => { + // There may be more than one screen, so we need to figure out on which screen our tray icon lives. + const { + workArea, + bounds: screenBounds, + } = electronScreen.getDisplayMatching(tray.getBounds()); + + workArea.x -= screenBounds.x; + workArea.y -= screenBounds.y; + + return [screenBounds, workArea]; +}; type TaskbarLocation = 'top' | 'bottom' | 'left' | 'right'; @@ -16,23 +29,31 @@ type TaskbarLocation = 'top' | 'bottom' | 'left' | 'right'; * @param tray - The Electron Tray instance. */ export function taskbarLocation(tray: Tray): TaskbarLocation { - const trayBounds = tray.getBounds(); + const [screenBounds, workArea] = trayToScreenRects(tray); - // Determine taskbar location - if (trayBounds.width !== trayBounds.height && trayBounds.y === 0) { - return 'top'; - } - if (trayBounds.width !== trayBounds.height && trayBounds.y > 0) { - return 'bottom'; - } - if (trayBounds.width === trayBounds.height && trayBounds.x < trayBounds.y) { + // TASKBAR LEFT + if (workArea.x > 0) { + // The workspace starts more on the right return 'left'; } - if (trayBounds.width === trayBounds.height && trayBounds.x > trayBounds.y) { + + // TASKBAR TOP + if (workArea.y > 0) { + return 'top'; + } + + // TASKBAR RIGHT + // Here both workArea.y and workArea.x are 0 so we can no longer leverage them. + // We can use the workarea and display width though. + // Determine taskbar location + if (workArea.width < screenBounds.width) { + // The taskbar is either on the left or right, but since the LEFT case was handled above, + // we can be sure we're dealing with a right taskbar return 'right'; } - // By default, return 'bottom' + // TASKBAR BOTTOM + // Since all the other cases were handled, we can be sure we're dealing with a bottom taskbar return 'bottom'; }