diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-08-24 15:34:55 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-08-24 15:34:55 -0300 |
| commit | c21686d1f9f9e04b18a418f5902a133584935883 (patch) | |
| tree | 9913a520b1bfecb841f09ec90b0f1bc7e099a6a6 /gui | |
| parent | 2e599ba1095894e5845d6db09a88df736d48e4f6 (diff) | |
| parent | a2760ea5eba54b19cb8133e3f3f3596dba17d79a (diff) | |
| download | mullvadvpn-c21686d1f9f9e04b18a418f5902a133584935883.tar.xz mullvadvpn-c21686d1f9f9e04b18a418f5902a133584935883.zip | |
Merge branch 'restore-window-to-last-position'
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/packages/desktop/src/main/window-controller.js | 178 |
1 files changed, 105 insertions, 73 deletions
diff --git a/gui/packages/desktop/src/main/window-controller.js b/gui/packages/desktop/src/main/window-controller.js index b27d04d621..ccada6cd0c 100644 --- a/gui/packages/desktop/src/main/window-controller.js +++ b/gui/packages/desktop/src/main/window-controller.js @@ -3,85 +3,37 @@ import { screen } from 'electron'; import type { BrowserWindow, Tray, Display } from 'electron'; -export default class WindowController { - _window: BrowserWindow; - _tray: Tray; - _isWindowReady = false; - - get window(): BrowserWindow { - return this._window; - } - - constructor(window: BrowserWindow, tray: Tray) { - this._window = window; - this._tray = tray; - - this._installDisplayMetricsHandler(); - this._installWindowReadyHandlers(); - } - - show(whenReady: boolean = true) { - if (whenReady) { - this._executeWhenWindowIsReady(() => this._showImmediately()); - } else { - this._showImmediately(); - } - } +type Position = { x: number, y: number }; - hide() { - this._window.hide(); - } - - toggle() { - if (this._window.isVisible()) { - this.hide(); - } else { - this.show(); - } - } +interface WindowPositioning { + getPosition(window: BrowserWindow): Position; +} - _showImmediately() { - const window = this._window; +class StandaloneWindowPositioning implements WindowPositioning { + getPosition(window: BrowserWindow): Position { + const windowBounds = window.getBounds(); - this._updatePosition(); + const primaryDisplay = screen.getPrimaryDisplay(); + const workArea = primaryDisplay.workArea; + const maxX = workArea.x + workArea.width - windowBounds.width; + const maxY = workArea.y + workArea.height - windowBounds.height; - window.show(); - window.focus(); - } + const x = Math.min(Math.max(windowBounds.x, workArea.x), maxX); + const y = Math.min(Math.max(windowBounds.y, workArea.y), maxY); - _updatePosition() { - const { x, y } = this._getWindowPosition(); - this._window.setPosition(x, y, false); + return { x, y }; } +} - _getTrayPlacement() { - switch (process.platform) { - case 'darwin': - // macOS has menubar always placed at the top - return 'top'; - - case 'win32': { - // taskbar occupies some part of the screen excluded from work area - const primaryDisplay = screen.getPrimaryDisplay(); - const displaySize = primaryDisplay.size; - const workArea = primaryDisplay.workArea; - - if (workArea.width < displaySize.width) { - return workArea.x > 0 ? 'left' : 'right'; - } else if (workArea.height < displaySize.height) { - return workArea.y > 0 ? 'top' : 'bottom'; - } else { - return 'none'; - } - } +class AttachedToTrayWindowPositioning implements WindowPositioning { + _tray: Tray; - default: - return 'none'; - } + constructor(tray: Tray) { + this._tray = tray; } - _getWindowPosition(): { x: number, y: number } { - const windowBounds = this._window.getBounds(); + getPosition(window: BrowserWindow): Position { + const windowBounds = window.getBounds(); const trayBounds = this._tray.getBounds(); const primaryDisplay = screen.getPrimaryDisplay(); @@ -122,10 +74,90 @@ export default class WindowController { x = Math.min(Math.max(x, workArea.x), maxX); y = Math.min(Math.max(y, workArea.y), maxY); - return { - x: Math.round(x), - y: Math.round(y), - }; + return { x, y }; + } + + _getTrayPlacement() { + switch (process.platform) { + case 'darwin': + // macOS has menubar always placed at the top + return 'top'; + + case 'win32': { + // taskbar occupies some part of the screen excluded from work area + const primaryDisplay = screen.getPrimaryDisplay(); + const displaySize = primaryDisplay.size; + const workArea = primaryDisplay.workArea; + + if (workArea.width < displaySize.width) { + return workArea.x > 0 ? 'left' : 'right'; + } else if (workArea.height < displaySize.height) { + return workArea.y > 0 ? 'top' : 'bottom'; + } else { + return 'none'; + } + } + + default: + return 'none'; + } + } +} + +export default class WindowController { + _window: BrowserWindow; + _windowPositioning: WindowPositioning; + _isWindowReady = false; + + get window(): BrowserWindow { + return this._window; + } + + constructor(window: BrowserWindow, tray: Tray) { + this._window = window; + + if (process.platform === 'linux') { + this._windowPositioning = new StandaloneWindowPositioning(); + } else { + this._windowPositioning = new AttachedToTrayWindowPositioning(tray); + } + + this._installDisplayMetricsHandler(); + this._installWindowReadyHandlers(); + } + + show(whenReady: boolean = true) { + if (whenReady) { + this._executeWhenWindowIsReady(() => this._showImmediately()); + } else { + this._showImmediately(); + } + } + + hide() { + this._window.hide(); + } + + toggle() { + if (this._window.isVisible()) { + this.hide(); + } else { + this.show(); + } + } + + _showImmediately() { + const window = this._window; + + this._updatePosition(); + + window.show(); + window.focus(); + } + + _updatePosition() { + const { x, y } = this._windowPositioning.getPosition(this._window); + this._window.setPosition(x, y, false); } // Installs display event handlers to update the window position on any changes in the display or workarea dimensions. |
