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

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: Rebase 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..f5cea4a41c561b0f5fa677ec111e9a21e480731d 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,68 @@ 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;
+
+ // Cancel implicit capture to all other windows.
+ bool observing_window = false;
+ std::set<ServerWindow*> unobserved_windows;
+ if (capture_window_) {
+ delegate_->OnLostCapture(capture_window_);
+ unobserved_windows.insert(capture_window_);
+ capture_window_->RemoveObserver(this);
+ }
+
+ for (const auto& pair : pointer_targets_) {
+ ServerWindow* target = pair.second.window;
+ if (!target)
+ continue;
+ if (target == window) {
+ observing_window = true;
+ } else if (unobserved_windows.insert(target).second) {
sky 2016/01/29 20:47:00 Why do you only send the cancel once per window? I
jonross 2016/02/01 18:52:22 Good catch, I've updated this to send once cancel
+ target->RemoveObserver(this);
+ 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): Do we want to track previous location in PointerTarger
sky 2016/01/29 20:47:00 PointerTarger->PointerTarget And to your TODO, I t
jonross 2016/02/01 18:52:22 Fixed the comment. I agree with storing the last
+ // 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 && !observing_window)
+ window->AddObserver(this);
}
void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
@@ -231,6 +283,14 @@ void EventDispatcher::ProcessKeyEvent(mojom::EventPtr event) {
}
void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
+ if (capture_window_) {
+ PointerTarget pointer_target;
+ pointer_target.window = capture_window_;
+ pointer_target.in_nonclient_area = capture_window_in_nonclient_area_;
+ DispatchToPointerTarget(pointer_target, std::move(event));
+ return;
sky 2016/01/29 20:47:00 The problem with an early return here is mouse_poi
jonross 2016/02/01 18:52:22 I've moved this, and added logic for updating mous
+ }
+
const bool is_mouse_event = event->pointer_data &&
event->pointer_data->kind == mojom::PointerKind::MOUSE;
@@ -380,6 +440,15 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target,
void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
window->RemoveObserver(this);
+ if (capture_window_ == window) {
sky 2016/01/29 20:47:00 When this happens you may need to update the curso
jonross 2016/02/01 18:52:22 Done.
+ 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);
+ return;
+ }
+
for (auto& pair : pointer_targets_) {
if (pair.second.window == window)
pair.second.window = nullptr;

Powered by Google App Engine
This is Rietveld 408576698