Commit 933ec987 authored by Brian Liu Xu's avatar Brian Liu Xu Committed by Commit Bot

Ignore rogue window management mouse move events

Do not process window management mouse messages (WMMMs) when the pen is active over the client area.

Windows sends window management mouse messages at the mouse position when windows open or close (e.g. Aura tooltips and Status Bubbles), including WM_MOUSEMOVE, WM_NCMOUSEMOVE, and WM_SETCURSOR. This is a longstanding Windows behavior designed to ensure that mouse cursor visuals and hover states update when the foreground window changes. However, this behavior does not extend to pen input, so WMMMs always come with the mouse coordinates instead of with the pen coordinates even if there is an active pen.

In Chromium, WM_POINTER processing in the window non-client area are "promoted" to mouse messages in order to allow for interaction with the native window frame (e.g. resize handles, title bar, and window caption buttons). However, WM_POINTER messages in the window client area are handled as Chromium events without any mouse promotion; in this latter case, mouse position and pen position are not guaranteed to be in sync.

Since Aura tooltips and Status Bubbles appear as custom windows on pen hover, opening/closing them causes Windows to send WMMMs. Consequently, users might see visual flickering as hover states flip back and forth between pen and mouse positions. In order to ensure that these WMMMs do not interfere with hover states, we must ignore such messages until the pen is no longer active.

This change affects only Windows 8 and newer clients, which use the WM_POINTER API.

Bug: 1147222
Change-Id: I44335348f933f48edcfe665b396f133388169957
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2525220
Commit-Queue: Brian Liu Xu <brx@microsoft.com>
Auto-Submit: Brian Liu Xu <brx@microsoft.com>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825665}
parent 2fa56352
......@@ -395,6 +395,7 @@ base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap>::
// HWNDMessageHandler, public:
LONG HWNDMessageHandler::last_touch_or_pen_message_time_ = 0;
bool HWNDMessageHandler::is_pen_active_in_client_area_ = false;
HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate,
const std::string& debugging_id)
......@@ -2485,6 +2486,11 @@ LRESULT HWNDMessageHandler::OnScrollMessage(UINT message,
LRESULT HWNDMessageHandler::OnSetCursor(UINT message,
WPARAM w_param,
LPARAM l_param) {
// Ignore system generated cursors likely caused by window management mouse
// moves while the pen is active over the window client area.
if (is_pen_active_in_client_area_)
return 1;
// Reimplement the necessary default behavior here. Calling DefWindowProc can
// trigger weird non-client painting for non-glass windows with custom frames.
// Using a ScopedRedrawLock to prevent caption rendering artifacts may allow
......@@ -2976,6 +2982,17 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
WPARAM w_param,
LPARAM l_param,
bool track_mouse) {
// Ignore system generated mouse messages while the pen is active over the
// window client area.
if (is_pen_active_in_client_area_) {
INPUT_MESSAGE_SOURCE input_message_source;
if (GetCurrentInputMessageSource(&input_message_source) &&
input_message_source.deviceType == IMDT_UNAVAILABLE) {
return 0;
}
is_pen_active_in_client_area_ = false;
}
// We handle touch events in Aura. Windows generates synthesized mouse
// messages whenever there's a touch, but it doesn't give us the actual touch
// messages if it thinks the touch point is in non-client space.
......@@ -3278,6 +3295,7 @@ LRESULT HWNDMessageHandler::HandlePointerEventTypePenClient(UINT message,
NOTREACHED();
last_touch_or_pen_message_time_ = ::GetMessageTime();
is_pen_active_in_client_area_ = true;
}
// Always mark as handled as we don't want to generate WM_MOUSE compatiblity
......
......@@ -715,6 +715,14 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
// IsMouseEventFromTouch function.
static LONG last_touch_or_pen_message_time_;
// When true, this flag makes us discard window management mouse messages.
// Windows sends window management mouse messages at the mouse location when
// window states change (e.g. tooltips or status bubbles opening/closing).
// Those system generated messages should be ignored while the pen is active
// over the client area, where it is not in sync with the mouse position.
// Reset to false when we get user mouse input again.
static bool is_pen_active_in_client_area_;
// Time the last WM_MOUSEHWHEEL message is received. Please refer to the
// HandleMouseEventInternal function as to why this is needed.
LONG last_mouse_hwheel_time_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment