From 76caf02cb2b4d52e60453d44a57d38a739743d6b Mon Sep 17 00:00:00 2001 From: Tasos Boulis Date: Tue, 3 Jan 2023 18:11:35 +0200 Subject: [PATCH] Maximize main window if monitor removed/changed resolution (#2486) * Maximize main window if monitor removed/changed resolution * Fix unit tests * Add better handlers to support active screen changes --- src/main/app/initialize.test.js | 3 +++ src/main/app/initialize.ts | 9 +++++++- src/main/windows/windowManager.ts | 38 ++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/app/initialize.test.js b/src/main/app/initialize.test.js index 8ee70f5d..79577b2d 100644 --- a/src/main/app/initialize.test.js +++ b/src/main/app/initialize.test.js @@ -51,6 +51,9 @@ jest.mock('electron', () => ({ handle: jest.fn(), emit: jest.fn(), }, + screen: { + on: jest.fn(), + }, session: { defaultSession: { setSpellCheckerDictionaryDownloadURL: jest.fn(), diff --git a/src/main/app/initialize.ts b/src/main/app/initialize.ts index e9e22000..06ace5b9 100644 --- a/src/main/app/initialize.ts +++ b/src/main/app/initialize.ts @@ -3,7 +3,7 @@ import path from 'path'; -import {app, ipcMain, session} from 'electron'; +import {app, ipcMain, screen, session} from 'electron'; import installExtension, {REACT_DEVELOPER_TOOLS} from 'electron-devtools-installer'; import isDev from 'electron-is-dev'; import log from 'electron-log'; @@ -119,6 +119,8 @@ export async function initialize() { app.whenReady(), ]); + initializeScreenEventListeners(); + // no need to continue initializing if app is quitting if (global.willAppQuit) { return; @@ -188,6 +190,11 @@ function initializeAppEventListeners() { app.on('will-finish-launching', handleAppWillFinishLaunching); } +function initializeScreenEventListeners() { + screen.on('display-removed', WindowManager.displayRemoved); + screen.on('display-metrics-changed', WindowManager.displayMetricsChanged); +} + function initializeBeforeAppReady() { if (!Config.data) { log.error('No config loaded'); diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index 294bfecd..da0d84e0 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -4,7 +4,7 @@ /* eslint-disable max-lines */ import path from 'path'; -import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent, IpcMainInvokeEvent, desktopCapturer} from 'electron'; +import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent, IpcMainInvokeEvent, desktopCapturer, Display, screen} from 'electron'; import log from 'electron-log'; import { @@ -255,6 +255,42 @@ export class WindowManager { this.sendToRenderer(MAXIMIZE_CHANGE, false); } + maximizeMainWindow = () => { + if (!(this.viewManager && this.mainWindow)) { + return; + } + this.mainWindow.maximize?.(); + } + + displayRemoved = (event: Event, oldDisplay: Display) => { + log.debug('WindowManager.displayRemoved', {oldDisplay}); + + if (!oldDisplay) { + return; + } + + if (this.isActiveScreen(oldDisplay.id)) { + this.maximizeMainWindow(); + } + } + + displayMetricsChanged = (event: Event, display: Display, changedMetrics: string[]) => { + log.debug('WindowManager.displayMetricsChanged', {display, changedMetrics}); + + this.maximizeMainWindow(); + } + + isActiveScreen = (id: Display['id']): boolean => { + if (!(this.viewManager && this.mainWindow)) { + return false; + } + + const mainWindowBounds = this.mainWindow.getBounds(); + const currentDisplay = screen.getDisplayNearestPoint({x: mainWindowBounds.x, y: mainWindowBounds.y}); + log.debug('WindowManager.isActiveScreen', {id, currentDisplay}); + return currentDisplay.id === id; + } + isResizing = false; handleWillResizeMainWindow = (event: Event, newBounds: Electron.Rectangle) => {