Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: ash/touch/touch_exploration_controller.cc

Issue 225143007: First crack at implementing the touch explaration mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor changes Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/touch/touch_exploration_controller.h"
6
7 #include "ash/root_window_settings.h"
8 #include "ash/shell.h"
9 #include "ash/wm/coordinate_conversion.h"
10 #include "base/logging.h"
11 #include "ui/aura/window_tree_host.h"
12 #include "ui/events/event.h"
13 #include "ui/events/event_processor.h"
14 #include "ui/gfx/point.h"
15
16 namespace ash {
17 namespace internal {
18
19 TouchExplorationController::TouchExplorationController(
20 aura::Window* root_window) :
21 display_id_(GetRootWindowSettings(root_window)->display_id),
22 root_window_(root_window) {
23 Shell::GetInstance()->display_controller()->AddObserver(this);
24 root_window_->AddPreTargetHandler(this);
25 }
26
27 TouchExplorationController::~TouchExplorationController() {
28 Shell::GetInstance()->display_controller()->RemoveObserver(this);
29 if (root_window_)
30 root_window_->RemovePreTargetHandler(this);
31 }
32
33 void TouchExplorationController::OnTouchEvent(ui::TouchEvent* event) {
34 ui::EventType type = event->type();
35 if (type == ui::ET_TOUCH_PRESSED) {
36 LOG(ERROR) << "ET_TOUCH_PRESSED";
37 // If this is the first and only finger touching - we are entering the
38 // mouse move mode.
39 if (touch_ids_.size() == 0) {
40 // TODO: Here and in other cases we take the flags from the touch event
mfomitchev 2014/04/11 21:00:58 Question here
sadrul 2014/04/14 20:22:11 Yes. The EventRewriter implementation should do th
41 // and send them along with the synthesized mouse event - is that correct?
42 GenerateMouseEvent(
43 ui::ET_MOUSE_ENTERED, event->location(), event->flags());
44 event->SetHandled();
45 event->StopPropagation();
mfomitchev 2014/04/11 21:00:58 If I don't call StopPropagation() (here and in oth
sadrul 2014/04/14 20:22:11 Yeah. We need to stop propagating the touch-event
46 }
47 // If this is the second finger - we should exit the mouse move mode (which
48 // we should have entered when the first finger touch started), and we
49 // should let this touch go through as is.
50 if (touch_ids_.size() == 1) {
51 // Generate ET_MOUSE_EXITED in the location of the _first_ touch.
52 int first_touch_id = touch_ids_.at(0);
53 gfx::Point first_touch_location = touch_locations_[first_touch_id];
54 GenerateMouseEvent(
sadrul 2014/04/14 20:22:11 WindowEventDispatcher takes care of dispatching mo
55 ui::ET_MOUSE_EXITED, first_touch_location, event->flags());
56 }
57 touch_ids_.push_back(event->touch_id());
58 touch_locations_.insert(
59 std::pair<int, gfx::Point>(event->touch_id(), event->location()));
60 // Ignore the synthesized release events - we are synthesizing them below.
61 } else if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)
62 && !(event->flags() & ui::EF_IS_SYNTHESIZED)) {
63 LOG(ERROR) << (type == ui::ET_TOUCH_RELEASED ?
64 "ET_TOUCH_RELEASED" : "ET_TOUCH_CANCELLED");
65 int touch_id = event->touch_id();
66 std::vector<int>::iterator it =
67 std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
68 if (it != touch_ids_.end()) {
69 // If it was the first finger that was lifted, we need to do a few
70 // things depending on how many fingers were on the screen:
71 // 1. If only one finger was on the screen, this is simply equivalent to
72 // the end of the mouse move.
73 // 2. If there were multiple fingers on the screen, this is equivalent
74 // to lifting the _second_ finger. Also, if there were exactly two
75 // fingers touching, we are only left with one, so we are entering the
76 // mouse move mode, and so we should also generate ET_MOUSE_ENTERED.
77 if (it == touch_ids_.begin()) {
78 if (touch_ids_.size() == 1) {
79 GenerateMouseEvent(
80 ui::ET_MOUSE_EXITED, event->location(), event->flags());
81 } else {
82 LOG(ERROR) << "Generating touch release event";
83 // Generate a touch release event for the second finger.
84 int second_touch_id = touch_ids_.at(1);
85 gfx::Point second_touch_location = touch_locations_[second_touch_id];
86 aura::Window* root = wm::GetRootWindowAt(second_touch_location);
87 DCHECK(root)
88 << "Root window not found while generating touch release event.";
89 aura::WindowTreeHost* host = root->GetHost();
90 // TODO: Should I use another constructor to pass in the flags?
mfomitchev 2014/04/11 21:00:58 Question here
91 ui::TouchEvent touch_event(ui::ET_TOUCH_RELEASED,
92 second_touch_location,
93 second_touch_id,
94 event->time_stamp());
95 host->event_processor()->OnEventFromSource(&touch_event);
96 // If there were exactly two fingers touching - generate
97 // ET_MOUSE_ENTERED.
98 if (touch_ids_.size() == 2) {
99 GenerateMouseEvent(
100 ui::ET_MOUSE_ENTERED, second_touch_location, event->flags());
101 }
102 }
103 event->SetHandled();
104 event->StopPropagation();
105 }
106 touch_ids_.erase(it);
107 touch_locations_.erase(touch_id);
108 } else {
109 NOTREACHED();
110 }
111 } else if (type == ui::ET_TOUCH_MOVED) {
112 LOG(ERROR) << "ET_TOUCH_MOVED";
113 // Consume if it is the first finger.
114 // If it is the only finger - generate a mouse move event.
115 std::vector<int>::iterator it =
116 std::find(touch_ids_.begin(), touch_ids_.end(), event->touch_id());
117 if (it != touch_ids_.end()) {
118 if (it == touch_ids_.begin()) {
119 if (touch_ids_.size() == 1) {
120 GenerateMouseEvent(
121 ui::ET_MOUSE_MOVED, event->location(), event->flags());
122 }
123 event->SetHandled();
124 event->StopPropagation();
125 }
126 touch_locations_[*it] = event->location();
127 } else {
128 NOTREACHED();
129 }
130 }
131 }
132
133 void TouchExplorationController::OnDisplaysInitialized() {
134 OnDisplayConfigurationChanged();
135 }
136
137 void TouchExplorationController::OnDisplayConfigurationChanging() {
138 if (!root_window_)
139 return;
140
141 root_window_->RemovePreTargetHandler(this);
142 root_window_ = NULL;
143 }
144
145 void TouchExplorationController::OnDisplayConfigurationChanged() {
146 if (root_window_)
147 return;
148
149 root_window_ = Shell::GetInstance()->display_controller()->
150 GetRootWindowForDisplayId(display_id_);
151 root_window_->AddPreTargetHandler(this);
152 }
153
154 void TouchExplorationController::GenerateMouseEvent(ui::EventType event_type,
155 gfx::Point location,
156 int flags) {
157 aura::Window* root_window = wm::GetRootWindowAt(location);
158 DCHECK(root_window)
159 << "Root window not found while converting touch to mouse event.";
160 aura::WindowTreeHost* host = root_window->GetHost();
161
162 LOG(ERROR) << "Generating mouse event: type=" << event_type;
163 ui::MouseEvent mouse_event(event_type,
164 location,
165 location,
166 ui::EF_IS_SYNTHESIZED | flags,
167 0);
168
169 // TODO: Should I use WindowEventDispatcher instead?
mfomitchev 2014/04/11 21:00:58 Question here
sadrul 2014/04/14 20:22:11 This is fine.
170 host->event_processor()->OnEventFromSource(&mouse_event);
171 }
172
173 } // namespace internal
174 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698