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

Unified Diff: components/mus/ws/event_dispatcher.cc

Issue 1605773004: mus: Implement Window Server Capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: components/mus/ws/event_dispatcher.cc
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 24f968030bbc65903eab3517bdcd458dbb70c57f..d943715ff26f8641ddd4d8e24923b6497538d757 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -6,6 +6,7 @@
#include <set>
+#include "base/time/time.h"
#include "cc/surfaces/surface_hittest.h"
#include "components/mus/surfaces/surfaces_state.h"
#include "components/mus/ws/event_dispatcher_delegate.h"
@@ -157,17 +158,66 @@ class EventMatcher {
EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
: delegate_(delegate),
root_(nullptr),
+ capture_window_(nullptr),
+ capture_window_in_nonclient_area_(false),
mouse_button_down_(false),
mouse_cursor_source_window_(nullptr) {}
EventDispatcher::~EventDispatcher() {
std::set<ServerWindow*> pointer_targets;
+ if (capture_window_) {
+ pointer_targets.insert(capture_window_);
+ capture_window_->RemoveObserver(this);
+ capture_window_ = nullptr;
+ }
for (const auto& pair : pointer_targets_) {
if (pair.second.window &&
pointer_targets.insert(pair.second.window).second) {
pair.second.window->RemoveObserver(this);
}
}
+ pointer_targets_.clear();
+}
+
+void EventDispatcher::SetCaptureWindow(ServerWindow* window,
+ bool in_nonclient_area) {
+ if (window == capture_window_)
+ return;
+
+ if (capture_window_) {
+ // Stop observing old capture window. |pointer_targets_| are cleared on
+ // intial setting of a capture window.
+ delegate_->OnLostCapture(capture_window_);
+ capture_window_->RemoveObserver(this);
+ } else {
+ // Cancel implicit capture to all other windows.
+ std::set<ServerWindow*> unobserved_windows;
+ for (const auto& pair : pointer_targets_) {
+ ServerWindow* target = pair.second.window;
+ if (!target)
+ continue;
+ if (unobserved_windows.insert(target).second)
+ target->RemoveObserver(this);
+ if (target == window)
+ continue;
+ mojom::EventPtr cancel_event = mojom::Event::New();
+ cancel_event->action = mojom::EventType::POINTER_CANCEL;
+ cancel_event->flags = mojom::kEventFlagNone;
+ cancel_event->time_stamp = base::TimeTicks::Now().ToInternalValue();
+ cancel_event->pointer_data = mojom::PointerData::New();
+ // TODO(jonross): Track previous location in PointerTarget for sending
+ // cancels
+ cancel_event->pointer_data->location = mojom::LocationData::New();
+ cancel_event->pointer_data->pointer_id = pair.first;
+ DispatchToPointerTarget(pair.second, std::move(cancel_event));
+ }
+ pointer_targets_.clear();
+ }
+ capture_window_ = window;
+ capture_window_in_nonclient_area_ = in_nonclient_area;
+ // Begin tracking the capture window if it is not yet being observed.
+ if (window)
+ window->AddObserver(this);
}
void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
@@ -237,6 +287,16 @@ void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
if (is_mouse_event)
mouse_pointer_last_location_ = EventLocationToPoint(*event);
+ if (capture_window_) {
+ PointerTarget pointer_target;
+ pointer_target.window = capture_window_;
+ pointer_target.in_nonclient_area = capture_window_in_nonclient_area_;
+ mouse_button_down_ = event->action == mojom::EventType::POINTER_DOWN;
sky 2016/02/01 20:43:33 This isn't right. For setting to true you want to
jonross 2016/02/03 18:52:17 Yeah I was mistaken here. Done.
+ mouse_cursor_source_window_ = capture_window_;
+ DispatchToPointerTarget(pointer_target, std::move(event));
+ return;
+ }
+
const int32_t pointer_id = event->pointer_data->pointer_id;
if (!IsTrackingPointer(pointer_id) ||
!pointer_targets_[pointer_id].is_pointer_down) {
@@ -271,9 +331,7 @@ void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
// before we perform dispatch because the Delegate is going to read this
// information from us.
mouse_button_down_ = false;
- gfx::Point location(EventLocationToPoint(*event));
- mouse_cursor_source_window_ =
- FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
+ UpdateCursorProviderByLastKnownLocation();
}
DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event));
@@ -380,6 +438,17 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target,
void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
window->RemoveObserver(this);
+ if (capture_window_ == window) {
+ capture_window_ = nullptr;
+ // A window only cares to be informed that it lost capture if it explicitly
+ // requested capture. A window can lose capture if another window gains
+ // explicit capture.
+ delegate_->OnLostCapture(window);
+ mouse_button_down_ = false;
+ UpdateCursorProviderByLastKnownLocation();
+ return;
+ }
+
for (auto& pair : pointer_targets_) {
if (pair.second.window == window)
pair.second.window = nullptr;

Powered by Google App Engine
This is Rietveld 408576698