Merge pull request #179 from magicmonty/HideWindowOnMinimize
Hide window to system tray on minimize/close in Windows/OSX
This commit is contained in:
@@ -11,9 +11,12 @@
|
|||||||
- Fixed the pixelated app icon on the top left of the window.
|
- Fixed the pixelated app icon on the top left of the window.
|
||||||
- Fixed the blurred tray icon.
|
- Fixed the blurred tray icon.
|
||||||
- Fixed that the redundant description appears in the pinned start menu on Windows 7.
|
- Fixed that the redundant description appears in the pinned start menu on Windows 7.
|
||||||
|
- The main window is now minimized to system tray on close
|
||||||
|
- Added Option to toggle minimize/restore on click on system tray icon
|
||||||
|
|
||||||
#### OS X
|
#### OS X
|
||||||
- Fixed that two icons appear on a notification.
|
- Fixed that two icons appear on a notification.
|
||||||
|
- Added Option to hide Window from dock on close
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
- Added shortcuts
|
- Added shortcuts
|
||||||
|
@@ -124,6 +124,10 @@ The Settings Page is available from the **File** menu under **Settings** (Click
|
|||||||
This option allows such images to be rendered, but please be careful for security.
|
This option allows such images to be rendered, but please be careful for security.
|
||||||
- **Start app on login** (Windows, Linux)
|
- **Start app on login** (Windows, Linux)
|
||||||
- This option starts the application when you login.
|
- This option starts the application when you login.
|
||||||
|
- **Leave app running in notification area when the window is closed** (OS X)
|
||||||
|
- This option hides the window from the dock, if the window is closed
|
||||||
|
- **Toggle window visibility when clicking on the tray icon** (Windows)
|
||||||
|
- If checked, then a click on the system tray icon leads to a toggling of the minimized/maximized state of the window
|
||||||
|
|
||||||
|
|
||||||
## Menu Bar
|
## Menu Bar
|
||||||
|
@@ -47,6 +47,13 @@ var SettingsPage = React.createClass({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
var currentWindow = remote.getCurrentWindow();
|
||||||
|
this.setState({
|
||||||
|
trayWasVisible: currentWindow.trayWasVisible
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleTeamsChange: function(teams) {
|
handleTeamsChange: function(teams) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -62,6 +69,8 @@ var SettingsPage = React.createClass({
|
|||||||
trayIconTheme: this.state.trayIconTheme,
|
trayIconTheme: this.state.trayIconTheme,
|
||||||
disablewebsecurity: this.state.disablewebsecurity,
|
disablewebsecurity: this.state.disablewebsecurity,
|
||||||
version: settings.version,
|
version: settings.version,
|
||||||
|
minimizeToTray: this.state.minimizeToTray,
|
||||||
|
toggleWindowOnTrayIconClick: this.state.toggleWindowOnTrayIconClick,
|
||||||
notifications: {
|
notifications: {
|
||||||
flashWindow: this.state.notifications.flashWindow
|
flashWindow: this.state.notifications.flashWindow
|
||||||
}
|
}
|
||||||
@@ -101,9 +110,16 @@ var SettingsPage = React.createClass({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleChangeShowTrayIcon: function() {
|
handleChangeShowTrayIcon: function() {
|
||||||
|
var shouldShowTrayIcon = this.refs.showTrayIcon.getChecked();
|
||||||
this.setState({
|
this.setState({
|
||||||
showTrayIcon: this.refs.showTrayIcon.getChecked()
|
showTrayIcon: shouldShowTrayIcon
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (process.platform === 'darwin' && !shouldShowTrayIcon) {
|
||||||
|
this.setState({
|
||||||
|
minimizeToTray: false
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleChangeTrayIconTheme: function() {
|
handleChangeTrayIconTheme: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -115,6 +131,19 @@ var SettingsPage = React.createClass({
|
|||||||
autostart: this.refs.autostart.getChecked()
|
autostart: this.refs.autostart.getChecked()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleChangeMinimizeToTray: function() {
|
||||||
|
var shouldMinimizeToTray = (process.platform !== 'darwin' || this.refs.showTrayIcon.getChecked())
|
||||||
|
&& this.refs.minimizeToTray.getChecked();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
minimizeToTray: shouldMinimizeToTray
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleChangeToggleWindowOnTrayIconClick: function() {
|
||||||
|
this.setState({
|
||||||
|
toggleWindowOnTrayIconClick: this.refs.toggleWindowOnTrayIconClick.getChecked()
|
||||||
|
});
|
||||||
|
},
|
||||||
toggleShowTeamForm: function() {
|
toggleShowTeamForm: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showAddTeamForm: !this.state.showAddTeamForm
|
showAddTeamForm: !this.state.showAddTeamForm
|
||||||
@@ -158,6 +187,17 @@ var SettingsPage = React.createClass({
|
|||||||
options.push(<Input key="inputAutoStart" id="inputAutoStart" ref="autostart" type="checkbox" label="Start app on login." checked={ this.state.autostart } onChange={ this.handleChangeAutoStart }
|
options.push(<Input key="inputAutoStart" id="inputAutoStart" ref="autostart" type="checkbox" label="Start app on login." checked={ this.state.autostart } onChange={ this.handleChangeAutoStart }
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
options.push(<Input key="inputMinimizeToTray" id="inputMinimizeToTray" ref="minimizeToTray" type="checkbox" label={ this.state.trayWasVisible || !this.state.showTrayIcon ? "Leave app running in notification area when the window is closed" : "Leave app running in notification area when the window is closed (available on next restart)" } disabled={ !this.state.showTrayIcon || !this.state.trayWasVisible } checked={ this.state.minimizeToTray }
|
||||||
|
onChange={ this.handleChangeMinimizeToTray } />);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
options.push(<Input key="inputToggleWindowOnTrayIconClick" id="inputToggleWindowOnTrayIconClick" ref="toggleWindowOnTrayIconClick" type="checkbox" label="Toggle window visibility when clicking on the tray icon."
|
||||||
|
checked={ this.state.toggleWindowOnTrayIconClick } onChange={ this.handleChangeToggleWindowOnTrayIconClick } />);
|
||||||
|
}
|
||||||
|
|
||||||
var options_row = (options.length > 0) ? (
|
var options_row = (options.length > 0) ? (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={ 12 }>
|
<Col md={ 12 }>
|
||||||
|
@@ -26,6 +26,7 @@ var loadDefault = function(version) {
|
|||||||
showTrayIcon: false,
|
showTrayIcon: false,
|
||||||
trayIconTheme: '',
|
trayIconTheme: '',
|
||||||
disablewebsecurity: true,
|
disablewebsecurity: true,
|
||||||
|
toggleWindowOnTrayIconClick: false,
|
||||||
version: 1,
|
version: 1,
|
||||||
notifications: {
|
notifications: {
|
||||||
flashWindow: 0 // 0 = flash never, 1 = only when idle (after 10 seconds), 2 = always
|
flashWindow: 0 // 0 = flash never, 1 = only when idle (after 10 seconds), 2 = always
|
||||||
|
54
src/main.js
54
src/main.js
@@ -156,6 +156,7 @@ app.on('browser-window-created', function(event, window) {
|
|||||||
// For OSX, show hidden mainWindow when clicking dock icon.
|
// For OSX, show hidden mainWindow when clicking dock icon.
|
||||||
app.on('activate', function(event) {
|
app.on('activate', function(event) {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
mainWindow.isHidden = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('before-quit', function() {
|
app.on('before-quit', function() {
|
||||||
@@ -227,12 +228,48 @@ app.on('ready', function() {
|
|||||||
|
|
||||||
trayIcon.setToolTip(app.getName());
|
trayIcon.setToolTip(app.getName());
|
||||||
trayIcon.on('click', function() {
|
trayIcon.on('click', function() {
|
||||||
mainWindow.focus();
|
if (process.platform === 'win32') {
|
||||||
|
if (mainWindow.isHidden || mainWindow.isMinimized()) {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.isHidden = false;
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
else if (config.toggleWindowOnTrayIconClick) {
|
||||||
|
mainWindow.minimize();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (process.platform === 'darwin') {
|
||||||
|
if (mainWindow.isHidden || mainWindow.isMinimized()) {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.isHidden = false;
|
||||||
|
mainWindow.focus();
|
||||||
|
app.dock.show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
trayIcon.on('right-click', () => {
|
trayIcon.on('right-click', () => {
|
||||||
trayIcon.popUpContextMenu();
|
trayIcon.popUpContextMenu();
|
||||||
});
|
});
|
||||||
trayIcon.on('balloon-click', function() {
|
trayIcon.on('balloon-click', function() {
|
||||||
|
if (process.platform === 'win32' || process.platform === 'darwin') {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.isHidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
app.dock.show();
|
||||||
|
}
|
||||||
|
|
||||||
mainWindow.focus();
|
mainWindow.focus();
|
||||||
});
|
});
|
||||||
ipcMain.on('notified', function(event, arg) {
|
ipcMain.on('notified', function(event, arg) {
|
||||||
@@ -321,6 +358,14 @@ app.on('ready', function() {
|
|||||||
if (shouldShowTrayIcon()) {
|
if (shouldShowTrayIcon()) {
|
||||||
const tray_menu = require('./main/menus/tray').createDefault(mainWindow);
|
const tray_menu = require('./main/menus/tray').createDefault(mainWindow);
|
||||||
trayIcon.setContextMenu(tray_menu);
|
trayIcon.setContextMenu(tray_menu);
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
// store the information, if the tray was initialized, for checking in the settings, if the application
|
||||||
|
// was restarted after setting "Show icon on menu bar"
|
||||||
|
if (trayIcon)
|
||||||
|
mainWindow.trayWasVisible = true;
|
||||||
|
else
|
||||||
|
mainWindow.trayWasVisible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the DevTools.
|
// Open the DevTools.
|
||||||
@@ -346,11 +391,18 @@ app.on('ready', function() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
|
mainWindow.hide();
|
||||||
|
mainWindow.isHidden = true;
|
||||||
|
break;
|
||||||
case 'linux':
|
case 'linux':
|
||||||
mainWindow.minimize();
|
mainWindow.minimize();
|
||||||
break;
|
break;
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
mainWindow.hide();
|
mainWindow.hide();
|
||||||
|
if (config.minimizeToTray) {
|
||||||
|
app.dock.hide();
|
||||||
|
mainWindow.isHidden = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,12 @@ function createDefault(mainWindow) {
|
|||||||
label: `Open ${app.getName()}`,
|
label: `Open ${app.getName()}`,
|
||||||
click: () => {
|
click: () => {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
mainWindow.isHidden = false;
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
app.dock.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
|
@@ -151,6 +151,26 @@ describe('browser/settings.html', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Minimize to tray', function() {
|
||||||
|
it('should appear on darwin', function() {
|
||||||
|
const expected = (process.platform === 'darwin');
|
||||||
|
env.addClientCommands(this.app.client);
|
||||||
|
return this.app.client
|
||||||
|
.loadSettingsPage()
|
||||||
|
.isExisting('#inputMinimizeToTray').should.eventually.equal(expected)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Toggle window visibility when clicking on the tray icon', function() {
|
||||||
|
it('should appear on win32', function() {
|
||||||
|
const expected = (process.platform === 'win32');
|
||||||
|
env.addClientCommands(this.app.client);
|
||||||
|
return this.app.client
|
||||||
|
.loadSettingsPage()
|
||||||
|
.isExisting('#inputToggleWindowOnTrayIconClick').should.eventually.equal(expected)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Notifications', function() {
|
describe('Notifications', function() {
|
||||||
it('should appear on win32', function() {
|
it('should appear on win32', function() {
|
||||||
const expected = (process.platform === 'win32');
|
const expected = (process.platform === 'win32');
|
||||||
|
Reference in New Issue
Block a user