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

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: merge again 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 // Pointer watchers cannot be added multiple times.
30 DCHECK(!pointer_watchers_.HasObserver(watcher)); 45 DCHECK(!move_watchers_.HasObserver(watcher));
31 // TODO(jamescook): Support adding pointer watchers with different 46 DCHECK(!non_move_watchers_.HasObserver(watcher));
32 // |want_moves| values by tracking whether the set as a whole wants moves. 47 if (wants_moves) {
33 // This will involve sending observed move events to a subset of the 48 move_watchers_.AddObserver(watcher);
34 // watchers. (crbug.com/627146) 49 if (event_types_ != EventTypes::MOVE_EVENTS) {
35 DCHECK(!HasPointerWatcher() || want_moves == pointer_watcher_want_moves_); 50 event_types_ = EventTypes::MOVE_EVENTS;
36 pointer_watcher_want_moves_ = want_moves; 51 const bool wants_moves = true;
37 52 window_tree_client_->StartPointerWatcher(wants_moves);
38 bool had_watcher = HasPointerWatcher(); 53 }
39 pointer_watchers_.AddObserver(watcher); 54 } else {
40 if (!had_watcher) { 55 non_move_watchers_.AddObserver(watcher);
41 // First PointerWatcher added, start the watcher on the window server. 56 if (event_types_ == EventTypes::NONE) {
42 window_tree_client_->StartPointerWatcher(want_moves); 57 event_types_ = EventTypes::NON_MOVE_EVENTS;
58 const bool wants_moves = false;
59 window_tree_client_->StartPointerWatcher(wants_moves);
60 }
43 } 61 }
44 } 62 }
45 63
46 void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) { 64 void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) {
47 DCHECK(pointer_watchers_.HasObserver(watcher)); 65 if (non_move_watchers_.HasObserver(watcher)) {
48 pointer_watchers_.RemoveObserver(watcher); 66 non_move_watchers_.RemoveObserver(watcher);
49 if (!HasPointerWatcher()) { 67 } else {
50 // Last PointerWatcher removed, stop the watcher on the window server. 68 DCHECK(move_watchers_.HasObserver(watcher));
51 window_tree_client_->StopPointerWatcher(); 69 move_watchers_.RemoveObserver(watcher);
52 pointer_watcher_want_moves_ = false; 70 }
71 const EventTypes types = DetermineEventTypes();
72 if (types == event_types_)
73 return;
74
75 event_types_ = types;
76 switch (types) {
77 case EventTypes::NONE:
78 window_tree_client_->StopPointerWatcher();
79 break;
80 case EventTypes::NON_MOVE_EVENTS:
81 window_tree_client_->StartPointerWatcher(false);
82 break;
83 case EventTypes::MOVE_EVENTS:
84 // It isn't possible to remove an observer and transition to wanting move
85 // events. This could only happen if there is a bug in the add logic.
86 NOTREACHED();
87 break;
53 } 88 }
54 } 89 }
55 90
56 void PointerWatcherEventRouter::OnPointerEventObserved( 91 void PointerWatcherEventRouter::OnPointerEventObserved(
57 const ui::PointerEvent& event, 92 const ui::PointerEvent& event,
58 ui::Window* target) { 93 ui::Window* target) {
59 Widget* target_widget = nullptr; 94 Widget* target_widget = nullptr;
60 if (target) { 95 if (target) {
61 ui::Window* window = target; 96 ui::Window* window = target;
62 while (window && !target_widget) { 97 while (window && !target_widget) {
63 target_widget = NativeWidgetMus::GetWidgetForWindow(target); 98 target_widget = NativeWidgetMus::GetWidgetForWindow(target);
64 window = window->parent(); 99 window = window->parent();
65 } 100 }
66 } 101 }
67 102
68 // The mojo input events type converter uses the event root_location field 103 // The mojo input events type converter uses the event root_location field
69 // to store screen coordinates. Screen coordinates really should be returned 104 // to store screen coordinates. Screen coordinates really should be returned
70 // separately. See http://crbug.com/608547 105 // separately. See http://crbug.com/608547
71 gfx::Point location_in_screen = event.AsLocatedEvent()->root_location(); 106 gfx::Point location_in_screen = event.AsLocatedEvent()->root_location();
72 FOR_EACH_OBSERVER( 107 FOR_EACH_OBSERVER(
73 PointerWatcher, pointer_watchers_, 108 PointerWatcher, move_watchers_,
74 OnPointerEventObserved(event, location_in_screen, target_widget)); 109 OnPointerEventObserved(event, location_in_screen, target_widget));
110 if (event.type() != ui::ET_POINTER_MOVED) {
111 FOR_EACH_OBSERVER(
112 PointerWatcher, non_move_watchers_,
113 OnPointerEventObserved(event, location_in_screen, target_widget));
114 }
75 } 115 }
76 116
77 bool PointerWatcherEventRouter::HasPointerWatcher() { 117 PointerWatcherEventRouter::EventTypes
78 // Check to see if we really have any observers left. This doesn't use 118 PointerWatcherEventRouter::DetermineEventTypes() {
79 // base::ObserverList<>::might_have_observers() because that returns true 119 if (HasPointerWatcher(&move_watchers_))
80 // during iteration over the list even when the last observer is removed. 120 return EventTypes::MOVE_EVENTS;
81 base::ObserverList<PointerWatcher>::Iterator iterator(&pointer_watchers_); 121
82 return !!iterator.GetNext(); 122 if (HasPointerWatcher(&non_move_watchers_))
123 return EventTypes::NON_MOVE_EVENTS;
124
125 return EventTypes::NONE;
83 } 126 }
84 127
85 void PointerWatcherEventRouter::OnWindowTreeCaptureChanged( 128 void PointerWatcherEventRouter::OnWindowTreeCaptureChanged(
86 ui::Window* gained_capture, 129 ui::Window* gained_capture,
87 ui::Window* lost_capture) { 130 ui::Window* lost_capture) {
88 FOR_EACH_OBSERVER(PointerWatcher, pointer_watchers_, OnMouseCaptureChanged()); 131 FOR_EACH_OBSERVER(PointerWatcher, move_watchers_, OnMouseCaptureChanged());
132 FOR_EACH_OBSERVER(PointerWatcher, non_move_watchers_,
133 OnMouseCaptureChanged());
89 } 134 }
90 135
91 void PointerWatcherEventRouter::OnDidDestroyClient( 136 void PointerWatcherEventRouter::OnDidDestroyClient(
92 ui::WindowTreeClient* client) { 137 ui::WindowTreeClient* client) {
93 DCHECK(!pointer_watchers_.might_have_observers()); 138 // We expect that all observers have been removed by this time.
139 DCHECK_EQ(event_types_, EventTypes::NONE);
94 DCHECK_EQ(client, window_tree_client_); 140 DCHECK_EQ(client, window_tree_client_);
95 window_tree_client_->RemoveObserver(this); 141 window_tree_client_->RemoveObserver(this);
96 window_tree_client_ = nullptr; 142 window_tree_client_ = nullptr;
97 } 143 }
98 144
99 } // namespace views 145 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/mus/pointer_watcher_event_router.h ('k') | ui/views/mus/pointer_watcher_event_router_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698