├── .gitignore ├── LICENSE.md ├── README.md ├── actions.d.ts ├── actions.js ├── index.d.ts ├── package.json ├── src ├── actions │ ├── closeDevtools.ts │ ├── closeWindow.ts │ ├── hideWindow.ts │ ├── openDevtools.ts │ ├── openWindow.ts │ ├── setBounds.ts │ └── showWindow.ts ├── api │ ├── closeDevTools.ts │ ├── closeWindow.ts │ ├── getCurrentWindow.ts │ ├── getCurrentWindowName.ts │ ├── getWindow.ts │ ├── getWindowNames.ts │ ├── hideWindow.ts │ ├── openDevTools.ts │ ├── openWindow.ts │ ├── setBounds.ts │ └── showWindow.ts ├── constants │ └── index.ts ├── exportedActions.ts ├── exportedUtils.ts ├── index.ts ├── sagas │ └── WindowHandler.ts ├── utils │ ├── closeWindow.ts │ ├── createWindow.ts │ ├── getBrowserWindow.ts │ ├── getGlobalVar.ts │ ├── isBrowserProcess.ts │ ├── isRendererProcess.ts │ ├── isWindow.ts │ ├── openWindow.ts │ └── processWindows.ts └── variables │ └── windows.ts ├── tsconfig.json ├── types.d.ts ├── utils.d.ts └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | /coverage 2 | /es6 3 | /lib 4 | /node_modules 5 | /umd 6 | /dist 7 | npm-debug.log 8 | /.idea 9 | /.history 10 | /.vscode -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Michal Bureš 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electron-simple-window-manager 2 | 3 | Easily manage (open, hide, move, ...) your [Electron](https://github.com/electron/electron) windows. 4 | 5 | 6 | ## Getting Started 7 | 8 | ### Installation 9 | 10 | `npm install electron-simple-window-manager --save` 11 | 12 | ### Usage 13 | 14 | The idea behind this library is that you declare all your windows in the electron's browser process and then you can access and manage those windows just by their name 15 | 16 | 17 | ```javascript 18 | import initSimpleWindowManager from 'electron-simple-window-manager' 19 | 20 | let windows = [ 21 | { 22 | name: 'window1', 23 | config: { 24 | options: { 25 | width: 100, 26 | height: 100, 27 | show: false, 28 | }, 29 | url: 'https://github.com', 30 | setup: function(window) { 31 | window.openDevTools(); 32 | }, 33 | onClosed: function(window) { 34 | console.log('Window is closing'); 35 | } 36 | } 37 | } 38 | ] 39 | 40 | // windows is an array or a map of {name, config} 41 | initSimpleWindowManager(windows) 42 | ``` 43 | *Add window configurations in the browser process* 44 | 45 | 46 | 47 | #### Direct use 48 | 49 | ```javascript 50 | import {openWindow} from 'electron-simple-window-manager/utils' 51 | 52 | openWindow({windowName: 'window1'}) 53 | ``` 54 | 55 | #### Use with redux and redux-saga 56 | 57 | First you need to add and run the `SimpleWindowManagerSaga` 58 | ```javascript 59 | import {SimpleWindowManagerSaga} from 'electron-simple-window-manager' 60 | ``` 61 | *If you are not familiar with `redux-saga` go [see its documentation](https://github.com/yelouafi/redux-saga#mainjs)* 62 | 63 | Now that our helper saga is up and running you can `dispatch` one of the available actions and the saga will process it. 64 | 65 | ```javascript 66 | import {openWindow} from 'electron-simple-window-manager/actions' 67 | 68 | dispatch(openWindow({windowName: 'window1'})) 69 | ``` 70 | 71 | ## Config 72 | 73 | * **options**: (*object*) - Same as [`BrowserWindow` options](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#new-browserwindowoptions) 74 | * **url**: (*url*) - Url to load with [`loadUrl`](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winloadurlurl-options) 75 | * **setup**: (*function*) - After the window is created and the url loaded this setup function will receive the newly created window as its argument 76 | * **onClosed**: (*function*) - Called during the `closed` window event with the closing window as its argument 77 | 78 | ```javascript 79 | import initSimpleWindowManager from 'electron-simple-window-manager' 80 | 81 | let config = { 82 | name: 'window1', 83 | config: { 84 | options: { 85 | width: 100, 86 | height: 100, 87 | show: false, 88 | }, 89 | url: 'https://github.com', 90 | setup: function(window) { 91 | window.openDevTools(); 92 | }, 93 | onClosed: function(window) { 94 | console.log('Window is closing'); 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | ## Utils 101 | 102 | * **openWindow**: Open window by name 103 | * **windowName** 104 | * **closeWindow**: Close window by name or id 105 | * **{windowName, windowId}** 106 | * **showWindow**: Show window by name or id 107 | * **{windowName, windowId}** 108 | * **hideWindow**: Hide window by name or id 109 | * **{windowName, windowId}** 110 | * **openDevTools**: Open DevTools in given window 111 | * **{windowName, windowId}** - if no name or id is given the current window will be used 112 | * **options** - same as in the [Electron documentation](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#webcontentsopendevtoolsoptions) 113 | * **closeDevTools**: Close DevTools in given window 114 | * **{windowName, windowId}** - if no name or id is given the current window will be used 115 | * **setBounds**: Move or resize given window ([see documentation](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winsetboundsoptions-animate)) 116 | * **{windowName, windowId}** - if no name or id is given the current window will be used 117 | * **options** - You don't have to provide all the arguments as in the official function. Using `{x: 0}` will move the window along the x axis and keep the rest unchanged. 118 | * x 119 | * y 120 | * width 121 | * height 122 | * **animate**: true/false 123 | * **getCurrentWindow**: Returns current `BrowserWindow` 124 | * **getCurrentWindowName**: Returns name of the current window 125 | * **getWindow**: 126 | * **{windowName, windowId}** - if no name or id is given the current window will be used 127 | * **getWindowNames**: Returns list of all known window names 128 | 129 | ## Actions 130 | 131 | * **openWindow**: Open window by name 132 | * **windowName** 133 | * **closeWindow**: Close window by name or id 134 | * **{windowName, windowId}** 135 | * **showWindow**: Show window by name or id 136 | * **{windowName, windowId}** 137 | * **hideWindow**: Hide window by name or id 138 | * **{windowName, windowId}** 139 | * **openDevTools**: Open DevTools in given window 140 | * **{windowName, windowId}** - if no name or id is given the current window will be used 141 | * **options** - same as in the [Electron documentation](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#webcontentsopendevtoolsoptions) 142 | * **closeDevTools**: Close DevTools in given window 143 | * **{windowName, windowId}** - if no name or id is given the current window will be used 144 | * **setBounds**: Move or resize given window ([see documentation](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winsetboundsoptions-animate)) 145 | * **{windowName, windowId}** - if no name or id is given the current window will be used 146 | * **options** - You don't have to provide all the arguments as in the official function. Using `{x: 0}` will move the window along the x axis and keep the rest unchanged. 147 | * x 148 | * y 149 | * width 150 | * height 151 | * **animate**: true/false 152 | 153 | ## License 154 | 155 | MIT -------------------------------------------------------------------------------- /actions.d.ts: -------------------------------------------------------------------------------- 1 | import {WindowName, WindowId, WindowNameOrId, Action} from './types'; 2 | export {WindowName, WindowId, WindowNameOrId, Action}; 3 | 4 | /** 5 | * Test test test xxx 6 | * 7 | * @export 8 | * @param {WindowName} target AAAa aaa 9 | * @param {string} xxx BBBB bbb 10 | */ 11 | export function openWindow(target:WindowName):Action; 12 | export function closeWindow(target:WindowName):Action; 13 | export function closeWindow(target:WindowId):Action; 14 | export function showWindow(target:WindowName):Action; 15 | export function showWindow(target:WindowId):Action; 16 | export function hideWindow(target:WindowName):Action; 17 | export function hideWindow(target:WindowId):Action; 18 | export function openDevTools(target:WindowName, options:object):Action; 19 | export function openDevTools(target:WindowId, options:object):Action; 20 | export function closeDevTools(target:WindowName):Action; 21 | export function closeDevTools(target:WindowId):Action; 22 | export function setBounds(target:WindowName, options:object, animate?:boolean):Action; 23 | export function setBounds(target:WindowId, options:object, animate?:boolean):Action; 24 | -------------------------------------------------------------------------------- /actions.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/exportedActions'); -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import {WindowConfig, WindowDefinition} from './types'; 2 | export {WindowConfig, WindowDefinition}; 3 | 4 | 5 | export default function processWindows(windows:Array):void; 6 | export function SimpleWindowManagerSaga():void; 7 | 8 | 9 | import * as utils from './utils'; 10 | import * as actions from './actions'; 11 | export {actions, utils}; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-simple-window-manager", 3 | "version": "1.1.1", 4 | "description": "Manage multiple Electron windows", 5 | "main": "lib/index.js", 6 | "files": [ 7 | "lib", 8 | "actions.js", 9 | "utils.js", 10 | "index.d.ts", 11 | "types.d.ts", 12 | "actions.d.ts", 13 | "utils.d.ts" 14 | ], 15 | "scripts": { 16 | "clean": "rimraf lib dist", 17 | "test": "cross-env NODE_ENV=test mocha", 18 | "test:select": "cross-env NODE_ENV=test mocha test/selectTestsOnly.js", 19 | "test:watch": "cross-env NODE_ENV=test mocha --watch", 20 | "build:dev": "cross-env NODE_ENV=development rimraf lib/&&tsc -p .", 21 | "build": "cross-env NODE_ENV=production rimraf lib/&&tsc -p ." 22 | }, 23 | "dependencies": {}, 24 | "devDependencies": { 25 | "@types/electron": "^1.4.33", 26 | "app-module-path": "^2.2.0", 27 | "cross-env": "^3.2.3", 28 | "expect": "^1.20.2", 29 | "mocha": "^3.2.0", 30 | "redux": "^3.6.0", 31 | "redux-saga": "^0.14.3", 32 | "rimraf": "^2.6.1", 33 | "typescript": "^2.2.1" 34 | }, 35 | "typings": "./index.d.ts", 36 | "author": "Michal Bureš", 37 | "homepage": "https://github.com/MichalBures/electron-simple-window-manager", 38 | "license": "MIT", 39 | "repository": { 40 | "type": "git", 41 | "url": "https://github.com/MichalBures/electron-simple-window-manager.git" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/actions/closeDevtools.ts: -------------------------------------------------------------------------------- 1 | import {CLOSE_DEVTOOLS} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | 7 | export function closeDevTools({ windowName, windowId }: WindowNameOrId): Action 8 | { 9 | return { 10 | type: CLOSE_DEVTOOLS, 11 | payload: { 12 | windowName, 13 | windowId, 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/actions/closeWindow.ts: -------------------------------------------------------------------------------- 1 | import {CLOSE_WINDOW} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | export function closeWindow({ windowName, windowId }: WindowNameOrId): Action 7 | { 8 | return { 9 | type: CLOSE_WINDOW, 10 | payload: { 11 | windowName, 12 | windowId, 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/actions/hideWindow.ts: -------------------------------------------------------------------------------- 1 | import {HIDE_WINDOW} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | 7 | export function hideWindow({ windowName, windowId }: WindowNameOrId): Action 8 | { 9 | return { 10 | type: HIDE_WINDOW, 11 | payload: { 12 | windowName, 13 | windowId, 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/actions/openDevtools.ts: -------------------------------------------------------------------------------- 1 | import {OPEN_DEVTOOLS} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | export function openDevTools({ windowName, windowId }: WindowNameOrId, options?):Action 7 | { 8 | return { 9 | type: OPEN_DEVTOOLS, 10 | payload: { 11 | windowName, 12 | windowId, 13 | options, 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/actions/openWindow.ts: -------------------------------------------------------------------------------- 1 | import {OPEN_WINDOW} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | export function openWindow({windowName} : WindowName):Action 7 | { 8 | return { 9 | type: OPEN_WINDOW, 10 | payload: { 11 | windowName, 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/actions/setBounds.ts: -------------------------------------------------------------------------------- 1 | import {SET_BOUNDS} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | export function setBounds({ windowName, windowId }: WindowNameOrId, options, animate = false) 7 | { 8 | return { 9 | type: SET_BOUNDS, 10 | payload: { 11 | windowName, 12 | windowId, 13 | options, 14 | animate, 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/actions/showWindow.ts: -------------------------------------------------------------------------------- 1 | import {SHOW_WINDOW} from '../constants' 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import {Action} from "../../types"; 5 | 6 | export function showWindow({ windowName, windowId }: WindowNameOrId): Action 7 | { 8 | return { 9 | type: SHOW_WINDOW, 10 | payload: { 11 | windowName, 12 | windowId, 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/api/closeDevTools.ts: -------------------------------------------------------------------------------- 1 | import { getWindow } from './getWindow'; 2 | import { isBrowserProcess } from '../utils/isBrowserProcess'; 3 | import { getCurrentWindow } from './getCurrentWindow'; 4 | 5 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 6 | 7 | 8 | export function closeDevTools(target?: WindowNameOrId | undefined) { 9 | const { windowName, windowId } = target; 10 | 11 | let window: Electron.BrowserWindow; 12 | if (windowName == null && windowId == null) { 13 | if (isBrowserProcess()) { 14 | return; 15 | } 16 | 17 | window = getCurrentWindow(); 18 | } 19 | else { 20 | 21 | window = getWindow({ 22 | windowName, 23 | windowId 24 | }); 25 | } 26 | 27 | if (window != null) { 28 | window.webContents.closeDevTools(); 29 | } 30 | } -------------------------------------------------------------------------------- /src/api/closeWindow.ts: -------------------------------------------------------------------------------- 1 | import { getGlobalVar } from '../utils/getGlobalVar'; 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import { ICloseWindow } from '../utils/closeWindow'; 5 | 6 | export function closeWindow(target?: WindowNameOrId | undefined) { 7 | const { windowName, windowId } = target; 8 | 9 | 10 | let globalCloseWindow:ICloseWindow = getGlobalVar('closeWindow'); 11 | 12 | if (globalCloseWindow == null) { 13 | return null; 14 | } 15 | 16 | globalCloseWindow({ windowName, windowId }); 17 | } -------------------------------------------------------------------------------- /src/api/getCurrentWindow.ts: -------------------------------------------------------------------------------- 1 | import {isBrowserProcess} from '../utils/isBrowserProcess'; 2 | import {isRendererProcess} from '../utils/isRendererProcess'; 3 | 4 | 5 | export function getCurrentWindow():Electron.BrowserWindow|null { 6 | if (isBrowserProcess()) 7 | { 8 | return null; 9 | } 10 | 11 | if (isRendererProcess()) 12 | { 13 | return require('electron').remote.getCurrentWindow(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/api/getCurrentWindowName.ts: -------------------------------------------------------------------------------- 1 | import {getGlobalVar} from '../utils/getGlobalVar'; 2 | import {getCurrentWindow} from './getCurrentWindow'; 3 | 4 | import { IGetWindowNameById } from '../variables/windows'; 5 | 6 | export function getCurrentWindowName():string 7 | { 8 | let window = getCurrentWindow(); 9 | 10 | if (window == null) { 11 | return null; 12 | } 13 | 14 | let globalGetWindowNameById:IGetWindowNameById = getGlobalVar('getWindowNameById'); 15 | 16 | if (globalGetWindowNameById == null) 17 | { 18 | return null; 19 | } 20 | 21 | return globalGetWindowNameById(window.id); 22 | } -------------------------------------------------------------------------------- /src/api/getWindow.ts: -------------------------------------------------------------------------------- 1 | import { getBrowserWindow } from '../utils/getBrowserWindow'; 2 | import { getGlobalVar } from '../utils/getGlobalVar'; 3 | import { getCurrentWindow } from './getCurrentWindow'; 4 | 5 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 6 | 7 | 8 | const BrowserWindow = getBrowserWindow(); 9 | 10 | export function getWindow(target: WindowName): Electron.BrowserWindow; 11 | export function getWindow(target: WindowId): Electron.BrowserWindow; 12 | export function getWindow(target?: WindowNameOrId): Electron.BrowserWindow; 13 | export function getWindow(target?: WindowNameOrId): Electron.BrowserWindow { 14 | const { windowName, windowId } = target; 15 | 16 | 17 | if (windowName != null) { 18 | return getWindowByName(windowName); 19 | } 20 | 21 | if (windowId != null) { 22 | return getWindowById(windowId); 23 | } 24 | 25 | if (windowName == null && windowId == null) { 26 | return getCurrentWindow(); 27 | } 28 | } 29 | 30 | 31 | export function getWindowById(windowId: number): Electron.BrowserWindow { 32 | return BrowserWindow.fromId(windowId); 33 | } 34 | 35 | import { IGetWindowIdByName } from '../variables/windows'; 36 | export function getWindowByName(windowName: string): Electron.BrowserWindow { 37 | let globalGetWindowIdByName: IGetWindowIdByName = getGlobalVar('getWindowIdByName'); 38 | 39 | if (globalGetWindowIdByName == null) { 40 | return; 41 | } 42 | 43 | const id = globalGetWindowIdByName(windowName); 44 | 45 | if (id == null) { 46 | return null; 47 | } 48 | 49 | return BrowserWindow.fromId(id); 50 | } -------------------------------------------------------------------------------- /src/api/getWindowNames.ts: -------------------------------------------------------------------------------- 1 | import {getGlobalVar} from '../utils/getGlobalVar'; 2 | 3 | import { IGetWindowNames } from '../variables/windows'; 4 | 5 | export function getWindowNames():Array { 6 | let globalGetWindowConfig:IGetWindowNames = getGlobalVar('getWindowNames'); 7 | 8 | if (globalGetWindowConfig == null) 9 | { 10 | return null; 11 | } 12 | 13 | return globalGetWindowConfig(); 14 | } -------------------------------------------------------------------------------- /src/api/hideWindow.ts: -------------------------------------------------------------------------------- 1 | import { getWindow } from './getWindow'; 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | 5 | 6 | export function hideWindow(target?: WindowNameOrId | undefined) { 7 | const { windowName, windowId } = target; 8 | 9 | 10 | let window = getWindow({ windowName, windowId }); 11 | 12 | if (window != null) { 13 | window.hide(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/api/openDevTools.ts: -------------------------------------------------------------------------------- 1 | import { getWindow } from './getWindow'; 2 | import { isBrowserProcess } from '../utils/isBrowserProcess'; 3 | import { getCurrentWindow } from './getCurrentWindow'; 4 | 5 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 6 | 7 | 8 | export function openDevTools(target?: WindowNameOrId | undefined, options?:object) { 9 | const { windowName, windowId } = target; 10 | 11 | 12 | let window: Electron.BrowserWindow; 13 | if (windowName == null && windowId == null) { 14 | if (isBrowserProcess()) { 15 | return; 16 | } 17 | 18 | window = getCurrentWindow(); 19 | } 20 | else { 21 | 22 | window = getWindow({ 23 | windowName, 24 | windowId 25 | }); 26 | } 27 | 28 | if (window != null) { 29 | window.webContents.openDevTools(options); 30 | } 31 | } -------------------------------------------------------------------------------- /src/api/openWindow.ts: -------------------------------------------------------------------------------- 1 | import {getGlobalVar} from '../utils/getGlobalVar'; 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | import { IOpenWindow } from '../utils/openWindow'; 5 | 6 | 7 | export function openWindow({windowName}:WindowName):Electron.BrowserWindow 8 | { 9 | let globalOpenWindow:IOpenWindow = getGlobalVar('openWindow'); 10 | 11 | if (globalOpenWindow == null) 12 | { 13 | return null; 14 | } 15 | 16 | return globalOpenWindow({windowName}); 17 | } -------------------------------------------------------------------------------- /src/api/setBounds.ts: -------------------------------------------------------------------------------- 1 | import { getWindow } from './getWindow'; 2 | import { isBrowserProcess } from '../utils/isBrowserProcess'; 3 | import { getCurrentWindow } from './getCurrentWindow'; 4 | 5 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 6 | 7 | 8 | export function setBounds(target?: WindowNameOrId | undefined, options = {}, animate = false) { 9 | const { windowName, windowId } = target; 10 | 11 | let window: Electron.BrowserWindow; 12 | if (windowName == null && windowId == null) { 13 | if (isBrowserProcess()) { 14 | return; 15 | } 16 | 17 | window = getCurrentWindow(); 18 | } 19 | else { 20 | 21 | window = getWindow({ 22 | windowName, 23 | windowId 24 | }); 25 | } 26 | 27 | if (window != null) { 28 | let bounds = window.getBounds(); 29 | window.setBounds({ ...bounds, ...options }, animate); 30 | } 31 | } -------------------------------------------------------------------------------- /src/api/showWindow.ts: -------------------------------------------------------------------------------- 1 | import {getWindow} from './getWindow'; 2 | 3 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 4 | 5 | 6 | export function showWindow(target?: WindowNameOrId | undefined) 7 | { 8 | const { windowName, windowId } = target; 9 | 10 | let window = getWindow({windowName, windowId}); 11 | 12 | if (window != null) { 13 | window.show(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const GLOBAL_VAR_NAME = 'SIMPLE_WINDOW_MANAGER'; 2 | 3 | export const LIB_PREFIX = 'ElectronSimpleWindowManager/'; 4 | 5 | export const OPEN_WINDOW = LIB_PREFIX + 'OPEN_WINDOW'; 6 | export const CLOSE_WINDOW = LIB_PREFIX + 'CLOSE_WINDOW'; 7 | export const SHOW_WINDOW = LIB_PREFIX + 'SHOW_WINDOW'; 8 | export const HIDE_WINDOW = LIB_PREFIX + 'HIDE_WINDOW'; 9 | export const OPEN_DEVTOOLS = LIB_PREFIX + 'OPEN_DEVTOOLS'; 10 | export const CLOSE_DEVTOOLS = LIB_PREFIX + 'CLOSE_DEVTOOLS'; 11 | export const SET_BOUNDS = LIB_PREFIX + 'SET_BOUNDS'; -------------------------------------------------------------------------------- /src/exportedActions.ts: -------------------------------------------------------------------------------- 1 | export {openWindow} from './actions/openWindow'; 2 | export {closeWindow} from './actions/closeWindow'; 3 | export {showWindow} from './actions/showWindow'; 4 | export {hideWindow} from './actions/hideWindow'; 5 | export {openDevTools} from './actions/openDevtools'; 6 | export {closeDevTools} from './actions/closeDevtools'; 7 | export {setBounds} from './actions/setBounds'; -------------------------------------------------------------------------------- /src/exportedUtils.ts: -------------------------------------------------------------------------------- 1 | export {openWindow} from './api/openWindow'; 2 | export {closeWindow} from './api/closeWindow'; 3 | export {showWindow} from './api/showWindow'; 4 | export {hideWindow} from './api/hideWindow'; 5 | export {openDevTools} from './api/openDevTools'; 6 | export {closeDevTools} from './api/closeDevTools'; 7 | export {setBounds} from './api/setBounds'; 8 | export {getCurrentWindow} from './api/getCurrentWindow'; 9 | export {getCurrentWindowName} from './api/getCurrentWindowName'; 10 | export {getWindow} from './api/getWindow'; 11 | export {getWindowNames} from './api/getWindowNames'; -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import {getWindowNames} from './variables/windows'; 2 | import {isBrowserProcess} from './utils/isBrowserProcess'; 3 | import {processWindows} from './utils/processWindows'; 4 | import {openWindow} from './utils/openWindow'; 5 | import {closeWindow} from './utils/closeWindow'; 6 | import {GLOBAL_VAR_NAME} from './constants'; 7 | import { 8 | getWindowIdByName, 9 | getWindowNameById, 10 | } from './variables/windows'; 11 | 12 | if (isBrowserProcess()) { 13 | global[GLOBAL_VAR_NAME] = { 14 | getWindowIdByName, 15 | getWindowNameById, 16 | openWindow, 17 | closeWindow, 18 | getWindowNames, 19 | } 20 | } 21 | 22 | export default processWindows; 23 | export {WindowHandler as SimpleWindowManagerSaga} from './sagas/WindowHandler'; -------------------------------------------------------------------------------- /src/sagas/WindowHandler.ts: -------------------------------------------------------------------------------- 1 | import { takeEvery } from 'redux-saga/effects'; 2 | import { 3 | OPEN_DEVTOOLS, 4 | CLOSE_DEVTOOLS, 5 | OPEN_WINDOW, 6 | CLOSE_WINDOW, 7 | SHOW_WINDOW, 8 | HIDE_WINDOW, 9 | SET_BOUNDS, 10 | } from '../constants'; 11 | import { getCurrentWindowName } from '../api/getCurrentWindowName'; 12 | import { isBrowserProcess } from '../utils/isBrowserProcess'; 13 | import { openDevTools } from '../api/openDevTools'; 14 | import { closeDevTools } from '../api/closeDevTools'; 15 | import { openWindow } from '../api/openWindow'; 16 | import { closeWindow } from '../api/closeWindow'; 17 | import { showWindow } from '../api/showWindow'; 18 | import { setBounds } from '../api/setBounds'; 19 | import { hideWindow } from '../api/hideWindow'; 20 | 21 | export function* WindowHandler(): IterableIterator { 22 | const task = yield takeEvery( 23 | [OPEN_DEVTOOLS, CLOSE_DEVTOOLS, OPEN_WINDOW, CLOSE_WINDOW, SHOW_WINDOW, HIDE_WINDOW, SET_BOUNDS], 24 | handleAction 25 | ); 26 | } 27 | 28 | function* handleAction(action) { 29 | let { windowName, windowId } = action.payload; 30 | 31 | if (windowName == null) { 32 | if (isBrowserProcess()) { 33 | return; 34 | } 35 | windowName = yield getCurrentWindowName(); 36 | } 37 | 38 | switch (action.type) { 39 | case OPEN_WINDOW: 40 | { 41 | yield openWindow({ windowName }); 42 | break; 43 | } 44 | case CLOSE_WINDOW: 45 | { 46 | yield closeWindow({ 47 | windowName, 48 | windowId 49 | }); 50 | break; 51 | } 52 | case SHOW_WINDOW: 53 | { 54 | yield showWindow({ 55 | windowName, 56 | windowId 57 | }); 58 | break; 59 | } 60 | case HIDE_WINDOW: 61 | { 62 | yield hideWindow({ 63 | windowName, 64 | windowId 65 | }); 66 | break; 67 | } 68 | case OPEN_DEVTOOLS: 69 | { 70 | yield openDevTools({ 71 | windowName, 72 | windowId 73 | }, action.payload.options); 74 | break; 75 | } 76 | case CLOSE_DEVTOOLS: 77 | { 78 | yield closeDevTools({ 79 | windowName, 80 | windowId 81 | }); 82 | break; 83 | } 84 | case SET_BOUNDS: 85 | { 86 | yield setBounds( 87 | { 88 | windowName, 89 | windowId 90 | }, 91 | action.payload.options, 92 | action.payload.animate, 93 | ); 94 | break; 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /src/utils/closeWindow.ts: -------------------------------------------------------------------------------- 1 | import {isWindow, removeWindowById} from '../variables/windows'; 2 | import {getWindowByName, getWindowById} from '../api/getWindow'; 3 | 4 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 5 | 6 | export type ICloseWindow = (target?: WindowNameOrId | undefined) => void; 7 | 8 | export function closeWindow(target?: WindowNameOrId | undefined) { 9 | const { windowName, windowId } = target; 10 | 11 | let window:Electron.BrowserWindow; 12 | 13 | if (windowName != null) { 14 | window = getWindowByName(windowName); 15 | 16 | } 17 | 18 | if (windowId != null) 19 | { 20 | window = getWindowById(windowId); 21 | 22 | } 23 | 24 | if (window == null) { 25 | return; 26 | } 27 | 28 | removeWindowById(window.id); 29 | 30 | window.close(); 31 | } -------------------------------------------------------------------------------- /src/utils/createWindow.ts: -------------------------------------------------------------------------------- 1 | import {getBrowserWindow} from './getBrowserWindow'; 2 | import { WindowName, WindowConfig } from '../../types'; 3 | 4 | 5 | const BrowserWindow = getBrowserWindow(); 6 | 7 | export function createWindow(config:WindowConfig):Electron.BrowserWindow { 8 | let window:Electron.BrowserWindow = new BrowserWindow(config.options); 9 | 10 | window.loadURL(config.url); 11 | 12 | if (config.setup != null && typeof config.setup === 'function') { 13 | config.setup(window); 14 | } 15 | 16 | 17 | window.on('closed', function () 18 | { 19 | if (config.onClosed != null && typeof config.onClosed === 'function') { 20 | config.onClosed(window); 21 | } 22 | 23 | window = null; 24 | }); 25 | 26 | return window; 27 | } -------------------------------------------------------------------------------- /src/utils/getBrowserWindow.ts: -------------------------------------------------------------------------------- 1 | import {isBrowserProcess} from './isBrowserProcess'; 2 | import {isRendererProcess} from './isRendererProcess'; 3 | 4 | export function getBrowserWindow():typeof Electron.BrowserWindow { 5 | if (isBrowserProcess()) 6 | { 7 | return require('electron').BrowserWindow; 8 | } 9 | 10 | if (isRendererProcess()) 11 | { 12 | return require('electron').remote.BrowserWindow as any; 13 | } 14 | } -------------------------------------------------------------------------------- /src/utils/getGlobalVar.ts: -------------------------------------------------------------------------------- 1 | import {isBrowserProcess} from './isBrowserProcess'; 2 | import {isRendererProcess} from './isRendererProcess'; 3 | import {GLOBAL_VAR_NAME} from '../constants'; 4 | 5 | export function getGlobalVar(globalVarName:string):any 6 | { 7 | let globalVar = null; 8 | 9 | if (isBrowserProcess()) 10 | { 11 | globalVar = global[GLOBAL_VAR_NAME]; 12 | } 13 | 14 | if (isRendererProcess()) 15 | { 16 | let remote = require('electron').remote; 17 | globalVar = remote.getGlobal(GLOBAL_VAR_NAME); 18 | } 19 | 20 | if (globalVar != null && globalVar[globalVarName] != null) 21 | { 22 | return globalVar[globalVarName]; 23 | } 24 | else 25 | { 26 | return null; 27 | } 28 | } -------------------------------------------------------------------------------- /src/utils/isBrowserProcess.ts: -------------------------------------------------------------------------------- 1 | import {type} from 'process'; 2 | 3 | export function isBrowserProcess():boolean 4 | { 5 | return type === 'browser'; 6 | } -------------------------------------------------------------------------------- /src/utils/isRendererProcess.ts: -------------------------------------------------------------------------------- 1 | import {type} from 'process'; 2 | 3 | export function isRendererProcess():boolean 4 | { 5 | return process.type === 'renderer'; 6 | } -------------------------------------------------------------------------------- /src/utils/isWindow.ts: -------------------------------------------------------------------------------- 1 | import {getWindow} from '../api/getWindow'; 2 | 3 | export function isWindow(windowName:string):boolean { 4 | let window = getWindow({windowName}) 5 | 6 | return window != null; 7 | } -------------------------------------------------------------------------------- /src/utils/openWindow.ts: -------------------------------------------------------------------------------- 1 | import {addWindow, getWindowConfig} from '../variables/windows'; 2 | import {createWindow} from './createWindow'; 3 | import {isWindow} from './isWindow'; 4 | 5 | import { WindowName, WindowId, WindowNameOrId, WindowConfig } from '../../types'; 6 | 7 | 8 | export type IOpenWindow = (target: WindowName) => Electron.BrowserWindow; 9 | 10 | export function openWindow({windowName}:WindowName):Electron.BrowserWindow { 11 | if (isWindow(windowName)) { 12 | return; 13 | } 14 | let config = getWindowConfig({windowName}); 15 | if (config == null) { 16 | return null; 17 | } 18 | let window = createWindow(config); 19 | if (window == null) { 20 | return null; 21 | } 22 | addWindow(windowName, window.id); 23 | return window; 24 | } -------------------------------------------------------------------------------- /src/utils/processWindows.ts: -------------------------------------------------------------------------------- 1 | import {addWindowConfig} from '../variables/windows' 2 | 3 | import { WindowName, WindowDefinition } from '../../types'; 4 | 5 | 6 | export function processWindows(windows:Array):void { 7 | windows.map((window) => { 8 | addWindowConfig(window.name, window.config) 9 | }) 10 | } -------------------------------------------------------------------------------- /src/variables/windows.ts: -------------------------------------------------------------------------------- 1 | import { WindowName, WindowConfig } from '../../types'; 2 | 3 | 4 | interface IWindowIds { 5 | [name: number]: string; 6 | } 7 | let windowIds: IWindowIds = {}; 8 | 9 | 10 | interface IWindowNames { 11 | [name: string]: number; 12 | } 13 | let windowNames: IWindowNames = {}; 14 | 15 | interface IStoredWindows { 16 | [name: string]: WindowConfig; 17 | } 18 | let storedWindows: IStoredWindows = {}; 19 | 20 | 21 | 22 | export function addWindow(name: string, id: number): void { 23 | windowNames[name] = id; 24 | windowIds[id] = name; 25 | } 26 | 27 | export function addWindowConfig(name: string, config: WindowConfig): void { 28 | storedWindows[name] = config; 29 | } 30 | 31 | export function removeWindowConfig(name: string): void { 32 | delete storedWindows[name]; 33 | } 34 | 35 | export function removeWindowByName(name: string): void { 36 | delete windowIds[windowNames[name]]; 37 | delete windowNames[name]; 38 | } 39 | 40 | export function removeWindowById(id: number): void { 41 | delete windowNames[windowIds[id]]; 42 | delete windowIds[id]; 43 | } 44 | 45 | export type IGetWindowNameById = (id: number) => string; 46 | export function getWindowNameById(id: number) { 47 | return windowIds[id]; 48 | } 49 | 50 | export type IGetWindowIdByName = (name: string) => number; 51 | export function getWindowIdByName(name:string) { 52 | return windowNames[name]; 53 | } 54 | 55 | export function getWindowConfig({ windowName }: WindowName) { 56 | return storedWindows[windowName]; 57 | } 58 | 59 | export type IGetWindowNames = () => Array; 60 | export function getWindowNames(): Array { 61 | return Object.keys(storedWindows); 62 | } 63 | 64 | export function isWindow(name): boolean { 65 | return getWindowIdByName(name) > 0; 66 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "commonjs", 5 | "sourceMap": false, 6 | "noImplicitAny": false, 7 | "jsx": "preserve", 8 | "baseUrl": "./src", 9 | "rootDir": "./src", 10 | "allowJs": true, 11 | "moduleResolution": "node", 12 | "strictNullChecks": false, 13 | "outDir": "./lib", 14 | "declaration": false 15 | }, 16 | "include": [ 17 | "src/**/*" 18 | ], 19 | "exclude": [ 20 | "**/*.spec.ts", 21 | ".history/**/*" 22 | ] 23 | } -------------------------------------------------------------------------------- /types.d.ts: -------------------------------------------------------------------------------- 1 | export interface WindowConfig { 2 | url:string; 3 | options:Electron.BrowserWindowOptions; 4 | setup?:(window:Electron.BrowserWindow) => void; 5 | onClosed?:(window:Electron.BrowserWindow) => void; 6 | } 7 | 8 | export interface Action { 9 | type: any; 10 | payload: any; 11 | meta?: any; 12 | error?:any; 13 | } 14 | 15 | export interface WindowDefinition { 16 | name:string; 17 | config:WindowConfig; 18 | } 19 | 20 | export interface WindowName { 21 | windowName:string; 22 | } 23 | export interface WindowId { 24 | windowId:number; 25 | } 26 | 27 | export type WindowNameOrId = WindowName & WindowId; -------------------------------------------------------------------------------- /utils.d.ts: -------------------------------------------------------------------------------- 1 | import {BrowserWindow} from 'electron'; 2 | 3 | import {WindowName, WindowId, WindowNameOrId} from './types'; 4 | export {WindowName, WindowId, WindowNameOrId}; 5 | 6 | /** 7 | * Close the current window. 8 | * 9 | * @export 10 | */ 11 | export function closeWindow():void; 12 | export function openWindow(target:WindowName):void; 13 | export function closeWindow(target:WindowName):void; 14 | export function closeWindow(target:WindowId):void; 15 | /** 16 | * Show the current window. 17 | * 18 | * @export 19 | */ 20 | export function showWindow():void; 21 | export function showWindow(target:WindowName):void; 22 | export function showWindow(target:WindowId):void; 23 | /** 24 | * Hide the current window. 25 | * 26 | * @export 27 | */ 28 | export function hideWindow():void; 29 | export function hideWindow(target:WindowName):void; 30 | export function hideWindow(target:WindowId):void; 31 | 32 | /** 33 | * Open Dev Tools in the current window. 34 | * 35 | * @export 36 | * @param {object} options 37 | */ 38 | export function openDevTools(options:object):void; 39 | export function openDevTools(target:WindowName, options:object):void; 40 | export function openDevTools(target:WindowId, options:object):void; 41 | /** 42 | * Close Dev Tools in the current window. 43 | * 44 | * @export 45 | */ 46 | export function closeDevTools():void; 47 | export function closeDevTools(target:WindowName):void; 48 | export function closeDevTools(target:WindowId):void; 49 | /** 50 | * Set bounds of the current window. 51 | * 52 | * @export 53 | * @param {object} options 54 | * @param {boolean} [animate] 55 | */ 56 | export function setBounds(options:object, animate?:boolean):void; 57 | export function setBounds(target:WindowName, options:object, animate?:boolean):void; 58 | export function setBounds(target:WindowId, options:object, animate?:boolean):void; 59 | 60 | export function getCurrentWindow():Electron.BrowserWindow|null; 61 | export function getCurrentWindowName():string|null; 62 | /** 63 | * Get the current window. 64 | */ 65 | export function getWindow():Electron.BrowserWindow|null; 66 | export function getWindow(target:WindowName):Electron.BrowserWindow|null; 67 | export function getWindow(target:WindowId):Electron.BrowserWindow|null; 68 | export function getWindowNames():Array; 69 | 70 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/exportedUtils'); --------------------------------------------------------------------------------