diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-04 18:47:17 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-04 18:47:17 +0000 |
commit | 143791f3767cb0c7007d2e517400c9ed2d9eb7c4 (patch) | |
tree | 6dfe610c7922774322ab0b1fd6dad9a488178f20 /ui/views | |
parent | bcc3d57371525d3a8acf37f053d3633db0521a33 (diff) | |
download | chromium_src-143791f3767cb0c7007d2e517400c9ed2d9eb7c4.zip chromium_src-143791f3767cb0c7007d2e517400c9ed2d9eb7c4.tar.gz chromium_src-143791f3767cb0c7007d2e517400c9ed2d9eb7c4.tar.bz2 |
Ensure that we tag mouse messages synthesized by Windows in response to touch events with the ui::EF_FROM_TOUCH flag.
There are mouse events which are synthesized by Windows for touch messages which don't have the magic message
extra information which identifies them as synthesized messages. As per msdn a possible way to detect these
messages is to compare the message times for these messages and the last touch message and whether the position
is different from the current cursor position. These messages are generated by Windows within 500ms of the last
touch message.
We incorporate this in a function HWNDMessageHandler::IsSynthesizedMouseMessage function which returns true
if the above is true.
The other changes are as below:-
1. We need to allow synthesized mouse exit events through even if mouse events are marked as disabled on the
cursor client. This ensures that hover state on buttons, etc is cleared. This is covered by an aura unittest.
WindowEventDispatcherTest.DispatchSyntheticMouseExitAfterMouseEventsDisabled
2. The CompoundEventFilter::UpdateCursor function should not attempt to update the cursor for mouse messages
flagged as coming from touch. This ensures that we don't make the cursor visible if we receive spurious mouse
messages from touch input. This is covered by a wm core unittest.
CompoundEventFilterTest.DontShowCursorOnMouseMovesFromTouch
BUG=326933
R=sky@chromium.org, tdanderson@chromium.org
Review URL: https://codereview.chromium.org/214383006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261807 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views')
-rw-r--r-- | ui/views/win/hwnd_message_handler.cc | 38 | ||||
-rw-r--r-- | ui/views/win/hwnd_message_handler.h | 15 |
2 files changed, 51 insertions, 2 deletions
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 92c8512..90140ed 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc @@ -256,6 +256,13 @@ void AddScrollStylesToWindow(HWND window) { const int kTouchDownContextResetTimeout = 500; +// Windows does not flag synthesized mouse messages from touch in all cases. +// This causes us grief as we don't want to process touch and mouse messages +// concurrently. Hack as per msdn is to check if the time difference between +// the touch message and the mouse move is within 500 ms and at the same +// location as the cursor. +const int kSynthesizedMouseTouchMessagesTimeDifference = 500; + } // namespace // A scoping class that prevents a window from being able to redraw in response @@ -325,6 +332,8 @@ class HWNDMessageHandler::ScopedRedrawLock { //////////////////////////////////////////////////////////////////////////////// // HWNDMessageHandler, public: +long HWNDMessageHandler::last_touch_message_time_ = 0; + HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) : delegate_(delegate), fullscreen_handler_(new FullscreenHandler), @@ -2116,6 +2125,8 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message, ScreenToClient(hwnd(), &point); + last_touch_message_time_ = ::GetMessageTime(); + ui::EventType touch_event_type = ui::ET_UNKNOWN; if (input[i].dwFlags & TOUCHEVENTF_DOWN) { @@ -2332,10 +2343,11 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, // be WM_RBUTTONUP instead of WM_NCRBUTTONUP. SetCapture(); } - MSG msg = { hwnd(), message, w_param, l_param, GetMessageTime(), + long message_time = GetMessageTime(); + MSG msg = { hwnd(), message, w_param, l_param, message_time, { CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param) } }; ui::MouseEvent event(msg); - if (!touch_ids_.empty() || ui::IsMouseEventFromTouch(message)) + if (IsSynthesizedMouseMessage(message, message_time, l_param)) event.set_flags(event.flags() | ui::EF_FROM_TOUCH); if (!(event.flags() & ui::EF_IS_NON_CLIENT)) @@ -2379,4 +2391,26 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, return 0; } +bool HWNDMessageHandler::IsSynthesizedMouseMessage(unsigned int message, + int message_time, + LPARAM l_param) { + if (ui::IsMouseEventFromTouch(message)) + return true; + // Ignore mouse messages which occur at the same location as the current + // cursor position and within a time difference of 500 ms from the last + // touch message. + if (last_touch_message_time_ && message_time >= last_touch_message_time_ && + ((message_time - last_touch_message_time_) <= + kSynthesizedMouseTouchMessagesTimeDifference)) { + POINT mouse_location = CR_POINT_INITIALIZER_FROM_LPARAM(l_param); + ::ClientToScreen(hwnd(), &mouse_location); + POINT cursor_pos = {0}; + ::GetCursorPos(&cursor_pos); + if (memcmp(&cursor_pos, &mouse_location, sizeof(POINT))) + return false; + return true; + } + return false; +} + } // namespace views diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h index 50dfdf8..7aeaa7d 100644 --- a/ui/views/win/hwnd_message_handler.h +++ b/ui/views/win/hwnd_message_handler.h @@ -462,6 +462,15 @@ class VIEWS_EXPORT HWNDMessageHandler : LPARAM l_param, bool track_mouse); + // Returns true if the mouse message passed in is an OS synthesized mouse + // message. + // |message| identifies the mouse message. + // |message_time| is the time when the message occurred. + // |l_param| indicates the location of the mouse message. + bool IsSynthesizedMouseMessage(unsigned int message, + int message_time, + LPARAM l_param); + HWNDMessageHandlerDelegate* delegate_; scoped_ptr<FullscreenHandler> fullscreen_handler_; @@ -585,6 +594,12 @@ class VIEWS_EXPORT HWNDMessageHandler : // native SetFocus calls invoked in the views code. bool touch_down_context_; + // Time the last touch message was received. Used to flag mouse messages + // synthesized by Windows for touch which are not flagged by the OS as + // synthesized mouse messages. For more information please refer to + // the IsMouseEventFromTouch function. + static long last_touch_message_time_; + DISALLOW_COPY_AND_ASSIGN(HWNDMessageHandler); }; |