UNPKG

electron-window-position

Version:

Easy and intuitive window positioning for electron browser windows.

149 lines (129 loc) 4.36 kB
/* * NPM Module "electron-window-position" by KIMB-technologies * https://github.com/kimbtech/electron-window-position * MIT License */ // load electron const electron = require('electron'); // link to electron app const app = electron.app; // fires a custom exception, defined here function NotReadyException( m ){ this.message = m; this.name = "NotReadyException"; } // export class for NodeJS /** * A class which allows easy and intuitive window positioning for electron browser windows. */ module.exports = class WindowPosition { /** * Initiates calculation, waits for electron app become ready before calculation. * @param {function(JSON)} gets calculated top left position as JSON {x: ?, y: ?} */ constructor ( callback ){ // position this.activeScreenTopLeftData = {x : 0, y : 0}; // nothing cacled until now this.activeScreenTopLeftCalced = false; // refers to choosen display for positioning this.display = null; // is electron app module ready? if( app.isReady() ){ // calc the position this.calcActiveScreenTopLeft(); // give the position back if( typeof callback == "function" ){ callback( this.getActiveScreenTopLeft() ); } } else{ // wait for electron app module to become ready app.on('ready', () => { // calc the position this.calcActiveScreenTopLeft(); // give the position back if( typeof callback == "function" ){ callback( this.getActiveScreenTopLeft() ); } }); } } /** * Getter for browser window position so that the window opens at the top left corner, * of the screen where the mouse is. * @return {JSON} calculated top left position as JSON {x: ?, y: ?} * @throws {NotReadyException} fired if electron app module is not ready */ getActiveScreenTopLeft(){ // already calced position? if( this.activeScreenTopLeftCalced ){ // return it return this.activeScreenTopLeftData; } else{ // no position calced and not possible now throw new NotReadyException( 'This query is impossible now, because electron is not ready yet. [electron.app.isReady()]' ); } } /** * Getter for browser window position so that the window opens centered * on the screen where the mouse is. * @param {number} width Width of the window which should be centered * @param {number} height Height of the window which should be centered * @return {JSON} calculated centered position as JSON {x: ?, y: ?} * @throws {NotReadyException} fired if electron app module is not ready */ getActiveScreenCenter( width, height ){ // make sure, the window opens in a possible position // huge window can not open centered on small screen if( this.display.bounds.width < width || this.display.bounds.height < height ){ //use top left as fallback return this.getActiveScreenTopLeft(); } // top left position var topleft = this.getActiveScreenTopLeft(); topleft.x = topleft.x - 20; topleft.y = topleft.y - 20; // calculate center var center = { x : topleft.x + Math.floor( this.display.bounds.width / 2 ), y : topleft.y + Math.floor( this.display.bounds.height / 2) }; // substract half window size => top left corner for centered window center.x = center.x - Math.floor( width / 2 ); center.y = center.y - Math.floor( height / 2 ); return center; } /** * Calculates top left position and saves it to class variables. * @private */ calcActiveScreenTopLeft(){ // electron app module ist ready, so we can access screen module const screen = electron.screen; // get the mouse's position, coordinates range over all displays var mouse = screen.getCursorScreenPoint(); // loop over all displays screen.getAllDisplays().some( display => { //check if mouse keeps in this display if( ( display.bounds.x - mouse.x ) < 0 && ( display.bounds.x + display.bounds.width - mouse.x ) > 0 && ( display.bounds.y - mouse.y ) < 0 && ( display.bounds.y + display.bounds.height - mouse.y ) > 0 ){ // get top left corner (each +20, looks better) this.activeScreenTopLeftData.x = display.bounds.x + 20; this.activeScreenTopLeftData.y = display.bounds.y + 20; // remeber this display this.display = display; //no we have calculated data this.activeScreenTopLeftCalced = true; //leave return; } }); } }