fix: non-client mouse events on WCO-enabled windows (#32871)
This commit is contained in:
parent
076bc58b2a
commit
e41c3e960d
4 changed files with 62 additions and 18 deletions
|
@ -113,3 +113,4 @@ fix_crash_when_saving_edited_pdf_files.patch
|
||||||
port_autofill_colors_to_the_color_pipeline.patch
|
port_autofill_colors_to_the_color_pipeline.patch
|
||||||
build_disable_partition_alloc_on_mac.patch
|
build_disable_partition_alloc_on_mac.patch
|
||||||
build_disable_thin_lto_on_mac.patch
|
build_disable_thin_lto_on_mac.patch
|
||||||
|
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: clavin <cwatford@slack-corp.com>
|
||||||
|
Date: Fri, 11 Feb 2022 15:05:42 -0700
|
||||||
|
Subject: fix: non-client mouse tracking and message bubbling on windows
|
||||||
|
|
||||||
|
It is not known why, but for some reason calling |DefWindowProc| on the parent
|
||||||
|
window handle causes a WM_NCMOUSELEAVE (non-client mouse exit) message to be
|
||||||
|
sent to the parent window, even though |TrackMouseEvent| is never called on it.
|
||||||
|
|
||||||
|
This patch also adds some boilerplate for properly tracking non-client mouse
|
||||||
|
messages in the legacy window handle layer.
|
||||||
|
|
||||||
|
These conditions are regularly hit with WCO-enabled windows on Windows.
|
||||||
|
|
||||||
|
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||||
|
index 4a894ef70eeb1d8489049aef552c9bae4f24ae62..f5049d730a850f2947023f976b25fb772e42107a 100644
|
||||||
|
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||||
|
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
|
||||||
|
@@ -288,12 +288,12 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
|
||||||
|
WPARAM w_param,
|
||||||
|
LPARAM l_param,
|
||||||
|
BOOL& handled) {
|
||||||
|
- if (message == WM_MOUSEMOVE) {
|
||||||
|
+ if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE) {
|
||||||
|
if (!mouse_tracking_enabled_) {
|
||||||
|
mouse_tracking_enabled_ = true;
|
||||||
|
TRACKMOUSEEVENT tme;
|
||||||
|
tme.cbSize = sizeof(tme);
|
||||||
|
- tme.dwFlags = TME_LEAVE;
|
||||||
|
+ tme.dwFlags = message == WM_NCMOUSEMOVE ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE;
|
||||||
|
tme.hwndTrack = hwnd();
|
||||||
|
tme.dwHoverTime = 0;
|
||||||
|
TrackMouseEvent(&tme);
|
||||||
|
@@ -319,12 +319,11 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
|
||||||
|
message, w_param, l_param, &msg_handled);
|
||||||
|
handled = msg_handled;
|
||||||
|
// If the parent did not handle non client mouse messages, we call
|
||||||
|
- // DefWindowProc on the message with the parent window handle. This
|
||||||
|
- // ensures that WM_SYSCOMMAND is generated for the parent and we are
|
||||||
|
- // out of the picture.
|
||||||
|
+ // DefWindowProc on the message. This ensures that WM_SYSCOMMAND is
|
||||||
|
+ // generated.
|
||||||
|
if (!handled &&
|
||||||
|
(message >= WM_NCMOUSEMOVE && message <= WM_NCXBUTTONDBLCLK)) {
|
||||||
|
- ret = ::DefWindowProc(GetParent(), message, w_param, l_param);
|
||||||
|
+ ret = ::DefWindowProc(hwnd(), message, w_param, l_param);
|
||||||
|
handled = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||||
|
index 79dffd981f4d461f30bd3796cfba1457eda3a89d..ae378ce95f90989fd0e74c38b57f5f7dc0a1ee29 100644
|
||||||
|
--- a/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||||
|
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
|
||||||
|
@@ -105,6 +105,7 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND
|
||||||
|
MESSAGE_HANDLER_EX(WM_NCHITTEST, OnNCHitTest)
|
||||||
|
MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK,
|
||||||
|
OnMouseRange)
|
||||||
|
+ MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseLeave)
|
||||||
|
MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize)
|
||||||
|
MESSAGE_HANDLER_EX(WM_SIZE, OnSize)
|
||||||
|
MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy)
|
|
@ -99,21 +99,4 @@ bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElectronDesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) {
|
|
||||||
// Call the default implementation of this method to get the event to its
|
|
||||||
// proper handler.
|
|
||||||
bool handled = views::DesktopWindowTreeHostWin::HandleMouseEvent(event);
|
|
||||||
|
|
||||||
// On WCO-enabled windows, we need to mark non-client mouse moved events as
|
|
||||||
// handled so they don't incorrectly propogate back to the OS.
|
|
||||||
if (native_window_view_->IsWindowControlsOverlayEnabled() &&
|
|
||||||
event->type() == ui::ET_MOUSE_MOVED &&
|
|
||||||
(event->flags() & ui::EF_IS_NON_CLIENT) != 0) {
|
|
||||||
event->SetHandled();
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -36,7 +36,6 @@ class ElectronDesktopWindowTreeHostWin
|
||||||
bool GetDwmFrameInsetsInPixels(gfx::Insets* insets) const override;
|
bool GetDwmFrameInsetsInPixels(gfx::Insets* insets) const override;
|
||||||
bool GetClientAreaInsets(gfx::Insets* insets,
|
bool GetClientAreaInsets(gfx::Insets* insets,
|
||||||
HMONITOR monitor) const override;
|
HMONITOR monitor) const override;
|
||||||
bool HandleMouseEvent(ui::MouseEvent* event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NativeWindowViews* native_window_view_; // weak ref
|
NativeWindowViews* native_window_view_; // weak ref
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue