diff options
| author | Andrei Mihailov <and.mikhaylov@gmail.com> | 2017-02-16 12:18:52 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-16 12:18:52 +0000 |
| commit | 4aaf7e0ddbbdf9a5e03fdbb20ecabe4866de96c3 (patch) | |
| tree | 8f7dfc5545c484472d3dc5138cddf6a810fa0558 /app/main.js | |
| parent | 5ba4a72e546747167e7ae815724ee2dd4b2ef8fb (diff) | |
| download | mullvadvpn-4aaf7e0ddbbdf9a5e03fdbb20ecabe4866de96c3.tar.xz mullvadvpn-4aaf7e0ddbbdf9a5e03fdbb20ecabe4866de96c3.zip | |
Feature/menubar popup window (#1)
Add menubar and tests
Diffstat (limited to 'app/main.js')
| -rw-r--r-- | app/main.js | 180 |
1 files changed, 109 insertions, 71 deletions
diff --git a/app/main.js b/app/main.js index caea31ab57..81e5d39e4c 100644 --- a/app/main.js +++ b/app/main.js @@ -1,11 +1,13 @@ import path from 'path'; -import url from 'url'; -import { app, crashReporter, BrowserWindow, Menu } from 'electron'; +import { app, crashReporter, BrowserWindow, ipcMain, Tray, Menu } from 'electron'; const isDevelopment = (process.env.NODE_ENV === 'development'); -let mainWindow = null; -let forceQuit = false; +let window = null; +let tray = null; + +// hide dock icon +app.dock.hide(); const installExtensions = async () => { const installer = require('electron-devtools-installer'); @@ -14,7 +16,7 @@ const installExtensions = async () => { 'REDUX_DEVTOOLS' ]; const forceDownload = !!process.env.UPGRADE_EXTENSIONS; - for (const name of extensions) { + for(const name of extensions) { try { await installer.default(installer[name], forceDownload); } catch (e) { @@ -23,86 +25,122 @@ const installExtensions = async () => { } }; -crashReporter.start({ - productName: 'YourName', - companyName: 'YourCompany', - submitURL: 'https://your-domain.com/url-to-submit', - uploadToServer: false -}); +const installDevTools = async () => { + await installExtensions(); -app.on('window-all-closed', () => { - // On OS X it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== 'darwin') { - app.quit(); - } -}); + // show devtools when ctrl clicked + tray.on('click', function () { + if(!window) { return; } -app.on('ready', async () => { - if (isDevelopment) { - await installExtensions(); - } + if(window.isDevToolsOpened()) { + window.devToolsWebContents.focus(); + } else { + window.openDevTools({ mode: 'detach' }); + } + }); + + // add inspect element on right click menu + window.webContents.on('context-menu', (e, props) => { + Menu.buildFromTemplate([{ + label: 'Inspect element', + click() { + window.openDevTools({ mode: 'detach' }); + window.inspectElement(props.x, props.y); + } + }]).popup(window); + }); +}; + +const getWindowPosition = () => { + const windowBounds = window.getBounds(); + const trayBounds = tray.getBounds(); + + // center window horizontally below the tray icon + const x = Math.round(trayBounds.x + (trayBounds.width / 2) - (windowBounds.width / 2)); - mainWindow = new BrowserWindow({ + // position window vertically below the tray icon + const y = Math.round(trayBounds.y + trayBounds.height); + + return { x, y }; +}; + +const createWindow = () => { + window = new BrowserWindow({ width: 320, - height: 568 + 20, // 20pt window chrome - show: false, - backgroundColor: '#000000', + height: 568, + frame: false, resizable: false, maximizable: false, - fullscreenable: false + fullscreenable: false, + transparent: true, + show: false, + webPreferences: { + // prevents renderer process code from not running when window is hidden + backgroundThrottling: false + } }); - mainWindow.loadURL(url.format({ - pathname: path.join(__dirname, 'index.html'), - protocol: 'file:', - slashes: true - })); + window.loadURL('file://' + path.join(__dirname, 'index.html')); - // show window once on first load - mainWindow.webContents.once('did-finish-load', () => { - mainWindow.show(); + // hide the window when it loses focus + window.on('blur', () => { + if(!window.webContents.isDevToolsOpened()) { + window.hide(); + } }); - mainWindow.webContents.on('did-finish-load', () => { - // Handle window logic properly on macOS: - // 1. App should not terminate if window has been closed - // 2. Click on icon in dock should re-open the window - // 3. ⌘+Q should close the window and quit the app - if (process.platform === 'darwin') { - mainWindow.on('close', function (e) { - if (!forceQuit) { - e.preventDefault(); - mainWindow.hide(); - } - }); + window.on('show', () => { + tray.setHighlightMode('always'); + }); - app.on('activate', () => { - mainWindow.show(); - }); - - app.on('before-quit', () => { - forceQuit = true; - }); - } else { - mainWindow.on('closed', () => { - mainWindow = null; - }); - } + window.on('hide', () => { + tray.setHighlightMode('never'); }); - if (isDevelopment) { - // auto-open dev tools - mainWindow.webContents.openDevTools(); +}; + +const toggleWindow = () => { + if (window.isVisible()) { + window.hide(); + } else { + showWindow(); + } +}; + +const showWindow = () => { + const position = getWindowPosition(); + window.setPosition(position.x, position.y, false); + window.show(); + window.focus(); +}; + +ipcMain.on('show-window', () => { + showWindow(); +}); + +const createTray = () => { + tray = new Tray(path.join(__dirname, 'assets/images/trayIconTemplate.png')); + tray.on('right-click', toggleWindow); + tray.on('double-click', toggleWindow); + tray.on('click', toggleWindow); +}; + +crashReporter.start({ + productName: 'YourName', + companyName: 'YourCompany', + submitURL: 'https://your-domain.com/url-to-submit', + uploadToServer: false +}); + +app.on('window-all-closed', () => { + app.quit(); +}); + +app.on('ready', () => { + createTray(); + createWindow(); - // add inspect element on right click menu - mainWindow.webContents.on('context-menu', (e, props) => { - Menu.buildFromTemplate([{ - label: 'Inspect element', - click() { - mainWindow.inspectElement(props.x, props.y); - } - }]).popup(mainWindow); - }); + if(isDevelopment) { + installDevTools(); } }); |
