mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2025-01-24 07:38:36 +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;
|
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;
|
||||||
|
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 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) => {
|
||||||
|
10
docs/api.md
10
docs/api.md
@ -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]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user