mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2025-01-09 00:21:10 +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:
parent
4c581f9067
commit
885790bc22
@ -10,11 +10,14 @@ const { isOSX, linkIsInternal, getCssToInject, shouldInjectCss } = helpers;
|
||||
|
||||
const ZOOM_INTERVAL = 0.1;
|
||||
|
||||
function maybeHideWindow(window, event, fastQuit) {
|
||||
function maybeHideWindow(window, event, fastQuit, tray) {
|
||||
if (isOSX() && !fastQuit) {
|
||||
// this is called when exiting from clicking the cross button on the window
|
||||
event.preventDefault();
|
||||
window.hide();
|
||||
} else if (!fastQuit && tray) {
|
||||
event.preventDefault();
|
||||
window.hide();
|
||||
}
|
||||
// will close the window on other platforms
|
||||
}
|
||||
@ -211,7 +214,7 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
|
||||
mainWindow.setFullScreen(false);
|
||||
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;
|
||||
|
79
app/src/components/trayIcon/trayIcon.js
Normal file
79
app/src/components/trayIcon/trayIcon.js
Normal 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;
|
@ -6,6 +6,7 @@ import electronDownload from 'electron-dl';
|
||||
|
||||
import createLoginWindow from './components/login/loginWindow';
|
||||
import createMainWindow from './components/mainWindow/mainWindow';
|
||||
import createTrayIcon from './components/trayIcon/trayIcon';
|
||||
import helpers from './helpers/helpers';
|
||||
import inferFlash from './helpers/inferFlash';
|
||||
|
||||
@ -103,6 +104,7 @@ if (appArgs.crashReporter) {
|
||||
|
||||
app.on('ready', () => {
|
||||
mainWindow = createMainWindow(appArgs, app.quit, setDockBadge);
|
||||
createTrayIcon(appArgs, mainWindow);
|
||||
});
|
||||
|
||||
app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||
|
10
docs/api.md
10
docs/api.md
@ -40,6 +40,7 @@
|
||||
- [[zoom]](#zoom)
|
||||
- [[crash-reporter]](#crash-reporter)
|
||||
- [[single-instance]](#single-instance)
|
||||
- [[tray]](#tray)
|
||||
- [[basic-auth-username]](#basic-auth-username)
|
||||
- [[basic-auth-password]](#basic-auth-username)
|
||||
- [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.
|
||||
|
||||
#### [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]
|
||||
|
||||
```
|
||||
@ -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.
|
||||
|
||||
|
||||
#### [processEnvs]
|
||||
|
||||
```
|
||||
|
@ -46,6 +46,7 @@ function selectAppArgs(options) {
|
||||
win32metadata: options.win32metadata,
|
||||
versionString: options.versionString,
|
||||
processEnvs: options.processEnvs,
|
||||
tray: options.tray,
|
||||
basicAuthUsername: options.basicAuthUsername,
|
||||
basicAuthPassword: options.basicAuthPassword,
|
||||
};
|
||||
|
@ -82,6 +82,7 @@ if (require.main === module) {
|
||||
.option('--crash-reporter <value>', 'remote server URL to send crash reports')
|
||||
.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('--tray', 'allow app to stay in system tray')
|
||||
.option('--basic-auth-username <value>', 'basic http(s) auth username')
|
||||
.option('--basic-auth-password <value>', 'basic http(s) auth password')
|
||||
.parse(process.argv);
|
||||
|
@ -66,6 +66,7 @@ export default function (inpOptions) {
|
||||
FileDescription: inpOptions.name,
|
||||
},
|
||||
processEnvs: inpOptions.processEnvs,
|
||||
tray: inpOptions.tray || false,
|
||||
basicAuthUsername: inpOptions.basicAuthUsername || null,
|
||||
basicAuthPassword: inpOptions.basicAuthPassword || null,
|
||||
};
|
||||
@ -102,4 +103,3 @@ export default function (inpOptions) {
|
||||
|
||||
return asyncConfig(options);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user