| 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 13cc62cbfbbe0db0a62cf78f37d39da3f0e2ce33..39de755bb48d68d4a78c4d920c0e42d108fb6424 100644
|
| --- a/ui/views/win/hwnd_message_handler.cc
|
| +++ b/ui/views/win/hwnd_message_handler.cc
|
| @@ -10,6 +10,7 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| +#include "base/logging.h"
|
| #include "base/profiler/scoped_tracker.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/tracked_objects.h"
|
| @@ -328,6 +329,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) {
|
| }
|
| @@ -2301,8 +2303,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);
|
| @@ -2318,50 +2318,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.
|
| @@ -2375,6 +2343,104 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
|
| return 0;
|
| }
|
|
|
| +void HWNDMessageHandler::PrepareTouchEventList(TOUCHINPUT input[],
|
| + int num_points,
|
| + TouchEvents* touch_events) {
|
| + 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);
|
| +
|
| + // TOUCHEVENTF_DOWN cannot be combined with TOUCHEVENTF_MOVE or
|
| + // TOUCHEVENTF_UP, but TOUCHEVENTF_MOVE and TOUCHEVENTF_UP can be combined
|
| + // in one input.
|
| + if (input[i].dwFlags & TOUCHEVENTF_DOWN) {
|
| + touch_down_contexts_++;
|
| + active_touch_point_count_++;
|
| + GenerateTouchEvent(input[i].dwID, point_location, ui::ET_TOUCH_PRESSED,
|
| + touch_events);
|
| + } else {
|
| + if (input[i].dwFlags & TOUCHEVENTF_MOVE) {
|
| + GenerateTouchEvent(input[i].dwID, point_location, ui::ET_TOUCH_MOVED,
|
| + touch_events);
|
| + }
|
| + if (input[i].dwFlags & TOUCHEVENTF_UP) {
|
| + active_touch_point_count_--;
|
| + GenerateTouchEvent(input[i].dwID, point_location, ui::ET_TOUCH_RELEASED,
|
| + 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 we see any touchmove or touchrelease we never seen before, we ignore
|
| + // them.
|
| + if (touch_point.in_touch_list == InTouchList::NotPresent &&
|
| + (touch_event_type == ui::ET_TOUCH_MOVED ||
|
| + touch_event_type == ui::ET_TOUCH_RELEASED))
|
| + return;
|
| +
|
| + 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(
|
| @@ -2509,15 +2575,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.
|
|
|