Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: non-client mouse events on WCO-enabled windows #32871

Merged
merged 1 commit into from Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions patches/chromium/.patches
Expand Up @@ -113,3 +113,4 @@ fix_crash_when_saving_edited_pdf_files.patch
port_autofill_colors_to_the_color_pipeline.patch
build_disable_partition_alloc_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)
17 changes: 0 additions & 17 deletions shell/browser/ui/win/electron_desktop_window_tree_host_win.cc
Expand Up @@ -99,21 +99,4 @@ bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets(
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
Expand Up @@ -36,7 +36,6 @@ class ElectronDesktopWindowTreeHostWin
bool GetDwmFrameInsetsInPixels(gfx::Insets* insets) const override;
bool GetClientAreaInsets(gfx::Insets* insets,
HMONITOR monitor) const override;
bool HandleMouseEvent(ui::MouseEvent* event) override;

private:
NativeWindowViews* native_window_view_; // weak ref
Expand Down