From 5aecd1050239f6e8ec1ec57ca7cd768d4527e58a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 13 Jun 2016 16:40:02 +0900 Subject: [PATCH 1/4] docs: Document the behavior of win.setIgnoreFocus on OS X --- docs/api/browser-window.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index d3a033760c78..95b76019e3f3 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -957,8 +957,13 @@ events. * `ignore` Boolean -Makes the window ignore focus. +Prevents the window from getting focus. -On OS X this prevents the window from becoming key and main window. +On OS X this API has to be called before the window shows: + +```javascript +let win = new BrowserWindow({show: false}) +win.setIgnoreFocus(true) +``` [blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in From 8eca728e0a7cac7348836f7143bd696e6f3783b8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 13 Jun 2016 17:10:28 +0900 Subject: [PATCH 2/4] Add focusable option --- atom/browser/api/atom_api_window.cc | 6 +++--- atom/browser/api/atom_api_window.h | 2 +- atom/browser/native_window.cc | 3 +++ atom/browser/native_window.h | 2 +- atom/browser/native_window_mac.h | 1 - atom/browser/native_window_mac.mm | 8 ++++---- atom/browser/native_window_views.cc | 4 ++-- atom/browser/native_window_views.h | 2 +- atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + docs/api/browser-window.md | 15 +++++---------- 11 files changed, 24 insertions(+), 23 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 0ce3e0e77a2a..5a93f27d2de0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -529,8 +529,8 @@ void Window::SetIgnoreMouseEvents(bool ignore) { return window_->SetIgnoreMouseEvents(ignore); } -void Window::SetIgnoreFocus(bool ignore) { - return window_->SetIgnoreFocus(ignore); +void Window::SetFocusable(bool focusable) { + return window_->SetFocusable(focusable); } void Window::CapturePage(mate::Arguments* args) { @@ -736,7 +736,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("setDocumentEdited", &Window::SetDocumentEdited) .SetMethod("isDocumentEdited", &Window::IsDocumentEdited) .SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents) - .SetMethod("setIgnoreFocus", &Window::SetIgnoreFocus) + .SetMethod("setFocusable", &Window::SetFocusable) .SetMethod("focusOnWebView", &Window::FocusOnWebView) .SetMethod("blurWebView", &Window::BlurWebView) .SetMethod("isWebViewFocused", &Window::IsWebViewFocused) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index e84e850a1966..286b47262159 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -146,7 +146,7 @@ class Window : public mate::TrackableObject, void SetDocumentEdited(bool edited); bool IsDocumentEdited(); void SetIgnoreMouseEvents(bool ignore); - void SetIgnoreFocus(bool ignore); + void SetFocusable(bool focusable); void CapturePage(mate::Arguments* args); void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index e0224836dace..e3c2ff99c55c 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -282,6 +282,9 @@ bool NativeWindow::IsDocumentEdited() { return false; } +void NativeWindow::SetFocusable(bool focusable) { +} + void NativeWindow::SetMenu(ui::MenuModel* menu) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index a321bc41543d..ffcdcc4da277 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -155,7 +155,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetDocumentEdited(bool edited); virtual bool IsDocumentEdited(); virtual void SetIgnoreMouseEvents(bool ignore) = 0; - virtual void SetIgnoreFocus(bool ignore) = 0; + virtual void SetFocusable(bool focusable); virtual void SetMenu(ui::MenuModel* menu); virtual bool HasModalDialog(); virtual gfx::NativeWindow GetNativeWindow() = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 2cbdbc851dab..27857239e8c8 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -77,7 +77,6 @@ class NativeWindowMac : public NativeWindow { void SetDocumentEdited(bool edited) override; bool IsDocumentEdited() override; void SetIgnoreMouseEvents(bool ignore) override; - void SetIgnoreFocus(bool ignore) override; bool HasModalDialog() override; gfx::NativeWindow GetNativeWindow() override; gfx::AcceleratedWidget GetAcceleratedWidget() override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index de02033b6ff8..9035d5e62d5a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -490,6 +490,10 @@ NativeWindowMac::NativeWindowMac( NSWindowCollectionBehaviorIgnoresCycle)]; } + bool focusable; + if (options.Get(options::kFocusable, &focusable) && !focusable) + [window_ setDisableKeyOrMainWindow:YES]; + // Remove non-transparent corners, see http://git.io/vfonD. if (!has_frame()) [window_ setOpaque:NO]; @@ -883,10 +887,6 @@ void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) { [window_ setIgnoresMouseEvents:ignore]; } -void NativeWindowMac::SetIgnoreFocus(bool ignore) { - [window_ setDisableKeyOrMainWindow:ignore]; -} - bool NativeWindowMac::HasModalDialog() { return [window_ attachedSheet] != nil; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 845e08a07de0..aa64156b143d 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -692,10 +692,10 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { #endif } -void NativeWindowViews::SetIgnoreFocus(bool ignore) { +void NativeWindowViews::SetFocusable(bool focusable) { #if defined(OS_WIN) LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); - if (ignore) + if (focusable) ex_style |= WS_EX_NOACTIVATE; else ex_style &= ~WS_EX_NOACTIVATE; diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 826b3fce7617..53774203742c 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -92,7 +92,7 @@ class NativeWindowViews : public NativeWindow, void SetHasShadow(bool has_shadow) override; bool HasShadow() override; void SetIgnoreMouseEvents(bool ignore) override; - void SetIgnoreFocus(bool ignore) override; + void SetFocusable(bool focusable) override; void SetMenu(ui::MenuModel* menu_model) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index d370f0ef859f..04e268c66e2e 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -75,6 +75,9 @@ const char kBackgroundColor[] = "backgroundColor"; // Whether the window should have a shadow. const char kHasShadow[] = "hasShadow"; +// Whether the window can be activated. +const char kFocusable[] = "focusable"; + // The WebPreferences. const char kWebPreferences[] = "webPreferences"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 5924c0549119..29fbc0e40f84 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -44,6 +44,7 @@ extern const char kDisableAutoHideCursor[]; extern const char kStandardWindow[]; extern const char kBackgroundColor[]; extern const char kHasShadow[]; +extern const char kFocusable[]; extern const char kWebPreferences[]; // WebPreferences. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 95b76019e3f3..1000d0c787be 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -54,6 +54,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. implemented on Linux. Default is `true`. * `closable` Boolean - Whether window is closable. This is not implemented on Linux. Default is `true`. + * `focusable` Boolean - Whether the window can be focused. Default is + `true`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When @@ -953,17 +955,10 @@ All mouse events happened in this window will be passed to the window below this window, but if this window has focus, it will still receive keyboard events. -### `win.setIgnoreFocus(ignore)` _OS X_ _Windows_ +### `win.setActivatable(activatable)` _Windows_ -* `ignore` Boolean +* `activatable` Boolean -Prevents the window from getting focus. - -On OS X this API has to be called before the window shows: - -```javascript -let win = new BrowserWindow({show: false}) -win.setIgnoreFocus(true) -``` +Changes whether the window can be activated. [blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in From 50f18370976410abb33d94bbb76946b482f050dd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 13 Jun 2016 17:24:45 +0900 Subject: [PATCH 3/4] On Windows focusable: false also means skipTaskbar: true --- atom/browser/native_window.cc | 2 +- atom/browser/native_window_views.cc | 10 ++++++++-- docs/api/browser-window.md | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index e3c2ff99c55c..8a00a88d5470 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -153,7 +153,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { SetFullScreen(true); } bool skip; - if (options.Get(options::kSkipTaskbar, &skip) && skip) { + if (options.Get(options::kSkipTaskbar, &skip)) { SetSkipTaskbar(skip); } bool kiosk; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index aa64156b143d..021ceba005e2 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -181,6 +181,10 @@ NativeWindowViews::NativeWindowViews( if (transparent() && !has_frame()) params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; + bool focusable; + if (options.Get(options::kFocusable, &focusable) && !focusable) + params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; + #if defined(OS_WIN) params.native_widget = new views::DesktopNativeWidgetAura(window_.get()); @@ -696,10 +700,12 @@ void NativeWindowViews::SetFocusable(bool focusable) { #if defined(OS_WIN) LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); if (focusable) - ex_style |= WS_EX_NOACTIVATE; - else ex_style &= ~WS_EX_NOACTIVATE; + else + ex_style |= WS_EX_NOACTIVATE; ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); + SetSkipTaskbar(!focusable); + Focus(false); #endif } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 1000d0c787be..6e81bb259a10 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -55,7 +55,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `closable` Boolean - Whether window is closable. This is not implemented on Linux. Default is `true`. * `focusable` Boolean - Whether the window can be focused. Default is - `true`. + `true`. On Windows setting `focusable: false` also implies setting + `skipTaskbar: true`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When @@ -955,10 +956,10 @@ All mouse events happened in this window will be passed to the window below this window, but if this window has focus, it will still receive keyboard events. -### `win.setActivatable(activatable)` _Windows_ +### `win.setFocusable(focusable)` _Windows_ -* `activatable` Boolean +* `focusable` Boolean -Changes whether the window can be activated. +Changes whether the window can be focused. [blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in From e284deb7e123867852ed74b5d0b3eeec5ad94e1c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 13 Jun 2016 17:53:08 +0900 Subject: [PATCH 4/4] docs: The side effect of focusable: false on Linux --- docs/api/browser-window.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6e81bb259a10..7f6c69673977 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -56,7 +56,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. on Linux. Default is `true`. * `focusable` Boolean - Whether the window can be focused. Default is `true`. On Windows setting `focusable: false` also implies setting - `skipTaskbar: true`. + `skipTaskbar: true`. On Linux setting `focusable: false` makes the window + stop interacting with wm, so the window will always stay on top in all + workspaces. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When