Source: index.js

/*
 * 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 ){
		// 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;
			}
		});
	}
}