Chromium Code Reviews| Index: ui/views/win/hwnd_message_handler.cc |
| diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc |
| index 8499cbfaedff42e8a465cc57924b92366b2f0c61..5eb7a8df2d14bbacd0117589943aba46b1b2ea4b 100644 |
| --- a/ui/views/win/hwnd_message_handler.cc |
| +++ b/ui/views/win/hwnd_message_handler.cc |
| @@ -360,6 +360,7 @@ HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) |
| last_mouse_hwheel_time_(0), |
| msg_handled_(FALSE), |
| dwm_transition_desired_(false), |
| + active_touch_point_count_(0), |
| autohide_factory_(this), |
| weak_factory_(this) { |
| } |
| @@ -2444,8 +2445,6 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message, |
| if (ui::GetTouchInputInfoWrapper(reinterpret_cast<HTOUCHINPUT>(l_param), |
| num_points, input.get(), |
| sizeof(TOUCHINPUT))) { |
| - int flags = ui::GetModifiersFromKeyState(); |
| - TouchEvents touch_events; |
| for (int i = 0; i < num_points; ++i) { |
| POINT point; |
| point.x = TOUCH_COORD_TO_PIXEL(input[i].x); |
| @@ -2461,50 +2460,18 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message, |
| if (hittest != HTCLIENT) |
| return 0; |
| } |
| - |
| - ScreenToClient(hwnd(), &point); |
| - |
| - last_touch_message_time_ = ::GetMessageTime(); |
| - |
| - ui::EventType touch_event_type = ui::ET_UNKNOWN; |
| - |
| - if (input[i].dwFlags & TOUCHEVENTF_DOWN) { |
| - touch_ids_.insert(input[i].dwID); |
| - touch_event_type = ui::ET_TOUCH_PRESSED; |
| - touch_down_contexts_++; |
| - base::MessageLoop::current()->PostDelayedTask( |
| - FROM_HERE, |
| - base::Bind(&HWNDMessageHandler::ResetTouchDownContext, |
| - weak_factory_.GetWeakPtr()), |
| - base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout)); |
| - } else if (input[i].dwFlags & TOUCHEVENTF_UP) { |
| - touch_ids_.erase(input[i].dwID); |
| - touch_event_type = ui::ET_TOUCH_RELEASED; |
| - } else if (input[i].dwFlags & TOUCHEVENTF_MOVE) { |
| - touch_event_type = ui::ET_TOUCH_MOVED; |
| - } |
| - if (touch_event_type != ui::ET_UNKNOWN) { |
| - // input[i].dwTime doesn't necessarily relate to the system time at all, |
| - // so use base::TimeTicks::Now() |
| - const base::TimeTicks now = base::TimeTicks::Now(); |
| - ui::TouchEvent event(touch_event_type, |
| - gfx::Point(point.x, point.y), |
| - id_generator_.GetGeneratedID(input[i].dwID), |
| - now - base::TimeTicks()); |
| - event.set_flags(flags); |
| - event.latency()->AddLatencyNumberWithTimestamp( |
| - ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, |
| - 0, |
| - 0, |
| - base::TimeTicks::FromInternalValue( |
| - event.time_stamp().ToInternalValue()), |
| - 1); |
| - |
| - touch_events.push_back(event); |
| - if (touch_event_type == ui::ET_TOUCH_RELEASED) |
| - id_generator_.ReleaseNumber(input[i].dwID); |
| - } |
| } |
| + TouchEvents touch_events; |
| + int old_touch_down_contexts = touch_down_contexts_; |
| + PrepareTouchEventList(input.get(), num_points, &touch_events); |
| + int new_touch_presses = touch_down_contexts_ - old_touch_down_contexts; |
| + if (new_touch_presses > 0) { |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, base::Bind(&HWNDMessageHandler::DecrementTouchDownContext, |
| + weak_factory_.GetWeakPtr(), new_touch_presses), |
| + base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout)); |
| + } |
| + |
| // Handle the touch events asynchronously. We need this because touch |
| // events on windows don't fire if we enter a modal loop in the context of |
| // a touch event. |
| @@ -2518,6 +2485,108 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message, |
| return 0; |
| } |
| +void HWNDMessageHandler::PrepareTouchEventList(TOUCHINPUT input[], |
| + int num_points, |
| + TouchEvents* touch_events) { |
| + ui::EventType touch_event_type = ui::ET_UNKNOWN; |
| + for (int i = 0; i < num_points; ++i) { |
| + POINT point; |
| + point.x = TOUCH_COORD_TO_PIXEL(input[i].x); |
| + point.y = TOUCH_COORD_TO_PIXEL(input[i].y); |
| + gfx::Point point_location(point.x, point.y); |
| + |
| + ScreenToClient(hwnd(), &point); |
| + |
| + touch_event_type = ui::ET_UNKNOWN; |
| + if (input[i].dwFlags & TOUCHEVENTF_DOWN) { |
| + touch_event_type = ui::ET_TOUCH_PRESSED; |
| + touch_down_contexts_++; |
| + active_touch_point_count_++; |
| + GenerateTouchEvent(input[i].dwID, point_location, touch_event_type, |
|
ananta
2015/05/05 22:06:58
I don't think that TOUCHEVENTF_DOWN can be combine
lanwei
2015/05/06 02:53:47
You are right, TOUCHEVENTF_DOWN cannot be combine
|
| + touch_events); |
| + } |
| + if (input[i].dwFlags & TOUCHEVENTF_MOVE) { |
| + touch_event_type = ui::ET_TOUCH_MOVED; |
| + GenerateTouchEvent(input[i].dwID, point_location, touch_event_type, |
| + touch_events); |
| + } |
| + if (input[i].dwFlags & TOUCHEVENTF_UP) { |
| + touch_event_type = ui::ET_TOUCH_RELEASED; |
| + active_touch_point_count_--; |
| + GenerateTouchEvent(input[i].dwID, point_location, touch_event_type, |
| + touch_events); |
| + } |
| + } |
| + last_touch_message_time_ = ::GetMessageTime(); |
| + |
| + UpdateTouchPointStates(touch_events); |
| +} |
| + |
| +void HWNDMessageHandler::GenerateTouchEvent(DWORD input_dwID, |
| + const gfx::Point& point_location, |
| + ui::EventType touch_event_type, |
| + TouchEvents* touch_events) { |
| + int touch_id = static_cast<int>(id_generator_.GetGeneratedID(input_dwID)); |
| + if (touch_id < 0 || touch_id >= static_cast<int>(touch_id_list_.size())) { |
| + return; |
| + } |
| + |
| + TouchPoint& touch_point = touch_id_list_[touch_id]; |
| + int flags = ui::GetModifiersFromKeyState(); |
| + |
| + // The dwTime of every input in the WM_TOUCH message doesn't necessarily |
| + // relate to the system time at all, so use base::TimeTicks::Now() for |
| + // touchevent time. |
| + base::TimeDelta now = ui::EventTimeForNow(); |
| + |
| + // If this touch pointer is not in the previous touch id list and it is |
| + // not a touch press, we should generate a touch press for it first. |
| + if (touch_event_type != ui::ET_TOUCH_PRESSED && |
| + touch_point.in_touch_list == InTouchList::NotPresent) { |
| + ui::TouchEvent event(ui::ET_TOUCH_PRESSED, point_location, touch_id, now); |
| + touch_events->push_back(event); |
| + touch_down_contexts_++; |
| + active_touch_point_count_++; |
| + } |
| + |
| + ui::TouchEvent event(touch_event_type, point_location, touch_id, now); |
| + event.set_flags(flags); |
| + event.latency()->AddLatencyNumberWithTimestamp( |
| + ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, base::TimeTicks::Now(), |
| + 1); |
| + touch_events->push_back(event); |
| + |
| + // Mark the active touch pointers in the touch_id_list_ to be |
| + // InCurrentMessage, so we can track the ones which are missed in the |
| + // current message and release them. |
| + if (touch_event_type == ui::ET_TOUCH_RELEASED) { |
| + id_generator_.ReleaseNumber(input_dwID); |
| + touch_point.in_touch_list = InTouchList::NotPresent; |
| + } else { |
| + touch_point.in_touch_list = InTouchList::InCurrentMessage; |
| + touch_point.location = point_location; |
| + } |
| +} |
| + |
| +void HWNDMessageHandler::UpdateTouchPointStates(TouchEvents* touch_events) { |
| + for (size_t i = 0; i != touch_id_list_.size(); ++i) { |
| + // Loop through the touch pointers list, if we see any which is only in |
| + // the previous message, we will send a touch release event for this ID. |
| + TouchPoint& touch_point = touch_id_list_[i]; |
| + if (touch_point.in_touch_list == InTouchList::InPreviousMessage) { |
| + base::TimeDelta now = base::TimeTicks::Now() - base::TimeTicks(); |
| + ui::TouchEvent event(ui::ET_TOUCH_RELEASED, touch_point.location, |
| + static_cast<int>(i), now); |
| + touch_events->push_back(event); |
| + touch_point.in_touch_list = InTouchList::NotPresent; |
| + id_generator_.ReleaseGeneratedID(i); |
| + active_touch_point_count_--; |
| + } else if (touch_point.in_touch_list == InTouchList::InCurrentMessage) { |
| + touch_point.in_touch_list = InTouchList::InPreviousMessage; |
| + } |
| + } |
| +} |
| + |
| void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. |
| tracked_objects::ScopedTracker tracking_profile( |
| @@ -2640,15 +2709,15 @@ void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { |
| delegate_->HandleTouchEvent(touch_events[i]); |
| } |
| -void HWNDMessageHandler::ResetTouchDownContext() { |
| - touch_down_contexts_--; |
| +void HWNDMessageHandler::DecrementTouchDownContext(int decrement) { |
| + touch_down_contexts_ -= decrement; |
| } |
| LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, |
| WPARAM w_param, |
| LPARAM l_param, |
| bool track_mouse) { |
| - if (!touch_ids_.empty()) |
| + if (active_touch_point_count_) |
| return 0; |
| // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. |