diff --git a/package-lock.json b/package-lock.json index 57c41d1b..a4564bf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "cross-env": "^5.2.0", "css-loader": "^1.0.1", "devtron": "^1.4.0", - "electron": "14.0.0", + "electron": "14.1.0", "electron-builder": "22.11.7", "electron-connect": "^0.6.3", "electron-mocha": "^10.1.0", @@ -12459,9 +12459,9 @@ } }, "node_modules/electron": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-14.0.0.tgz", - "integrity": "sha512-O6EI7L1BPIrTpEIFefjjmdbmSn9LtE4mmrv4dfpV4Mqaa8uKuNYQogwZPEvSwaBexb69eb1LQ25n+f+kBcjiRQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-14.1.0.tgz", + "integrity": "sha512-MnZSITjtdrY6jM/z/qXcuJqbIvz7MbxHp9f1O93mq/vt7aTxHYgjerPSqwya/RoUjkPEm1gkz669FsRk6ZtMdQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -38279,9 +38279,9 @@ } }, "electron": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-14.0.0.tgz", - "integrity": "sha512-O6EI7L1BPIrTpEIFefjjmdbmSn9LtE4mmrv4dfpV4Mqaa8uKuNYQogwZPEvSwaBexb69eb1LQ25n+f+kBcjiRQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-14.1.0.tgz", + "integrity": "sha512-MnZSITjtdrY6jM/z/qXcuJqbIvz7MbxHp9f1O93mq/vt7aTxHYgjerPSqwya/RoUjkPEm1gkz669FsRk6ZtMdQ==", "dev": true, "requires": { "@electron/get": "^1.0.1", diff --git a/package.json b/package.json index 70c4519d..b92d9a47 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "cross-env": "^5.2.0", "css-loader": "^1.0.1", "devtron": "^1.4.0", - "electron": "14.0.0", + "electron": "14.1.0", "electron-builder": "22.11.7", "electron-connect": "^0.6.3", "electron-mocha": "^10.1.0", diff --git a/src/main/menus/app.ts b/src/main/menus/app.ts index 6371757b..b2bd8e26 100644 --- a/src/main/menus/app.ts +++ b/src/main/menus/app.ts @@ -142,7 +142,14 @@ function createTemplate(config: Config) { return 'Ctrl+Shift+I'; })(), click(item: Electron.MenuItem, focusedWindow?: WebContents) { - WindowManager.openAppWrapperDevTools(focusedWindow); + if (focusedWindow) { + // toggledevtools opens it in the last known position, so sometimes it goes below the browserview + if (focusedWindow.isDevToolsOpened()) { + focusedWindow.closeDevTools(); + } else { + focusedWindow.openDevTools({mode: 'detach'}); + } + } }, }, { label: 'Developer Tools for Current Tab', diff --git a/src/main/utils.ts b/src/main/utils.ts index 506b25b2..6b7cdf83 100644 --- a/src/main/utils.ts +++ b/src/main/utils.ts @@ -22,15 +22,6 @@ export function shouldBeHiddenOnStartup(parsedArgv: Args) { return false; } -export function getMainViewBounds(windowWidth: number, windowHeight: number) { - return { - x: 0, - y: 0, - width: windowWidth, - height: windowHeight, - }; -} - export function getWindowBoundaries(win: BrowserWindow, hasBackBar = false) { const {width, height} = win.getContentBounds(); return getAdjustedWindowBoundaries(width, height, hasBackBar); diff --git a/src/main/views/teamDropdownView.ts b/src/main/views/teamDropdownView.ts index 92e7b35f..d1e1633d 100644 --- a/src/main/views/teamDropdownView.ts +++ b/src/main/views/teamDropdownView.ts @@ -128,12 +128,8 @@ export default class TeamDropdownView { } getBounds = (width: number, height: number) => { - let threeDotMenuWidth = THREE_DOT_MENU_WIDTH; - if (process.platform === 'darwin') { - threeDotMenuWidth = this.window.isFullScreen() ? 6 : THREE_DOT_MENU_WIDTH_MAC; - } return { - x: threeDotMenuWidth - MENU_SHADOW_WIDTH, + x: (process.platform === 'darwin' ? THREE_DOT_MENU_WIDTH_MAC : THREE_DOT_MENU_WIDTH) - MENU_SHADOW_WIDTH, y: TAB_BAR_HEIGHT - MENU_SHADOW_WIDTH, width, height, diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts index 08f79d71..525c192e 100644 --- a/src/main/views/viewManager.ts +++ b/src/main/views/viewManager.ts @@ -45,16 +45,14 @@ export class ViewManager { urlView?: BrowserView; urlViewCancel?: () => void; mainWindow: BrowserWindow; - mainView: BrowserView; loadingScreen?: BrowserView; - constructor(config: CombinedConfig, mainWindow: BrowserWindow, mainView: BrowserView) { + constructor(config: CombinedConfig, mainWindow: BrowserWindow) { this.configServers = config.teams; this.lastActiveServer = config.lastActiveTeam; this.viewOptions = {webPreferences: {spellcheck: config.useSpellChecker}}; this.views = new Map(); // keep in mind that this doesn't need to hold server order, only tabs on the renderer need that. this.mainWindow = mainWindow; - this.mainView = mainView; this.closedViews = new Map(); } @@ -132,7 +130,7 @@ export class ViewManager { delete this.currentView; this.showInitial(); } else { - this.mainView.webContents.send(SET_ACTIVE_VIEW); + this.mainWindow.webContents.send(SET_ACTIVE_VIEW); } } oldviews.forEach((unused) => { @@ -179,16 +177,11 @@ export class ViewManager { if (newView.needsLoadingScreen()) { this.showLoadingScreen(); } - this.mainView.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.name, newView.tab.type); + newView.window.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.name, newView.tab.type); ipcMain.emit(SET_ACTIVE_VIEW, true, newView.tab.server.name, newView.tab.type); if (newView.isReady()) { // if view is not ready, the renderer will have something to display instead. newView.show(); - - // Need to call this function so that macOS has a draggable top bar - // https://github.com/electron/electron/issues/31068 - this.mainView.setBounds(this.mainView.getBounds()); - ipcMain.emit(UPDATE_LAST_ACTIVE, true, newView.tab.server.name, newView.tab.type); if (newView.needsLoadingScreen()) { this.showLoadingScreen(); diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 739e9788..8da118cc 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -17,6 +17,7 @@ import {DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT, MINI import * as Validator from '../Validator'; import ContextMenu from '../contextMenu'; +import {getLocalPreload, getLocalURLString} from '../utils'; function saveWindowState(file: string, window: BrowserWindow) { const windowState: SavedWindowState = { @@ -42,6 +43,7 @@ function isFramelessWindow() { function createMainWindow(config: CombinedConfig, options: {linuxAppIcon: string}) { // Create the browser window. + const preload = getLocalPreload('mainWindow.js'); const boundsInfoPath = path.join(app.getPath('userData'), 'bounds-info.json'); let savedWindowState; try { @@ -61,6 +63,8 @@ function createMainWindow(config: CombinedConfig, options: {linuxAppIcon: string const {maximized: windowIsMaximized} = savedWindowState; + const spellcheck = (typeof config.useSpellChecker === 'undefined' ? true : config.useSpellChecker); + const windowOptions: BrowserWindowConstructorOptions = Object.assign({}, savedWindowState, { title: app.name, fullscreenable: true, @@ -78,6 +82,8 @@ function createMainWindow(config: CombinedConfig, options: {linuxAppIcon: string nodeIntegration: process.env.NODE_ENV === 'test', contextIsolation: process.env.NODE_ENV !== 'test', disableBlinkFeatures: 'Auxclick', + preload, + spellcheck, }, }); @@ -94,13 +100,24 @@ function createMainWindow(config: CombinedConfig, options: {linuxAppIcon: string log.error('Tried to register second handler, skipping'); } - mainWindow.once('show', () => { + const localURL = getLocalURLString('index.html'); + mainWindow.loadURL(localURL).catch( + (reason) => { + log.error(`Main window failed to load: ${reason}`); + }); + mainWindow.once('ready-to-show', () => { + mainWindow.webContents.zoomLevel = 0; + mainWindow.show(); if (windowIsMaximized) { mainWindow.maximize(); } }); + mainWindow.once('show', () => { + mainWindow.show(); + }); + mainWindow.once('restore', () => { mainWindow.restore(); }); diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index 4a563d27..85a06ad5 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import path from 'path'; -import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent, BrowserView, WebContents} from 'electron'; +import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent} from 'electron'; import log from 'electron-log'; import {CombinedConfig} from 'types/config'; @@ -23,7 +23,7 @@ import urlUtils from 'common/utils/url'; import {getTabViewName} from 'common/tabs/TabView'; -import {getAdjustedWindowBoundaries, getLocalPreload, getLocalURLString, getMainViewBounds} from '../utils'; +import {getAdjustedWindowBoundaries} from '../utils'; import {ViewManager} from '../views/viewManager'; import CriticalErrorHandler from '../CriticalErrorHandler'; @@ -37,7 +37,6 @@ import createMainWindow from './mainWindow'; type WindowManagerStatus = { mainWindow?: BrowserWindow; - mainView?: BrowserView; settingsWindow?: BrowserWindow; config?: CombinedConfig; viewManager?: ViewManager; @@ -105,33 +104,6 @@ export function showMainWindow(deeplinkingURL?: string | URL) { app.quit(); } - const preload = getLocalPreload('mainWindow.js'); - const spellcheck = (typeof status.config.useSpellChecker === 'undefined' ? true : status.config.useSpellChecker); - status.mainView = new BrowserView({ - webPreferences: { - nodeIntegration: process.env.NODE_ENV === 'test', - contextIsolation: process.env.NODE_ENV !== 'test', - disableBlinkFeatures: 'Auxclick', - preload, - spellcheck, - }, - }); - const localURL = getLocalURLString('index.html'); - status.mainView.webContents.loadURL(localURL).catch( - (reason) => { - log.error(`Main view failed to load: ${reason}`); - }); - status.mainWindow.addBrowserView(status.mainView); - const windowBounds = status.mainWindow.getContentBounds(); - status.mainView.setBounds(getMainViewBounds(windowBounds.width, windowBounds.height)); - - status.mainView.webContents.once('did-finish-load', () => { - if (status.mainView) { - status.mainView.webContents.zoomLevel = 0; - } - status.mainWindow?.show(); - }); - // window handlers status.mainWindow.on('closed', () => { log.warn('main window closed'); @@ -150,7 +122,7 @@ export function showMainWindow(deeplinkingURL?: string | URL) { status.mainWindow.on('leave-full-screen', () => sendToRenderer('leave-full-screen')); if (process.env.MM_DEBUG_SETTINGS) { - status.mainView.webContents.openDevTools({mode: 'detach'}); + status.mainWindow.webContents.openDevTools({mode: 'detach'}); } if (status.viewManager) { @@ -204,9 +176,6 @@ function handleResizeMainWindow() { if (currentView) { currentView.setBounds(getAdjustedWindowBoundaries(bounds.width!, bounds.height!, !(urlUtils.isTeamUrl(currentView.tab.url, currentView.view.webContents.getURL()) || urlUtils.isAdminUrl(currentView.tab.url, currentView.view.webContents.getURL())))); } - status.mainView?.setBounds(getMainViewBounds(bounds.width!, bounds.height!)); - status.viewManager?.setLoadingScreenBounds(); - status.teamDropdown?.updateWindowBounds(); }; // Another workaround since the window doesn't update properly under Linux for some reason @@ -216,13 +185,15 @@ function handleResizeMainWindow() { } else { setBoundsFunction(); } + status.viewManager.setLoadingScreenBounds(); + status.teamDropdown?.updateWindowBounds(); } export function sendToRenderer(channel: string, ...args: any[]) { if (!status.mainWindow) { showMainWindow(); } - status.mainView!.webContents.send(channel, ...args); + status.mainWindow!.webContents.send(channel, ...args); if (status.settingsWindow && status.settingsWindow.isVisible()) { status.settingsWindow.webContents.send(channel, ...args); } @@ -378,8 +349,8 @@ export function handleDoubleClick(e: IpcMainEvent, windowType?: string) { } function initializeViewManager() { - if (!status.viewManager && status.config && status.mainWindow && status.mainView) { - status.viewManager = new ViewManager(status.config, status.mainWindow, status.mainView); + if (!status.viewManager && status.config && status.mainWindow) { + status.viewManager = new ViewManager(status.config, status.mainWindow); status.viewManager.load(); status.viewManager.showInitial(); status.currentServerName = (status.config.teams.find((team) => team.order === status.config?.lastActiveTeam) || status.config.teams.find((team) => team.order === 0))?.name; @@ -434,9 +405,9 @@ export function openBrowserViewDevTools() { } export function focusThreeDotMenu() { - if (status.mainView) { - status.mainView.webContents.focus(); - status.mainView.webContents.send(FOCUS_THREE_DOT_MENU); + if (status.mainWindow) { + status.mainWindow.webContents.focus(); + status.mainWindow.webContents.send(FOCUS_THREE_DOT_MENU); } } @@ -605,16 +576,3 @@ export function getCurrentTeamName() { function handleAppLoggedIn(event: IpcMainEvent, viewName: string) { status.viewManager?.reloadViewIfNeeded(viewName); } - -export function openAppWrapperDevTools(focusedWindow?: WebContents) { - if (focusedWindow) { - // toggledevtools opens it in the last known position, so sometimes it goes below the browserview - if (focusedWindow.isDevToolsOpened()) { - focusedWindow.closeDevTools(); - } else if (focusedWindow.id === status.mainWindow?.webContents.id) { - status.mainView?.webContents.openDevTools({mode: 'detach'}); - } else { - focusedWindow.openDevTools({mode: 'detach'}); - } - } -}