Created
May 9, 2015 00:41
-
-
Save medmunds/fb1cd6b370a6cec5d618 to your computer and use it in GitHub Desktop.
Save and restore window state for Electron (Atom-Shell)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Preserve and restore window state in localStorage. | |
// Adapted for Electron from nw.js: | |
// https://github.com/nwjs/nw.js/wiki/Preserve-window-state-between-sessions | |
// | |
// As written, it only handles a single-window app. | |
// | |
// This code is meant to run in the renderer process. | |
// To use, load from index.html (or whatever file you loadUrl into your BrowserWindow): | |
// <script src="winstate.js"></script> | |
// Ported code: | |
'use strict'; | |
/** | |
* Cross-platform window state preservation. | |
* Yes this code is quite complicated, but this is the best I came up with for | |
* current state of node-webkit Window API (v0.7.3 and later). | |
* | |
* Known issues: | |
* - Unmaximization not always sets the window (x, y) in the lastly used coordinates. | |
* - Unmaximization animation sometimes looks wierd. | |
* - Extra height added to window, at least in linux x64 gnome-shell env. It seems that | |
* when we read height then it returns it with window frame, but if we resize window | |
* then it applies dimensions only to internal document without external frame. | |
* Need to test in other environments with different visual themes. | |
* | |
* Change log: | |
* 2015-05-08 | |
* - Electron (atom-shell) port | |
* | |
* 2013-12-01 | |
* - Workaround of extra height in gnome-shell added. | |
* | |
* 2014-03-22 | |
* - Repared workaround (from 2013-12-01) behaviour when use frameless window. | |
* Now it works correctly. | |
* 2014-10-02 | |
* - Fixed cannot set windowState of null error when attempting to set localStorage | |
* | |
* 2015-03-05 | |
* - Don't call window.show() if dev tools are already open (see initWindowState). | |
*/ | |
var remote = require('remote'); | |
var win = remote.getCurrentWindow(); | |
var localStorageKey = 'windowState'; // you could include win.id for a multi-window app | |
var winState; | |
var currWinMode; | |
var resizeTimeout; | |
var isMaximizationEvent = false; | |
// extra height added in linux x64 gnome-shell env, use it as workaround | |
var deltaHeight = (function () { | |
// TODO: not sure how to find out if BrowserWindow is frameless | |
// TODO: (also not sure if this workaround is needed in Electron) | |
// use deltaHeight only in windows with frame enabled | |
// if (gui.App.manifest.window.frame) return true; else return 'disabled'; | |
return true; | |
})(); | |
function initWindowState() { | |
winState = JSON.parse(localStorage[localStorageKey] || 'null'); | |
if (winState) { | |
currWinMode = winState.mode; | |
if (currWinMode === 'maximized') { | |
win.maximize(); | |
} else { | |
restoreWindowState(); | |
} | |
} else { | |
currWinMode = 'normal'; | |
if (deltaHeight !== 'disabled') deltaHeight = 0; | |
dumpWindowState(); | |
} | |
// On Windows win.show() also acts like win.requestAttention(). | |
// If you use LiveReload, it becomes annoying when your app is already open | |
// but starts to blink in the taskbar on changes. | |
// There seems to be no way to check if a window is open, so let's at least | |
// check for dev tools. | |
if (!win.isDevToolsOpened()) { | |
win.show(); | |
} | |
} | |
function dumpWindowState() { | |
if (!winState) { | |
winState = {}; | |
} | |
// we don't want to save minimized state, only maximized or normal | |
if (currWinMode === 'maximized') { | |
winState.mode = 'maximized'; | |
} else { | |
winState.mode = 'normal'; | |
} | |
// when window is maximized you want to preserve normal | |
// window dimensions to restore them later (even between sessions) | |
if (currWinMode === 'normal') { | |
var pos = win.getPosition(), | |
size = win.getSize(); | |
winState.x = pos[0]; | |
winState.y = pos[1]; | |
winState.width = size[0]; | |
winState.height = size[1]; | |
// save delta only of it is not zero | |
if (deltaHeight !== 'disabled' && deltaHeight !== 0 && currWinMode !== 'maximized') { | |
winState.deltaHeight = deltaHeight; | |
} | |
} | |
} | |
function restoreWindowState() { | |
// deltaHeight already saved, so just restore it and adjust window height | |
if (deltaHeight !== 'disabled' && typeof winState.deltaHeight !== 'undefined') { | |
deltaHeight = winState.deltaHeight; | |
winState.height = winState.height - deltaHeight; | |
} | |
win.setSize(winState.width, winState.height); | |
win.setPosition(winState.x, winState.y); | |
} | |
function saveWindowState() { | |
dumpWindowState(); | |
localStorage[localStorageKey] = JSON.stringify(winState); | |
} | |
initWindowState(); | |
win.on('maximize', function () { | |
isMaximizationEvent = true; | |
currWinMode = 'maximized'; | |
}); | |
win.on('unmaximize', function () { | |
currWinMode = 'normal'; | |
restoreWindowState(); | |
}); | |
win.on('minimize', function () { | |
currWinMode = 'minimized'; | |
}); | |
win.on('restore', function () { | |
currWinMode = 'normal'; | |
}); | |
window.addEventListener('resize', function () { | |
// resize event is fired many times on one resize action, | |
// this hack with setTiemout forces it to fire only once | |
clearTimeout(resizeTimeout); | |
resizeTimeout = setTimeout(function () { | |
// on MacOS you can resize maximized window, so it's no longer maximized | |
if (isMaximizationEvent) { | |
// first resize after maximization event should be ignored | |
isMaximizationEvent = false; | |
} else { | |
if (currWinMode === 'maximized') { | |
currWinMode = 'normal'; | |
} | |
} | |
// there is no deltaHeight yet, calculate it and adjust window size | |
if (deltaHeight !== 'disabled' && deltaHeight === false) { | |
var size = win.getSize(), | |
width = size[0], | |
height = size[1]; | |
deltaHeight = height - winState.height; | |
// set correct size | |
if (deltaHeight !== 0) { | |
win.resizeTo(width, height - deltaHeight); | |
} | |
} | |
dumpWindowState(); | |
}, 500); | |
}, false); | |
win.on('close', function () { | |
try { | |
saveWindowState(); | |
} catch(err) { | |
console.log("winstateError: " + err); | |
} | |
this.close(true); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment