summaryrefslogtreecommitdiffhomepage
path: root/app/main.js
diff options
context:
space:
mode:
authorAndrei Mihailov <and.mikhaylov@gmail.com>2017-02-16 12:18:52 +0000
committerGitHub <noreply@github.com>2017-02-16 12:18:52 +0000
commit4aaf7e0ddbbdf9a5e03fdbb20ecabe4866de96c3 (patch)
tree8f7dfc5545c484472d3dc5138cddf6a810fa0558 /app/main.js
parent5ba4a72e546747167e7ae815724ee2dd4b2ef8fb (diff)
downloadmullvadvpn-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.js180
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();
}
});