OLD | NEW |
---|---|
(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/client/cursor_client.h" | |
12 #include "ui/aura/window_tree_host.h" | |
13 #include "ui/events/event.h" | |
14 #include "ui/gfx/point.h" | |
15 | |
16 namespace ash { | |
17 | |
18 TouchExplorationController::TouchExplorationController( | |
19 aura::Window* root_window) : | |
20 display_id_(GetRootWindowSettings(root_window)->display_id), | |
21 root_window_(root_window) { | |
22 Shell::GetInstance()->display_controller()->AddObserver(this); | |
23 ui::EventSource* event_source = root_window->GetHost()->GetEventSource(); | |
24 event_source->AddEventRewriter(this); | |
25 } | |
26 | |
27 TouchExplorationController::~TouchExplorationController() { | |
28 Shell::GetInstance()->display_controller()->RemoveObserver(this); | |
29 if (root_window_) | |
30 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | |
31 } | |
32 | |
33 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | |
34 const ui::Event& event, | |
35 scoped_ptr<ui::Event>* rewritten_event) { | |
36 if (!event.IsTouchEvent()) { | |
37 return ui::EVENT_REWRITE_CONTINUE; | |
38 } | |
39 ui::EventRewriteStatus result; | |
40 const ui::TouchEvent& touch_event = | |
41 static_cast<const ui::TouchEvent&> (event); | |
42 ui::EventType type = touch_event.type(); | |
43 gfx::Point location = touch_event.location(); | |
44 int touch_id = touch_event.touch_id(); | |
45 int flags = touch_event.flags(); | |
46 | |
47 if (type == ui::ET_TOUCH_PRESSED) { | |
48 LOG(ERROR) << "ET_TOUCH_PRESSED"; | |
49 // If this is the first and only finger touching rewrite the touch as a | |
50 // mouse move. | |
51 if (touch_ids_.size() == 0) { | |
52 result = ui::EVENT_REWRITE_REWRITTEN; | |
53 rewritten_event->reset(CreateMouseMoveEvent(location, flags)); | |
54 aura::client::CursorClient* cursor_client = | |
55 root_window_ ? aura::client::GetCursorClient(root_window_) : NULL; | |
56 if (cursor_client) { | |
57 cursor_client->EnableMouseEvents(); | |
mfomitchev
2014/04/16 19:32:17
This makes mouse events go through
| |
58 cursor_client->HideCursor(); | |
mfomitchev
2014/04/16 19:32:17
Don't think we want to see the cursor while touchi
| |
59 } | |
60 | |
61 // Otherwise let the touch go through. | |
62 } else { | |
63 result = ui::EVENT_REWRITE_CONTINUE; | |
64 } | |
65 touch_ids_.push_back(touch_id); | |
66 touch_locations_.insert(std::pair<int, gfx::Point>(touch_id, location)); | |
67 } else if ((type == ui::ET_TOUCH_RELEASED || | |
68 type == ui::ET_TOUCH_CANCELLED)) { | |
69 LOG(ERROR) << (type == ui::ET_TOUCH_RELEASED ? | |
70 "ET_TOUCH_RELEASED" : "ET_TOUCH_CANCELLED"); | |
71 std::vector<int>::iterator it = | |
72 std::find(touch_ids_.begin(), touch_ids_.end(), touch_id); | |
73 if (it != touch_ids_.end()) { | |
74 if (it != touch_ids_.begin()) { | |
75 // If it wasn't the first finger that was lifted, leave the event as is. | |
76 result = ui::EVENT_REWRITE_CONTINUE; | |
77 } else { | |
78 // If it was the first finger that was lifted, we need to do a few | |
79 // things depending on how many fingers were on the screen: | |
80 // 1. If only one finger was on the screen, this is simply equivalent to | |
81 // the end of the mouse move. | |
82 // 2. If there were multiple fingers on the screen, this is equivalent | |
83 // to lifting the _second_ finger. Also, if there were exactly two | |
84 // fingers touching, we are only left with one, so we are entering | |
85 // the mouse move mode, and so we should also generate a mouse move. | |
86 if (touch_ids_.size() == 1) { | |
87 result = ui::EVENT_REWRITE_REWRITTEN; | |
88 rewritten_event->reset(CreateMouseMoveEvent(location, flags)); | |
89 } else { | |
90 LOG(ERROR) << "Rewriting as a touch release event"; | |
91 // Rewrite the release of the first finger as a release of the | |
92 // second finger. | |
93 int second_touch_id = touch_ids_.at(1); | |
94 gfx::Point second_touch_location = touch_locations_[second_touch_id]; | |
95 ui::TouchEvent* touch_release_event = new ui::TouchEvent( | |
96 ui::ET_TOUCH_RELEASED, | |
97 second_touch_location, | |
98 second_touch_id, | |
99 event.time_stamp()); | |
100 rewritten_event->reset(touch_release_event); | |
101 if (touch_ids_.size() == 2) { | |
102 // If there were exactly two fingers touching - also dispatch | |
103 // a mouse move corresponding to the second finger's location. | |
104 result = ui::EVENT_REWRITE_DISPATCH_ANOTHER; | |
105 next_dispatch_event_.reset( | |
106 CreateMouseMoveEvent(second_touch_location, flags)); | |
107 } else { | |
108 result = ui::EVENT_REWRITE_REWRITTEN; | |
109 } | |
110 } | |
111 } | |
112 touch_ids_.erase(it); | |
113 touch_locations_.erase(touch_id); | |
114 } else { | |
115 NOTREACHED(); | |
116 result = ui::EVENT_REWRITE_CONTINUE; | |
117 } | |
118 } else if (type == ui::ET_TOUCH_MOVED) { | |
119 LOG(ERROR) << "ET_TOUCH_MOVED"; | |
120 // Consume if it is the first finger. | |
121 // If it is the the first and only finger - generate a mouse move event. | |
122 std::vector<int>::iterator it = | |
123 std::find(touch_ids_.begin(), touch_ids_.end(), touch_id); | |
124 if (it != touch_ids_.end()) { | |
125 if (it != touch_ids_.begin()) { | |
126 result = ui::EVENT_REWRITE_CONTINUE; | |
127 } else { | |
128 if (touch_ids_.size() == 1) { | |
129 result = ui::EVENT_REWRITE_REWRITTEN; | |
130 rewritten_event->reset(CreateMouseMoveEvent(location, flags)); | |
131 } else { | |
132 result = ui::EVENT_REWRITE_DISCARD; | |
133 } | |
134 } | |
135 touch_locations_[*it] = location; | |
136 } else { | |
137 NOTREACHED(); | |
138 result = ui::EVENT_REWRITE_CONTINUE; | |
139 } | |
140 } else { | |
141 result = ui::EVENT_REWRITE_CONTINUE; | |
142 } | |
143 return result; | |
144 } | |
145 | |
146 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | |
147 const ui::Event& last_event, | |
148 scoped_ptr<ui::Event>* new_event) { | |
149 new_event->reset(next_dispatch_event_.release()); | |
150 return ui::EVENT_REWRITE_REWRITTEN; | |
151 } | |
152 | |
153 void TouchExplorationController::OnDisplaysInitialized() { | |
154 OnDisplayConfigurationChanged(); | |
155 } | |
156 | |
157 void TouchExplorationController::OnDisplayConfigurationChanging() { | |
158 if (!root_window_) | |
159 return; | |
160 | |
161 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | |
162 root_window_ = NULL; | |
163 } | |
164 | |
165 void TouchExplorationController::OnDisplayConfigurationChanged() { | |
166 if (root_window_) | |
167 return; | |
168 | |
169 root_window_ = Shell::GetInstance()->display_controller()-> | |
170 GetRootWindowForDisplayId(display_id_); | |
171 root_window_->GetHost()->GetEventSource()->AddEventRewriter(this); | |
172 } | |
173 | |
174 ui::Event* TouchExplorationController::CreateMouseMoveEvent( | |
175 gfx::Point location, int flags) { | |
176 LOG(ERROR) << "Creating mouse move event"; | |
177 return new ui::MouseEvent(ui::ET_MOUSE_MOVED, | |
178 location, | |
179 location, | |
180 ui::EF_IS_SYNTHESIZED | flags, | |
181 0); | |
182 } | |
183 | |
184 } // namespace ash | |
OLD | NEW |