2
2
mirror of https://github.com/Llewellynvdm/nativefier.git synced 2024-06-26 15:14:07 +00:00

Fix #304 - Add --tray CLI flag to let app running in background on window close. Supports in-title counter. (#457)

This commit is contained in:
omouren 2017-10-06 01:32:48 +02:00 committed by Ronan Jouchet
parent 4c581f9067
commit 885790bc22
7 changed files with 99 additions and 3 deletions

View File

@ -10,11 +10,14 @@ const { isOSX, linkIsInternal, getCssToInject, shouldInjectCss } = helpers;
const ZOOM_INTERVAL = 0.1; const ZOOM_INTERVAL = 0.1;
function maybeHideWindow(window, event, fastQuit) { function maybeHideWindow(window, event, fastQuit, tray) {
if (isOSX() && !fastQuit) { if (isOSX() && !fastQuit) {
// this is called when exiting from clicking the cross button on the window // this is called when exiting from clicking the cross button on the window
event.preventDefault(); event.preventDefault();
window.hide(); window.hide();
} else if (!fastQuit && tray) {
event.preventDefault();
window.hide();
} }
// will close the window on other platforms // will close the window on other platforms
} }
@ -211,7 +214,7 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
mainWindow.setFullScreen(false); mainWindow.setFullScreen(false);
mainWindow.once('leave-full-screen', maybeHideWindow.bind(this, mainWindow, event, options.fastQuit)); mainWindow.once('leave-full-screen', maybeHideWindow.bind(this, mainWindow, event, options.fastQuit));
} }
maybeHideWindow(mainWindow, event, options.fastQuit); maybeHideWindow(mainWindow, event, options.fastQuit, options.tray);
}); });
return mainWindow; return mainWindow;

View File

@ -0,0 +1,79 @@
import path from 'path';
const { app, Tray, Menu, ipcMain } = require('electron');
/**
*
* @param {{}} inpOptions AppArgs from nativefier.json
* @param {electron.BrowserWindow} mainWindow MainWindow created from main.js
* @returns {electron.Tray}
*/
function createTrayIcon(inpOptions, mainWindow) {
const options = Object.assign({}, inpOptions);
if (options.tray) {
const iconPath = path.join(__dirname, '../', '/icon.png');
const appIcon = new Tray(iconPath);
const onClick = () => {
if (mainWindow.isVisible()) {
mainWindow.hide();
} else {
mainWindow.show();
}
};
const contextMenu = Menu.buildFromTemplate([
{
label: options.name,
click: onClick,
},
{
label: 'Quit',
click: app.exit,
},
]);
appIcon.on('click', onClick);
mainWindow.on('show', () => {
appIcon.setHighlightMode('always');
});
mainWindow.on('hide', () => {
appIcon.setHighlightMode('never');
});
if (options.counter) {
mainWindow.on('page-title-updated', (e, title) => {
const itemCountRegex = /[([{](\d*?)\+?[}\])]/;
const match = itemCountRegex.exec(title);
if (match) {
appIcon.setToolTip(`(${match[1]}) ${options.name}`);
} else {
appIcon.setToolTip(options.name);
}
});
} else {
ipcMain.on('notification', () => {
if (mainWindow.isFocused()) {
return;
}
appIcon.setToolTip(`${options.name}`);
});
mainWindow.on('focus', () => {
appIcon.setToolTip(options.name);
});
}
appIcon.setToolTip(options.name);
appIcon.setContextMenu(contextMenu);
return appIcon;
}
return null;
}
export default createTrayIcon;

View File

@ -6,6 +6,7 @@ import electronDownload from 'electron-dl';
import createLoginWindow from './components/login/loginWindow'; import createLoginWindow from './components/login/loginWindow';
import createMainWindow from './components/mainWindow/mainWindow'; import createMainWindow from './components/mainWindow/mainWindow';
import createTrayIcon from './components/trayIcon/trayIcon';
import helpers from './helpers/helpers'; import helpers from './helpers/helpers';
import inferFlash from './helpers/inferFlash'; import inferFlash from './helpers/inferFlash';
@ -103,6 +104,7 @@ if (appArgs.crashReporter) {
app.on('ready', () => { app.on('ready', () => {
mainWindow = createMainWindow(appArgs, app.quit, setDockBadge); mainWindow = createMainWindow(appArgs, app.quit, setDockBadge);
createTrayIcon(appArgs, mainWindow);
}); });
app.on('login', (event, webContents, request, authInfo, callback) => { app.on('login', (event, webContents, request, authInfo, callback) => {

View File

@ -40,6 +40,7 @@
- [[zoom]](#zoom) - [[zoom]](#zoom)
- [[crash-reporter]](#crash-reporter) - [[crash-reporter]](#crash-reporter)
- [[single-instance]](#single-instance) - [[single-instance]](#single-instance)
- [[tray]](#tray)
- [[basic-auth-username]](#basic-auth-username) - [[basic-auth-username]](#basic-auth-username)
- [[basic-auth-password]](#basic-auth-username) - [[basic-auth-password]](#basic-auth-username)
- [Programmatic API](#programmatic-api) - [Programmatic API](#programmatic-api)
@ -410,6 +411,14 @@ Sets a default zoom factor to be used when the app is opened, defaults to `1.0`.
Prevents application from being run multiple times. If such an attempt occurs the already running instance is brought to front. Prevents application from being run multiple times. If such an attempt occurs the already running instance is brought to front.
#### [tray]
```
--tray
```
Application will stay as an icon in the system tray. Prevents application from being closed from clicking the window close button.
#### [basic-auth-username] #### [basic-auth-username]
``` ```
@ -418,6 +427,7 @@ Prevents application from being run multiple times. If such an attempt occurs th
Set basic http(s) auth via the command line to have the app automatically log you in to a protected site. Both fields are required if one is set. Set basic http(s) auth via the command line to have the app automatically log you in to a protected site. Both fields are required if one is set.
#### [processEnvs] #### [processEnvs]
``` ```

View File

@ -46,6 +46,7 @@ function selectAppArgs(options) {
win32metadata: options.win32metadata, win32metadata: options.win32metadata,
versionString: options.versionString, versionString: options.versionString,
processEnvs: options.processEnvs, processEnvs: options.processEnvs,
tray: options.tray,
basicAuthUsername: options.basicAuthUsername, basicAuthUsername: options.basicAuthUsername,
basicAuthPassword: options.basicAuthPassword, basicAuthPassword: options.basicAuthPassword,
}; };

View File

@ -82,6 +82,7 @@ if (require.main === module) {
.option('--crash-reporter <value>', 'remote server URL to send crash reports') .option('--crash-reporter <value>', 'remote server URL to send crash reports')
.option('--single-instance', 'allow only a single instance of the application') .option('--single-instance', 'allow only a single instance of the application')
.option('--processEnvs <json-string>', 'a JSON string of key/value pairs to be set as environment variables before any browser windows are opened.', getProcessEnvs) .option('--processEnvs <json-string>', 'a JSON string of key/value pairs to be set as environment variables before any browser windows are opened.', getProcessEnvs)
.option('--tray', 'allow app to stay in system tray')
.option('--basic-auth-username <value>', 'basic http(s) auth username') .option('--basic-auth-username <value>', 'basic http(s) auth username')
.option('--basic-auth-password <value>', 'basic http(s) auth password') .option('--basic-auth-password <value>', 'basic http(s) auth password')
.parse(process.argv); .parse(process.argv);

View File

@ -66,6 +66,7 @@ export default function (inpOptions) {
FileDescription: inpOptions.name, FileDescription: inpOptions.name,
}, },
processEnvs: inpOptions.processEnvs, processEnvs: inpOptions.processEnvs,
tray: inpOptions.tray || false,
basicAuthUsername: inpOptions.basicAuthUsername || null, basicAuthUsername: inpOptions.basicAuthUsername || null,
basicAuthPassword: inpOptions.basicAuthPassword || null, basicAuthPassword: inpOptions.basicAuthPassword || null,
}; };
@ -102,4 +103,3 @@ export default function (inpOptions) {
return asyncConfig(options); return asyncConfig(options);
} }