summaryrefslogtreecommitdiffstats
path: root/ui/views
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-04 18:47:17 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-04 18:47:17 +0000
commit143791f3767cb0c7007d2e517400c9ed2d9eb7c4 (patch)
tree6dfe610c7922774322ab0b1fd6dad9a488178f20 /ui/views
parentbcc3d57371525d3a8acf37f053d3633db0521a33 (diff)
downloadchromium_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.cc38
-rw-r--r--ui/views/win/hwnd_message_handler.h15
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);
};