123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- '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
- };
- };
|