summary refs log tree commit diff
path: root/resources/app/node_modules/electron-window-state/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/app/node_modules/electron-window-state/index.js')
-rw-r--r--resources/app/node_modules/electron-window-state/index.js174
1 files changed, 174 insertions, 0 deletions
diff --git a/resources/app/node_modules/electron-window-state/index.js b/resources/app/node_modules/electron-window-state/index.js
new file mode 100644
index 0000000..ea17e2e
--- /dev/null
+++ b/resources/app/node_modules/electron-window-state/index.js
@@ -0,0 +1,174 @@
+'use strict';
+
+var path = require('path');
+var electron = require('electron');
+var jsonfile = require('jsonfile');
+var mkdirp = require('mkdirp');
+var deepEqual = require('deep-equal');
+
+module.exports = function (options) {
+  var app = electron.app || electron.remote.app;
+  var screen = electron.screen || electron.remote.screen;
+  var state;
+  var winRef;
+  var stateChangeTimer;
+  var eventHandlingDelay = 100;
+  var config = Object.assign({
+    file: 'window-state.json',
+    path: app.getPath('userData'),
+    maximize: true,
+    fullScreen: true
+  }, options);
+  var fullStoreFileName = path.join(config.path, config.file);
+
+  function isNormal(win) {
+    return !win.isMaximized() && !win.isMinimized() && !win.isFullScreen();
+  }
+
+  function hasBounds() {
+    return state &&
+      Number.isInteger(state.x) &&
+      Number.isInteger(state.y) &&
+      Number.isInteger(state.width) && state.width > 0 &&
+      Number.isInteger(state.height) && state.height > 0;
+  }
+
+  function validateState() {
+    var isValid = state && (hasBounds() || state.isMaximized || state.isFullScreen);
+    if (!isValid) {
+      state = null;
+      return;
+    }
+
+    if (hasBounds() && state.displayBounds) {
+      // Check if the display where the window was last open is still available
+      var displayBounds = screen.getDisplayMatching(state).bounds;
+      var sameBounds = deepEqual(state.displayBounds, displayBounds, {strict: true});
+      if (!sameBounds) {
+        if (displayBounds.width < state.displayBounds.width) {
+          if (state.x > displayBounds.width) {
+            state.x = 0;
+          }
+
+          if (state.width > displayBounds.width) {
+            state.width = displayBounds.width;
+          }
+        }
+
+        if (displayBounds.height < state.displayBounds.height) {
+          if (state.y > displayBounds.height) {
+            state.y = 0;
+          }
+
+          if (state.height > displayBounds.height) {
+            state.height = displayBounds.height;
+          }
+        }
+      }
+    }
+  }
+
+  function updateState(win) {
+    win = win || winRef;
+    if (!win) {
+      return;
+    }
+    // don't throw an error when window was closed
+    try {
+      var winBounds = win.getBounds();
+      if (isNormal(win)) {
+        state.x = winBounds.x;
+        state.y = winBounds.y;
+        state.width = winBounds.width;
+        state.height = winBounds.height;
+      }
+      state.isMaximized = win.isMaximized();
+      state.isFullScreen = win.isFullScreen();
+      state.displayBounds = screen.getDisplayMatching(winBounds).bounds;
+    } catch (err) {}
+  }
+
+  function saveState(win) {
+    // Update window state only if it was provided
+    if (win) {
+      updateState(win);
+    }
+
+    // Save state
+    try {
+      mkdirp.sync(path.dirname(fullStoreFileName));
+      jsonfile.writeFileSync(fullStoreFileName, state);
+    } catch (err) {
+      // Don't care
+    }
+  }
+
+  function stateChangeHandler() {
+    // Handles both 'resize' and 'move'
+    clearTimeout(stateChangeTimer);
+    stateChangeTimer = setTimeout(updateState, eventHandlingDelay);
+  }
+
+  function closeHandler() {
+    updateState();
+  }
+
+  function closedHandler() {
+    // Unregister listeners and save state
+    unmanage();
+    saveState();
+  }
+
+  function manage(win) {
+    if (config.maximize && state.isMaximized) {
+      win.maximize();
+    }
+    if (config.fullScreen && state.isFullScreen) {
+      win.setFullScreen(true);
+    }
+    win.on('resize', stateChangeHandler);
+    win.on('move', stateChangeHandler);
+    win.on('close', closeHandler);
+    win.on('closed', closedHandler);
+    winRef = win;
+  }
+
+  function unmanage() {
+    if (winRef) {
+      winRef.removeListener('resize', stateChangeHandler);
+      winRef.removeListener('move', stateChangeHandler);
+      clearTimeout(stateChangeTimer);
+      winRef.removeListener('close', closeHandler);
+      winRef.removeListener('closed', closedHandler);
+      winRef = null;
+    }
+  }
+
+  // Load previous state
+  try {
+    state = jsonfile.readFileSync(fullStoreFileName);
+  } catch (err) {
+    // Don't care
+  }
+
+  // Check state validity
+  validateState();
+
+  // Set state fallback values
+  state = Object.assign({
+    width: config.defaultWidth || 800,
+    height: config.defaultHeight || 600
+  }, state);
+
+  return {
+    get x() { return state.x; },
+    get y() { return state.y; },
+    get width() { return state.width; },
+    get height() { return state.height; },
+    get isMaximized() { return state.isMaximized; },
+    get isFullScreen() { return state.isFullScreen; },
+    saveState: saveState,
+    unmanage: unmanage,
+    manage: manage
+  };
+};