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

Unified Diff: services/ui/input_manager/input_dispatcher_impl.cc

Issue 1776473005: Mozart: Implement basic input event dispatch with hit testing. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-7
Patch Set: Created 4 years, 9 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: services/ui/input_manager/input_dispatcher_impl.cc
diff --git a/services/ui/input_manager/input_dispatcher_impl.cc b/services/ui/input_manager/input_dispatcher_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..658b608090380b04b8406d04c5723090d95bced3
--- /dev/null
+++ b/services/ui/input_manager/input_dispatcher_impl.cc
@@ -0,0 +1,129 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/ui/input_manager/input_dispatcher_impl.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/services/geometry/cpp/geometry_util.h"
+#include "mojo/services/gfx/composition/cpp/formatting.h"
+#include "mojo/services/ui/views/cpp/formatting.h"
+#include "services/ui/input_manager/input_associate.h"
+
+namespace input_manager {
+namespace {
+void TransformEvent(const mojo::Transform& transform, mojo::Event* event) {
+ if (!event->pointer_data)
+ return;
+ mojo::Point point;
+ point.x = event->pointer_data->x;
+ point.y = event->pointer_data->y;
+ point = TransformPoint(transform, point);
+ event->pointer_data->x = point.x;
+ event->pointer_data->y = point.y;
+}
+} // namespace
+
+InputDispatcherImpl::InputDispatcherImpl(
+ InputAssociate* associate,
+ mojo::ui::ViewTreeTokenPtr view_tree_token,
+ mojo::InterfaceRequest<mojo::ui::InputDispatcher> request)
+ : associate_(associate),
+ view_tree_token_(view_tree_token.Pass()),
+ hit_tester_(
+ new mojo::ui::ViewTreeHitTesterClient(associate_->inspector(),
+ view_tree_token_.Clone())),
+ binding_(this, request.Pass()),
+ weak_factory_(this) {
+ DCHECK(associate_);
+ DCHECK(view_tree_token_);
+
+ binding_.set_connection_error_handler(
+ base::Bind(&InputAssociate::OnInputDispatcherDied,
+ base::Unretained(associate_), base::Unretained(this)));
+}
+
+InputDispatcherImpl::~InputDispatcherImpl() {}
+
+void InputDispatcherImpl::DispatchEvent(mojo::EventPtr event) {
+ DCHECK(event);
+
+ pending_events_.push(event.Pass());
+ if (pending_events_.size() == 1u)
+ ProcessNextEvent();
+}
+
+void InputDispatcherImpl::ProcessNextEvent() {
+ DCHECK(!pending_events_.empty());
+
+ const mojo::Event* event = pending_events_.front().get();
+ if (event->action != mojo::EventType::POINTER_DOWN) {
+ DeliverNextEvent();
+ return;
+ }
+
+ DCHECK(event->pointer_data);
+ auto point = mojo::Point::New();
+ point->x = event->pointer_data->x;
+ point->y = event->pointer_data->y;
+ DVLOG(1) << "HitTest: point=" << point;
+ hit_tester_->HitTest(point.Pass(),
+ base::Bind(&InputDispatcherImpl::OnHitTestResult,
+ weak_factory_.GetWeakPtr()));
+}
+
+void InputDispatcherImpl::DeliverNextEvent() {
+ DCHECK(!pending_events_.empty());
+
+ mojo::EventPtr event = pending_events_.front().Pass();
+ pending_events_.pop();
+
+ if (focused_view_token_) {
+ TransformEvent(*focused_view_transform_, event.get());
+ associate_->DeliverEvent(focused_view_token_.get(), event.Pass());
+ }
+
+ if (!pending_events_.empty()) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&InputDispatcherImpl::ProcessNextEvent,
+ weak_factory_.GetWeakPtr()));
abarth 2016/03/09 04:17:37 Interesting.
jeffbrown 2016/03/09 19:38:50 This was to prevent reentrance when called from On
+ }
+}
+
+void InputDispatcherImpl::OnHitTestResult(
+ scoped_ptr<mojo::ui::ResolvedHits> resolved_hits) {
+ DVLOG(1) << "OnHitTestResult: resolved_hits=" << resolved_hits.get();
+
+ // TODO(jeffbrown): Flesh out the input protocol so it makes sense to
+ // look at more than the first hit.
+ focused_view_token_.reset();
+ focused_view_transform_.reset();
+ if (resolved_hits && resolved_hits->result()->root) {
+ mojo::gfx::composition::HitTestResultPtr result =
+ resolved_hits->TakeResult();
+ const mojo::gfx::composition::SceneHit* scene = result->root.get();
+ for (;;) {
+ DCHECK(scene->hits.size());
+ if (scene->hits[0]->is_node()) {
+ auto it = resolved_hits->map().find(scene->scene_token->value);
+ if (it != resolved_hits->map().end()) {
+ focused_view_token_ = it->second.Clone();
+ focused_view_transform_ =
+ scene->hits[0]->get_node()->transform.Pass();
+ }
+ break;
+ }
+ DCHECK(scene->hits[0]->is_scene());
+ scene = scene->hits[0]->get_scene().get();
abarth 2016/03/09 04:17:37 I see, you're just delivering to the most specific
jeffbrown 2016/03/09 19:38:50 Acknowledged.
+ }
+ }
+
+ DVLOG(1) << "OnHitTestResult: focused_view_token_=" << focused_view_token_
+ << ", focused_view_transform_=" << focused_view_transform_;
+
+ DeliverNextEvent();
+}
+
+} // namespace input_manager

Powered by Google App Engine
This is Rietveld 408576698