diff --git a/images/daplie-logo.png b/images/daplie-logo.png new file mode 100644 index 0000000..6d968ca Binary files /dev/null and b/images/daplie-logo.png differ diff --git a/index.js b/index.js index 1f2e3b9..db7d685 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,9 @@ function createWindow () { // Create the browser window. win = new BrowserWindow({width: 800, height: 600}); + var tray = require('./tray'); + tray.init(win); + // and load the index.html of the app. win.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), @@ -23,11 +26,19 @@ function createWindow () { win.webContents.openDevTools(); // Emitted when the window is closed. - win.on('closed', function () { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - win = null; + win.on('close', function (e) { + if (process.platform !== 'darwin') { + if (!tray.hasTray()) { + app.quit(); + return; + } + } + // We are either on Mac with a dock, or a system where we want to minimize to the tray, so + // don't actually close, just hide the window. + if (!app.isQuitting) { + e.preventDefault(); + win.hide(); + } }); } @@ -36,20 +47,17 @@ function createWindow () { // Some APIs can only be used after this event occurs. app.on('ready', createWindow); -// Quit when all windows are closed. -app.on('window-all-closed', function () { - // On macOS 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(); - } +// Mark the application as quitting so the logic we have to minimize to the tray on window +// close doesn't prevent the proper exitting of the application. +app.on('before-quit', function () { + app.isQuitting = true; }); app.on('activate', function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. - if (win === null) { - createWindow(); + if (win) { + win.show(); } }); diff --git a/package.json b/package.json index f9a4f4b..a28286d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron-demo", - "version": "0.0.1", + "version": "0.0.2", "description": "Demo Electron app to use all the 'sexy' features", "maintainers": [ "seth.gibelyou@daplie.com" diff --git a/tray.js b/tray.js new file mode 100644 index 0000000..c5697b5 --- /dev/null +++ b/tray.js @@ -0,0 +1,94 @@ +var electron = require('electron'); +var app = electron.app; + +var win, tray; + +function updateTrayMenu () { + if (!tray) { + return; + } + + var menuTemplate = []; + + if (win.isVisible()) { + menuTemplate.push({ + label: 'Hide to tray', + click: function () { win.hide(); }, + }); + } else { + menuTemplate.push({ + label: 'Electron Demo App', + click: function () { win.show(); }, + }); + } + + menuTemplate.push({ + label: 'Quit', + click: function () { app.quit(); }, + }); + tray.setContextMenu(electron.Menu.buildFromTemplate(menuTemplate)); +} + +// Check to see if the tray is supported on this system. This code was mostly copied from +// the Webtorrent project. +function checkLinuxTraySupport (cb) { + var cp = require('child_process'); + + cp.exec('dpkg --get-selections libappindicator1', function (err, stdout) { + // Unfortunately there's no cleaner way, as far as I can tell, to check + // whether a debian package is installed: + if (err) { + cb(err); + } else if (stdout.endsWith('\tinstall\n')) { + cb(null); + } else { + cb(new Error('debian package not installed')); + } + }); +} + +function createTray() { + tray = new electron.Tray('./images/daplie-logo.png'); + tray.on('click', function () { win.show(); }); + updateTrayMenu(); +} + + +function initLinux () { + checkLinuxTraySupport(function (err) { + if (!err) { + createTray(); + } + }); +} +function initWin32 () { + createTray(); +} + +function init(window) { + if (win) { + console.error("can't initialize the tray mulitple times"); + return; + } + + win = window; + win.on('blur', updateTrayMenu); + win.on('focus', updateTrayMenu); + win.on('hide', updateTrayMenu); + win.on('show', updateTrayMenu); + + // Mac apps generally do not have menu bar icons + if (process.platform === 'linux') { + initLinux(); + } + if (process.platform === 'win32') { + initWin32(); + } +} + +function hasTray() { + return !!tray; +} + +module.exports.init = init; +module.exports.hasTray = hasTray;