diff options
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/main/index.ts | 57 | ||||
| -rw-r--r-- | gui/src/main/window-controller.ts | 50 |
2 files changed, 67 insertions, 40 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 29baab992a..5e3b28b342 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -1937,34 +1937,43 @@ class ApplicationMain { } private installTrayClickHandlers() { - if (this.guiSettings.unpinnedWindow) { - if (process.platform === 'win32' || process.platform === 'darwin') { - this.tray?.on('right-click', () => + switch (process.platform) { + case 'win32': + if (this.guiSettings.unpinnedWindow) { // This needs to be executed on click since if it is added to the tray icon it will be // displayed on left click as well. - this.tray?.popUpContextMenu(this.createTrayContextMenu()), - ); - } - this.tray?.on('click', () => this.windowController?.show()); - } else { - this.tray?.on('click', (event) => { - // The app shouldn't become visible if the user is reordering the tray icons on macOS. The - // tray icon becomes draggable when holding the command key (meta). - if (process.platform !== 'darwin' || !event.metaKey) { - const isMacOsBigSur = process.platform === 'darwin' && parseInt(os.release(), 10) >= 20; - if (isMacOsBigSur && !this.windowController?.isVisible()) { - // This is a workaround for this Electron issue, when it's resolved - // `this.windowController?.toggle()` should do the trick on all platforms: - // https://github.com/electron/electron/issues/28776 - const contextMenu = Menu.buildFromTemplate([]); - contextMenu.on('menu-will-show', () => this.windowController?.show()); - this.tray?.popUpContextMenu(contextMenu); + this.tray?.on('right-click', () => + this.tray?.popUpContextMenu(this.createTrayContextMenu()), + ); + this.tray?.on('click', () => this.windowController?.show()); + } else { + this.tray?.on('right-click', () => this.windowController?.hide()); + this.tray?.on('click', () => this.windowController?.toggle()); + } + break; + case 'darwin': + this.tray?.on('right-click', () => this.windowController?.hide()); + this.tray?.on('click', (event) => { + if (event.metaKey) { + setImmediate(() => this.windowController?.updatePosition()); } else { - this.windowController?.toggle(); + const isBigSurOrNewer = parseInt(os.release(), 10) >= 20; + if (isBigSurOrNewer && !this.windowController?.isVisible()) { + // This is a workaround for this Electron issue, when it's resolved + // `this.windowController?.toggle()` should do the trick on all platforms: + // https://github.com/electron/electron/issues/28776 + const contextMenu = Menu.buildFromTemplate([]); + contextMenu.on('menu-will-show', () => this.windowController?.show()); + this.tray?.popUpContextMenu(contextMenu); + } else { + this.windowController?.toggle(); + } } - } - }); - this.tray?.on('right-click', () => this.windowController?.hide()); + }); + break; + case 'linux': + this.tray?.on('click', () => this.windowController?.show()); + break; } } diff --git a/gui/src/main/window-controller.ts b/gui/src/main/window-controller.ts index 298f767fb5..c7ab18b5f7 100644 --- a/gui/src/main/window-controller.ts +++ b/gui/src/main/window-controller.ts @@ -1,6 +1,7 @@ import { BrowserWindow, Display, screen, Tray, WebContents } from 'electron'; import { IpcMainEventChannel } from './ipc-event-channel'; import { IWindowShapeParameters } from '../shared/ipc-types'; +import { Scheduler } from '../shared/scheduler'; interface IPosition { x: number; @@ -134,6 +135,8 @@ export default class WindowController { private webContentsValue: WebContents; private windowPositioning: IWindowPositioning; + private windowPositioningScheduler = new Scheduler(); + get window(): BrowserWindow | undefined { return this.windowValue.isDestroyed() ? undefined : this.windowValue; } @@ -153,21 +156,25 @@ export default class WindowController { : new AttachedToTrayWindowPositioning(tray); this.installDisplayMetricsHandler(); + this.installHideHandler(); } - public replaceWindow(window: BrowserWindow, unpinnedWindow: boolean) { - this.window?.removeAllListeners(); + public replaceWindow(windowValue: BrowserWindow, unpinnedWindow: boolean) { this.window?.destroy(); - this.windowValue = window; - this.webContentsValue = window.webContents; + const [width, height] = windowValue.getSize(); + this.width = width; + this.height = height; + this.windowValue = windowValue; + this.webContentsValue = windowValue.webContents; this.windowPositioning = unpinnedWindow ? new StandaloneWindowPositioning() : new AttachedToTrayWindowPositioning(this.tray); + this.installDisplayMetricsHandler(); + this.installHideHandler(); this.updatePosition(); - this.notifyUpdateWindowShape(); } public show(whenReady = true) { @@ -194,6 +201,20 @@ export default class WindowController { return this.window?.isVisible() ?? false; } + public updatePosition() { + if (this.window) { + const { x, y } = this.windowPositioning.getPosition(this.window); + this.window.setPosition(x, y, false); + } + + this.notifyUpdateWindowShape(); + } + + private installHideHandler() { + this.window?.addListener('hide', () => this.windowPositioningScheduler.cancel()); + this.window?.addListener('closed', () => this.windowPositioningScheduler.cancel()); + } + private showImmediately() { const window = this.window; @@ -209,23 +230,14 @@ export default class WindowController { window?.focus(); this.updatePosition(); - this.notifyUpdateWindowShape(); } else { this.updatePosition(); - this.notifyUpdateWindowShape(); window?.show(); window?.focus(); } } - private updatePosition() { - if (this.window) { - const { x, y } = this.windowPositioning.getPosition(this.window); - this.window.setPosition(x, y, false); - } - } - private notifyUpdateWindowShape() { if (this.window) { const shapeParameters = this.windowPositioning.getWindowShapeParameters(this.window); @@ -251,8 +263,10 @@ export default class WindowController { changedMetrics: string[], ) => { if (changedMetrics.includes('workArea') && this.window?.isVisible()) { - this.updatePosition(); - this.notifyUpdateWindowShape(); + this.onWorkAreaSizeChange(); + if (process.platform === 'win32') { + this.windowPositioningScheduler.schedule(() => this.onWorkAreaSizeChange(), 500); + } } // On linux, the window won't be properly rescaled back to it's original @@ -263,6 +277,10 @@ export default class WindowController { } }; + private onWorkAreaSizeChange() { + this.updatePosition(); + } + private forceResizeWindow() { this.window?.setSize(this.width, this.height); } |
