diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ea1d95b79ca..2975980cabe 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -191,6 +191,14 @@ void Window::OnWindowFocus() { Emit("focus"); } +void Window::OnWindowShow() { + Emit("show"); +} + +void Window::OnWindowHide() { + Emit("hide"); +} + void Window::OnWindowMaximize() { Emit("maximize"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 641124f4dfd..d814a48c983 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -58,6 +58,8 @@ class Window : public mate::TrackableObject, void OnWindowClosed() override; void OnWindowBlur() override; void OnWindowFocus() override; + void OnWindowShow() override; + void OnWindowHide() override; void OnWindowMaximize() override; void OnWindowUnmaximize() override; void OnWindowMinimize() override; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 09fae6c6bcf..a215b9eb4c1 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -210,6 +210,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowClosed(); void NotifyWindowBlur(); void NotifyWindowFocus(); + void NotifyWindowShow(); + void NotifyWindowHide(); void NotifyWindowMaximize(); void NotifyWindowUnmaximize(); void NotifyWindowMinimize(); diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 4af181085a0..e9dbff4292e 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -42,6 +42,12 @@ class NativeWindowObserver { // Called when window gains focus. virtual void OnWindowFocus() {} + // Called when window is shown. + virtual void OnWindowShow() {} + + // Called when window is hidden. + virtual void OnWindowHide() {} + // Called when window state changed. virtual void OnWindowMaximize() {} virtual void OnWindowUnmaximize() {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 93eb7b88d89..15f2046364b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -302,6 +302,8 @@ bool NativeWindowViews::IsFocused() { void NativeWindowViews::Show() { window_->native_widget_private()->ShowWithWindowState(GetRestoredState()); + NotifyWindowShow(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowMapped(); @@ -311,6 +313,8 @@ void NativeWindowViews::Show() { void NativeWindowViews::ShowInactive() { window_->ShowInactive(); + NotifyWindowShow(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowMapped(); @@ -320,6 +324,8 @@ void NativeWindowViews::ShowInactive() { void NativeWindowViews::Hide() { window_->Hide(); + NotifyWindowHide(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowUnmapped(); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6e1bc992539..0595fbc7056 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -245,6 +245,14 @@ Emitted when the window loses focus. Emitted when the window gains focus. +### Event: 'show' + +Emitted when the window is shown. + +### Event: 'hide' + +Emitted when the window is hidden. + ### Event: 'maximize' Emitted when window is maximized. diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index b3e27c58056..139659c2ea2 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -20,7 +20,7 @@ BrowserWindow.prototype._init = function() { } // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', function(event, url, frameName) { + this.webContents.on('-new-window', (event, url, frameName) => { var options; options = { show: true, @@ -32,27 +32,21 @@ BrowserWindow.prototype._init = function() { // window.resizeTo(...) // window.moveTo(...) - this.webContents.on('move', (function(_this) { - return function(event, size) { - return _this.setBounds(size); - }; - })(this)); + this.webContents.on('move', (event, title) => { + return this.setBounds(size); + }); // Hide the auto-hide menu when webContents is focused. - this.webContents.on('activate', (function(_this) { - return function() { - if (process.platform !== 'darwin' && _this.isMenuBarAutoHide() && _this.isMenuBarVisible()) { - return _this.setMenuBarVisibility(false); - } - }; - })(this)); + this.webContents.on('activate', () => { + if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) { + return this.setMenuBarVisibility(false); + } + }); // Forward the crashed event. - this.webContents.on('crashed', (function(_this) { - return function() { - return _this.emit('crashed'); - }; - })(this)); + this.webContents.on('crashed', () => { + return this.emit('crashed'); + }); // Change window title to page title. this.webContents.on('page-title-updated', (event, title) => { @@ -77,48 +71,40 @@ BrowserWindow.prototype._init = function() { }); // Redirect focus/blur event to app instance too. - this.on('blur', (function(_this) { - return function(event) { - return app.emit('browser-window-blur', event, _this); - }; - })(this)); - this.on('focus', (function(_this) { - return function(event) { - return app.emit('browser-window-focus', event, _this); - }; - })(this)); + this.on('blur', (event) => { + return app.emit('browser-window-blur', event, this); + }); + this.on('focus', (event) => { + return app.emit('browser-window-focus', event, this); + }); // Evented visibilityState changes - this.on('minimize', (function(_this) { - return function() { - return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false); - }; - })(this)); - this.on('restore', (function(_this) { - return function() { - return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true); - }; - })(this)); + this.on('show', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true, this.isMinimized()); + }); + this.on('hide', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false, this.isMinimized()); + }); + this.on('minimize', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), true); + }); + this.on('restore', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), false); + }); // Notify the creation of the window. app.emit('browser-window-created', {}, this); // Be compatible with old APIs. - this.webContents.on('devtools-focused', (function(_this) { - return function() { - return _this.emit('devtools-focused'); - }; - })(this)); - this.webContents.on('devtools-opened', (function(_this) { - return function() { - return _this.emit('devtools-opened'); - }; - })(this)); - this.webContents.on('devtools-closed', (function(_this) { - return function() { - return _this.emit('devtools-closed'); - }; - })(this)); + this.webContents.on('devtools-focused', () => { + return this.emit('devtools-focused'); + }); + this.webContents.on('devtools-opened', () => { + return this.emit('devtools-opened'); + }); + this.webContents.on('devtools-closed', () => { + return this.emit('devtools-closed'); + }); return Object.defineProperty(this, 'devToolsWebContents', { enumerable: true, configurable: false, diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 6a025af4ed1..2b0e48b3dd3 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -4,10 +4,13 @@ const remote = require('electron').remote; var slice = [].slice; // Cache browser window visibility -var _isVisible = (function() { +var _isVisible = true; +var _isMinimized = false; +(function() { var currentWindow; currentWindow = remote.getCurrentWindow(); - return currentWindow.isMinimized() || !currentWindow.isVisible(); + _isVisible = currentWindow.isVisible(); + _isMinimized = currentWindow.isMinimized(); })(); // Helper function to resolve relative url. @@ -177,10 +180,15 @@ if (process.openerId != null) { window.opener = BrowserWindowProxy.getOrCreate(process.openerId); } -ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible) { - _isVisible = isVisible; +ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible, isMinimized) { + var hasChanged = _isVisible != isVisible || _isMinimized != isMinimized; + + if (hasChanged) { + _isVisible = isVisible; + _isMinimized = isMinimized; - document.dispatchEvent(new Event('visibilitychange')); + document.dispatchEvent(new Event('visibilitychange')); + } }); ipcRenderer.on('ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', function(event, sourceId, message, sourceOrigin) { @@ -227,12 +235,14 @@ Object.defineProperty(window.history, 'length', { // Make document.hidden and document.visibilityState return the correct value. Object.defineProperty(document, 'hidden', { - get: !_isVisible + get: function () { + return _isMinimized || !_isVisible; + } }); Object.defineProperty(document, 'visibilityState', { get: function() { - if (_isVisible) { + if (_isVisible && !_isMinimized) { return "visible"; } else { return "hidden";