summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-08-24 15:34:55 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-08-24 15:34:55 -0300
commitc21686d1f9f9e04b18a418f5902a133584935883 (patch)
tree9913a520b1bfecb841f09ec90b0f1bc7e099a6a6 /gui
parent2e599ba1095894e5845d6db09a88df736d48e4f6 (diff)
parenta2760ea5eba54b19cb8133e3f3f3596dba17d79a (diff)
downloadmullvadvpn-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.js178
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.