From cae25cab3ec3c5e5d9aa61202ed613cb5e8fbc40 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 19:38:41 +0900 Subject: [PATCH 1/3] Implement SetIgnoreMouseEvents for Windows --- atom/browser/native_window.cc | 3 --- atom/browser/native_window.h | 2 +- atom/browser/native_window_views.cc | 11 +++++++++++ atom/browser/native_window_views.h | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c22159fc25db..46c3250a94a6 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -281,9 +281,6 @@ bool NativeWindow::IsDocumentEdited() { return false; } -void NativeWindow::SetIgnoreMouseEvents(bool ignore) { -} - void NativeWindow::SetMenu(ui::MenuModel* menu) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0846fbde4a9c..a12663a1aa5a 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -154,7 +154,7 @@ class NativeWindow : public base::SupportsUserData, virtual std::string GetRepresentedFilename(); virtual void SetDocumentEdited(bool edited); virtual bool IsDocumentEdited(); - virtual void SetIgnoreMouseEvents(bool ignore); + virtual void SetIgnoreMouseEvents(bool ignore) = 0; virtual void SetMenu(ui::MenuModel* menu); virtual bool HasModalDialog(); virtual gfx::NativeWindow GetNativeWindow() = 0; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 6a0919635f3e..6b16072f6adb 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -672,6 +672,17 @@ bool NativeWindowViews::HasShadow() { return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE; } +void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { +#if defined(OS_WIN) + LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + if (ignore) + ex_style |= (WS_EX_TRANSPARENT | WS_EX_LAYERED); + else + ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); + ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); +#endif +} + void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { if (menu_model == nullptr) { // Remove accelerators diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 909c5b6fd4ba..6a26c14e0084 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -91,6 +91,7 @@ class NativeWindowViews : public NativeWindow, void SetBackgroundColor(const std::string& color_name) override; void SetHasShadow(bool has_shadow) override; bool HasShadow() override; + void SetIgnoreMouseEvents(bool ignore) override; void SetMenu(ui::MenuModel* menu_model) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, From f8b69c1fac54fd85e444f77320de91fb81b6e280 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 20:23:29 +0900 Subject: [PATCH 2/3] Implement SetIgnoreMouseEvents for Linux --- atom/browser/native_window_views.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 6b16072f6adb..29c4187a124c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -680,6 +680,15 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { else ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); +#elif defined(USE_X11) + if (ignore) { + XRectangle r = {0, 0, 1, 1}; + XShapeCombineRectangles(gfx::GetXDisplay(), GetAcceleratedWidget(), + ShapeInput, 0, 0, &r, 1, ShapeSet, YXBanded); + } else { + XShapeCombineMask(gfx::GetXDisplay(), GetAcceleratedWidget(), + ShapeInput, 0, 0, None, ShapeSet); + } #endif } From 6192eef1b6b9a5adbdfaa4a206adbdc8eb2f2c09 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 20:32:52 +0900 Subject: [PATCH 3/3] Update docs on win.setIgnoreMouseEvents --- docs/api/browser-window.md | 8 ++++++-- docs/api/frameless-window.md | 20 ++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index fc558515fdc4..e6ff43ca234d 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -928,10 +928,14 @@ Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. -### `win.setIgnoreMouseEvents(ignore)` _OS X_ +### `win.setIgnoreMouseEvents(ignore)` * `ignore` Boolean -Ignore all moused events that happened in the window. +Makes the window ignore all mouse events. + +All mouse events happened in this window will be passed to the window bellow +this window, but if this window has focus, it will still receive keyboard +events. [blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=576 diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index f3017037210d..66c42588b2b5 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -14,8 +14,8 @@ To create a frameless window, you need to set `frame` to `false` in ```javascript -const {BrowserWindow} = require('electron'); -let win = new BrowserWindow({width: 800, height: 600, frame: false}); +const {BrowserWindow} = require('electron') +let win = new BrowserWindow({width: 800, height: 600, frame: false}) ``` ### Alternatives on OS X @@ -28,7 +28,7 @@ the window controls ("traffic lights") for standard window actions. You can do so by specifying the new `titleBarStyle` option: ```javascript -let win = new BrowserWindow({titleBarStyle: 'hidden'}); +let win = new BrowserWindow({titleBarStyle: 'hidden'}) ``` ## Transparent window @@ -37,7 +37,7 @@ By setting the `transparent` option to `true`, you can also make the frameless window transparent: ```javascript -let win = new BrowserWindow({transparent: true, frame: false}); +let win = new BrowserWindow({transparent: true, frame: false}) ``` ### Limitations @@ -59,6 +59,16 @@ let win = new BrowserWindow({transparent: true, frame: false}); Linux. * On Mac the native window shadow will not be shown on a transparent window. +## Click-through window + +To create a click-through window, i.e. making the window ignore all mouse +events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events] +API: + +```javascript +win.setIgnoreMouseEvents(true) +``` + ## Draggable region By default, the frameless window is non-draggable. Apps need to specify @@ -108,3 +118,5 @@ On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas. + +[ignore-mouse-events]: browser-window.md#winsetignoremouseeventsignore