summaryrefslogtreecommitdiffstats
path: root/ui/views/win/hwnd_message_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/views/win/hwnd_message_handler.cc')
-rw-r--r--ui/views/win/hwnd_message_handler.cc38
1 files changed, 36 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