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

Side by Side Diff: ui/views/mus/pointer_watcher_event_router.cc

Issue 2248263003: Updates PointerEventRouter to handle switching move type (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: false- Created 4 years, 4 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/mus/pointer_watcher_event_router.h" 5 #include "ui/views/mus/pointer_watcher_event_router.h"
6 6
7 #include "services/ui/public/cpp/window.h" 7 #include "services/ui/public/cpp/window.h"
8 #include "services/ui/public/cpp/window_tree_client.h" 8 #include "services/ui/public/cpp/window_tree_client.h"
9 #include "ui/events/base_event_utils.h" 9 #include "ui/events/base_event_utils.h"
10 #include "ui/events/event.h" 10 #include "ui/events/event.h"
11 #include "ui/views/mus/native_widget_mus.h" 11 #include "ui/views/mus/native_widget_mus.h"
12 #include "ui/views/pointer_watcher.h" 12 #include "ui/views/pointer_watcher.h"
13 13
14 namespace views { 14 namespace views {
15 namespace {
16
17 bool HasPointerWatcher(
18 base::ObserverList<views::PointerWatcher, true>* observer_list) {
19 if (!observer_list->might_have_observers())
20 return false;
21
22 // might_have_observers() returned true, see if there really are any
23 // observers. The only way to truly know is to use an Iterator and see if it
24 // has at least one observer.
25 base::ObserverList<PointerWatcher>::Iterator iterator(observer_list);
26 return !!iterator.GetNext();
27 }
28
29 } // namespace
15 30
16 PointerWatcherEventRouter::PointerWatcherEventRouter( 31 PointerWatcherEventRouter::PointerWatcherEventRouter(
17 ui::WindowTreeClient* client) 32 ui::WindowTreeClient* client)
18 : window_tree_client_(client) { 33 : window_tree_client_(client) {
19 client->AddObserver(this); 34 client->AddObserver(this);
20 } 35 }
21 36
22 PointerWatcherEventRouter::~PointerWatcherEventRouter() { 37 PointerWatcherEventRouter::~PointerWatcherEventRouter() {
23 if (window_tree_client_) 38 if (window_tree_client_)
24 window_tree_client_->RemoveObserver(this); 39 window_tree_client_->RemoveObserver(this);
25 } 40 }
26 41
27 void PointerWatcherEventRouter::AddPointerWatcher(PointerWatcher* watcher, 42 void PointerWatcherEventRouter::AddPointerWatcher(PointerWatcher* watcher,
28 bool want_moves) { 43 bool wants_moves) {
29 // Pointer watchers cannot be added multiple times. 44 if (wants_moves) {
30 DCHECK(!pointer_watchers_.HasObserver(watcher)); 45 // Pointer watchers cannot be added multiple times.
msw 2016/08/18 22:45:23 Should this check both lists? (ditto below)
sky 2016/08/18 23:17:15 Done.
31 // TODO(jamescook): Support adding pointer watchers with different 46 DCHECK(!move_watchers_.HasObserver(watcher));
32 // |want_moves| values by tracking whether the set as a whole wants moves. 47 move_watchers_.AddObserver(watcher);
33 // This will involve sending observed move events to a subset of the 48 if (event_types_ != EventTypes::MOVE_EVENTS) {
34 // watchers. (crbug.com/627146) 49 event_types_ = EventTypes::MOVE_EVENTS;
35 DCHECK(!HasPointerWatcher() || want_moves == pointer_watcher_want_moves_); 50 const bool wants_moves = true;
36 pointer_watcher_want_moves_ = want_moves; 51 window_tree_client_->StartPointerWatcher(wants_moves);
37 52 }
38 bool had_watcher = HasPointerWatcher(); 53 } else {
39 pointer_watchers_.AddObserver(watcher); 54 // Pointer watchers cannot be added multiple times.
40 if (!had_watcher) { 55 DCHECK(!non_move_watchers_.HasObserver(watcher));
41 // First PointerWatcher added, start the watcher on the window server. 56 non_move_watchers_.AddObserver(watcher);
42 window_tree_client_->StartPointerWatcher(want_moves); 57 if (event_types_ == EventTypes::NONE) {
58 event_types_ = EventTypes::NON_MOVE_EVENTS;
59 const bool wants_moves = false;
60 window_tree_client_->StartPointerWatcher(wants_moves);
61 }
43 } 62 }
44 } 63 }
45 64
46 void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) { 65 void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) {
47 DCHECK(pointer_watchers_.HasObserver(watcher)); 66 if (non_move_watchers_.HasObserver(watcher)) {
48 pointer_watchers_.RemoveObserver(watcher); 67 non_move_watchers_.RemoveObserver(watcher);
49 if (!HasPointerWatcher()) { 68 } else {
50 // Last PointerWatcher removed, stop the watcher on the window server. 69 DCHECK(move_watchers_.HasObserver(watcher));
51 window_tree_client_->StopPointerWatcher(); 70 move_watchers_.RemoveObserver(watcher);
52 pointer_watcher_want_moves_ = false; 71 }
72 const EventTypes types = DetermineEventTypes();
73 if (types == event_types_)
74 return;
75
76 event_types_ = types;
77 switch (types) {
78 case EventTypes::NONE:
79 window_tree_client_->StopPointerWatcher();
80 break;
81 case EventTypes::NON_MOVE_EVENTS:
82 window_tree_client_->StartPointerWatcher(false);
83 break;
84 case EventTypes::MOVE_EVENTS:
85 // It isn't possible to remove an observer and transition to wanting move
86 // events. This could only happen if there is a bug in the add logic.
87 NOTREACHED();
88 break;
53 } 89 }
54 } 90 }
55 91
56 void PointerWatcherEventRouter::OnPointerEventObserved( 92 void PointerWatcherEventRouter::OnPointerEventObserved(
57 const ui::PointerEvent& event, 93 const ui::PointerEvent& event,
58 ui::Window* target) { 94 ui::Window* target) {
59 Widget* target_widget = nullptr; 95 Widget* target_widget = nullptr;
60 if (target) { 96 if (target) {
61 ui::Window* window = target; 97 ui::Window* window = target;
62 while (window && !target_widget) { 98 while (window && !target_widget) {
63 target_widget = NativeWidgetMus::GetWidgetForWindow(target); 99 target_widget = NativeWidgetMus::GetWidgetForWindow(target);
64 window = window->parent(); 100 window = window->parent();
65 } 101 }
66 } 102 }
67 103
68 // The mojo input events type converter uses the event root_location field 104 // The mojo input events type converter uses the event root_location field
69 // to store screen coordinates. Screen coordinates really should be returned 105 // to store screen coordinates. Screen coordinates really should be returned
70 // separately. See http://crbug.com/608547 106 // separately. See http://crbug.com/608547
71 gfx::Point location_in_screen = event.AsLocatedEvent()->root_location(); 107 gfx::Point location_in_screen = event.AsLocatedEvent()->root_location();
72 FOR_EACH_OBSERVER( 108 FOR_EACH_OBSERVER(
73 PointerWatcher, pointer_watchers_, 109 PointerWatcher, move_watchers_,
74 OnPointerEventObserved(event, location_in_screen, target_widget)); 110 OnPointerEventObserved(event, location_in_screen, target_widget));
111 if (event.type() != ui::ET_POINTER_MOVED) {
112 FOR_EACH_OBSERVER(
113 PointerWatcher, non_move_watchers_,
114 OnPointerEventObserved(event, location_in_screen, target_widget));
115 }
75 } 116 }
76 117
77 bool PointerWatcherEventRouter::HasPointerWatcher() { 118 PointerWatcherEventRouter::EventTypes
78 // Check to see if we really have any observers left. This doesn't use 119 PointerWatcherEventRouter::DetermineEventTypes() {
79 // base::ObserverList<>::might_have_observers() because that returns true 120 if (HasPointerWatcher(&move_watchers_))
80 // during iteration over the list even when the last observer is removed. 121 return EventTypes::MOVE_EVENTS;
81 base::ObserverList<PointerWatcher>::Iterator iterator(&pointer_watchers_); 122
82 return !!iterator.GetNext(); 123 if (HasPointerWatcher(&non_move_watchers_))
124 return EventTypes::NON_MOVE_EVENTS;
125
126 return EventTypes::NONE;
83 } 127 }
84 128
85 void PointerWatcherEventRouter::OnWindowTreeCaptureChanged( 129 void PointerWatcherEventRouter::OnWindowTreeCaptureChanged(
86 ui::Window* gained_capture, 130 ui::Window* gained_capture,
87 ui::Window* lost_capture) { 131 ui::Window* lost_capture) {
88 FOR_EACH_OBSERVER(PointerWatcher, pointer_watchers_, OnMouseCaptureChanged()); 132 FOR_EACH_OBSERVER(PointerWatcher, move_watchers_, OnMouseCaptureChanged());
133 FOR_EACH_OBSERVER(PointerWatcher, non_move_watchers_,
134 OnMouseCaptureChanged());
89 } 135 }
90 136
91 void PointerWatcherEventRouter::OnDidDestroyClient( 137 void PointerWatcherEventRouter::OnDidDestroyClient(
92 ui::WindowTreeClient* client) { 138 ui::WindowTreeClient* client) {
93 DCHECK(!pointer_watchers_.might_have_observers()); 139 // We expect that all observers have been removed by this time.
140 DCHECK_EQ(event_types_, EventTypes::NONE);
94 DCHECK_EQ(client, window_tree_client_); 141 DCHECK_EQ(client, window_tree_client_);
95 window_tree_client_->RemoveObserver(this); 142 window_tree_client_->RemoveObserver(this);
96 window_tree_client_ = nullptr; 143 window_tree_client_ = nullptr;
97 } 144 }
98 145
99 } // namespace views 146 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698