summaryrefslogtreecommitdiffstats
path: root/mojo/services
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-22 17:13:12 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-22 17:13:12 +0000
commit802e6c55549dcd03d8b6e80a3e3d5358fab33c39 (patch)
tree19876d7d1d43c4e3d4017afff24b2d0a88977c3c /mojo/services
parente2e47e9c92cc282a77231e59066ba7258085a00d (diff)
downloadchromium_src-802e6c55549dcd03d8b6e80a3e3d5358fab33c39.zip
chromium_src-802e6c55549dcd03d8b6e80a3e3d5358fab33c39.tar.gz
chromium_src-802e6c55549dcd03d8b6e80a3e3d5358fab33c39.tar.bz2
SetBounds for ViewTreeNode.
R=sky@chromium.org http://crbug.com/365012 Review URL: https://codereview.chromium.org/287053004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272209 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/services')
-rw-r--r--mojo/services/public/cpp/view_manager/DEPS3
-rw-r--r--mojo/services/public/cpp/view_manager/lib/DEPS5
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc45
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h5
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node.cc49
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h5
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc49
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc80
-rw-r--r--mojo/services/public/cpp/view_manager/util.h8
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_node.h7
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_node_observer.h9
-rw-r--r--mojo/services/public/interfaces/view_manager/view_manager.mojom8
-rw-r--r--mojo/services/view_manager/DEPS1
-rw-r--r--mojo/services/view_manager/root_node_manager.cc10
-rw-r--r--mojo/services/view_manager/root_node_manager.h5
-rw-r--r--mojo/services/view_manager/view_manager_connection.cc39
-rw-r--r--mojo/services/view_manager/view_manager_connection.h11
-rw-r--r--mojo/services/view_manager/view_manager_connection_unittest.cc58
18 files changed, 393 insertions, 4 deletions
diff --git a/mojo/services/public/cpp/view_manager/DEPS b/mojo/services/public/cpp/view_manager/DEPS
new file mode 100644
index 0000000..8ce1d20
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ui/gfx/geometry"
+]
diff --git a/mojo/services/public/cpp/view_manager/lib/DEPS b/mojo/services/public/cpp/view_manager/lib/DEPS
index 2661b64..a3f6c8f 100644
--- a/mojo/services/public/cpp/view_manager/lib/DEPS
+++ b/mojo/services/public/cpp/view_manager/lib/DEPS
@@ -1,3 +1,8 @@
+include_rules = [
+ "+mojo/geometry",
+ "+ui/gfx/geometry"
+]
+
specific_include_rules = {
"view_manager_test_suite.cc": [
"+ui/gl",
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
index 8eea829..76a6b52 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
@@ -99,7 +99,9 @@ class ViewManagerTransaction {
// parent.)
TYPE_HIERARCHY,
// View replacement.
- TYPE_SET_ACTIVE_VIEW
+ TYPE_SET_ACTIVE_VIEW,
+ // Node bounds.
+ TYPE_SET_BOUNDS
};
ViewManagerTransaction(TransactionType transaction_type,
@@ -305,6 +307,32 @@ class SetActiveViewTransaction : public ViewManagerTransaction {
DISALLOW_COPY_AND_ASSIGN(SetActiveViewTransaction);
};
+class SetBoundsTransaction : public ViewManagerTransaction {
+ public:
+ SetBoundsTransaction(TransportNodeId node_id,
+ const gfx::Rect& bounds,
+ ViewManagerSynchronizer* synchronizer)
+ : ViewManagerTransaction(TYPE_SET_BOUNDS, synchronizer),
+ node_id_(node_id),
+ bounds_(bounds) {}
+ virtual ~SetBoundsTransaction() {}
+
+ private:
+ // Overridden from ViewManagerTransaction:
+ virtual void DoCommit() OVERRIDE {
+ AllocationScope scope;
+ service()->SetNodeBounds(node_id_, bounds_, ActionCompletedCallback());
+ }
+ virtual void DoActionCompleted(bool success) OVERRIDE {
+ // TODO(beng): recovery?
+ }
+
+ const TransportNodeId node_id_;
+ const gfx::Rect bounds_;
+
+ DISALLOW_COPY_AND_ASSIGN(SetBoundsTransaction);
+};
+
ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
: view_manager_(view_manager),
connected_(false),
@@ -399,6 +427,14 @@ void ViewManagerSynchronizer::SetActiveView(TransportNodeId node_id,
Sync();
}
+void ViewManagerSynchronizer::SetBounds(TransportNodeId node_id,
+ const gfx::Rect& bounds) {
+ DCHECK(connected_);
+ pending_transactions_.push_back(
+ new SetBoundsTransaction(node_id, bounds, this));
+ Sync();
+}
+
////////////////////////////////////////////////////////////////////////////////
// ViewManagerSynchronizer, IViewManagerClient implementation:
@@ -423,6 +459,13 @@ void ViewManagerSynchronizer::OnServerChangeIdAdvanced(
next_server_change_id_ = next_server_change_id;
}
+void ViewManagerSynchronizer::OnNodeBoundsChanged(uint32 node_id,
+ const Rect& old_bounds,
+ const Rect& new_bounds) {
+ ViewTreeNode* node = view_manager_->GetNodeById(node_id);
+ ViewTreeNodePrivate(node).LocalSetBounds(old_bounds, new_bounds);
+}
+
void ViewManagerSynchronizer::OnNodeHierarchyChanged(
uint32_t node_id,
uint32_t new_parent_id,
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
index 7a82a44..5e5c79f 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
@@ -9,6 +9,7 @@
#include "base/callback.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
+#include "mojo/geometry/geometry_type_converters.h"
#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
@@ -48,6 +49,7 @@ class ViewManagerSynchronizer : public IViewManagerClient {
bool OwnsView(TransportViewId id) const;
void SetActiveView(TransportNodeId node_id, TransportViewId view_id);
+ void SetBounds(TransportNodeId node_id, const gfx::Rect& bounds);
void set_changes_acked_callback(const base::Callback<void(void)>& callback) {
changes_acked_callback_ = callback;
@@ -67,6 +69,9 @@ class ViewManagerSynchronizer : public IViewManagerClient {
const mojo::Array<INode>& nodes) OVERRIDE;
virtual void OnServerChangeIdAdvanced(
uint32_t next_server_change_id) OVERRIDE;
+ virtual void OnNodeBoundsChanged(uint32 node_id,
+ const Rect& old_bounds,
+ const Rect& new_bounds) OVERRIDE;
virtual void OnNodeHierarchyChanged(
uint32 node_id,
uint32 new_parent_id,
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
index e501ea6..66331a7 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
@@ -124,6 +124,40 @@ class ScopedSetActiveViewNotifier {
DISALLOW_COPY_AND_ASSIGN(ScopedSetActiveViewNotifier);
};
+class ScopedSetBoundsNotifier {
+ public:
+ ScopedSetBoundsNotifier(ViewTreeNode* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds)
+ : node_(node),
+ old_bounds_(old_bounds),
+ new_bounds_(new_bounds) {
+ FOR_EACH_OBSERVER(
+ ViewTreeNodeObserver,
+ *ViewTreeNodePrivate(node_).observers(),
+ OnNodeBoundsChange(node_,
+ old_bounds_,
+ new_bounds_,
+ ViewTreeNodeObserver::DISPOSITION_CHANGING));
+ }
+ ~ScopedSetBoundsNotifier() {
+ FOR_EACH_OBSERVER(
+ ViewTreeNodeObserver,
+ *ViewTreeNodePrivate(node_).observers(),
+ OnNodeBoundsChange(node_,
+ old_bounds_,
+ new_bounds_,
+ ViewTreeNodeObserver::DISPOSITION_CHANGED));
+ }
+
+ private:
+ ViewTreeNode* node_;
+ const gfx::Rect old_bounds_;
+ const gfx::Rect new_bounds_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier);
+};
+
class ScopedDestructionNotifier {
public:
explicit ScopedDestructionNotifier(ViewTreeNode* node)
@@ -159,6 +193,7 @@ ViewTreeNode* ViewTreeNode::Create(ViewManager* view_manager) {
}
void ViewTreeNode::Destroy() {
+ // TODO(beng): only proceed if |manager_| OwnsNode(this).
if (manager_)
ViewManagerPrivate(manager_).synchronizer()->DestroyViewTreeNode(id_);
while (!children_.empty())
@@ -166,6 +201,13 @@ void ViewTreeNode::Destroy() {
LocalDestroy();
}
+void ViewTreeNode::SetBounds(const gfx::Rect& bounds) {
+ // TODO(beng): only proceed if |manager_| OwnsNode(this).
+ if (manager_)
+ ViewManagerPrivate(manager_).synchronizer()->SetBounds(id_, bounds);
+ LocalSetBounds(bounds_, bounds);
+}
+
void ViewTreeNode::AddObserver(ViewTreeNodeObserver* observer) {
observers_.AddObserver(observer);
}
@@ -276,6 +318,13 @@ void ViewTreeNode::LocalSetActiveView(View* view) {
ViewPrivate(active_view_).set_node(this);
}
+void ViewTreeNode::LocalSetBounds(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ DCHECK(old_bounds == bounds_);
+ ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds);
+ bounds_ = new_bounds;
+}
+
} // namespace view_manager
} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
index ab2daaf..ec825d8 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
@@ -39,10 +39,13 @@ class ViewTreeNodePrivate {
void LocalRemoveChild(ViewTreeNode* child) {
node_->LocalRemoveChild(child);
}
-
void LocalSetActiveView(View* view) {
node_->LocalSetActiveView(view);
}
+ void LocalSetBounds(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ node_->LocalSetBounds(old_bounds, new_bounds);
+ }
private:
ViewTreeNode* node_;
diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
index f86820a..d28dca2 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
@@ -18,6 +18,7 @@
namespace mojo {
namespace view_manager {
+namespace {
base::RunLoop* current_run_loop = NULL;
@@ -72,6 +73,36 @@ void WaitForActiveViewToChange(ViewTreeNode* node) {
node->RemoveObserver(&observer);
}
+class BoundsChangeObserver : public ViewTreeNodeObserver {
+ public:
+ explicit BoundsChangeObserver(ViewTreeNode* node) : node_(node) {}
+ virtual ~BoundsChangeObserver() {}
+
+ private:
+ // Overridden from ViewTreeNodeObserver:
+ virtual void OnNodeBoundsChange(ViewTreeNode* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ DispositionChangePhase phase) OVERRIDE {
+ DCHECK_EQ(node, node_);
+ if (phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
+ return;
+ QuitRunLoop();
+ }
+
+ ViewTreeNode* node_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
+};
+
+// Wait until the bounds of the supplied node change.
+void WaitForBoundsToChange(ViewTreeNode* node) {
+ BoundsChangeObserver observer(node);
+ node->AddObserver(&observer);
+ DoRunLoop();
+ node->RemoveObserver(&observer);
+}
+
// Spins a runloop until the tree beginning at |root| has |tree_size| nodes
// (including |root|).
class TreeSizeMatchesObserver : public ViewTreeNodeObserver {
@@ -185,6 +216,8 @@ void WaitForDestruction(ViewManager* view_manager,
DoRunLoop();
}
+} // namespace
+
// ViewManager -----------------------------------------------------------------
// These tests model synchronization of two peer connections to the view manager
@@ -528,5 +561,21 @@ TEST_F(ViewManagerTest, MapSubtreeOnAttach) {
EXPECT_EQ(view11_2, node11_2->active_view());
}
+// Verifies that bounds changes applied to a node hierarchy in one connection
+// are reflected to another.
+TEST_F(ViewManagerTest, SetBounds) {
+ ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
+ WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
+
+ ViewTreeNode* node1_2 = view_manager_2()->GetNodeById(node1->id());
+ EXPECT_EQ(node1->bounds(), node1_2->bounds());
+
+ node1->SetBounds(gfx::Rect(0, 0, 100, 100));
+ WaitForBoundsToChange(node1_2);
+ EXPECT_EQ(node1->bounds(), node1_2->bounds());
+
+
+}
+
} // namespace view_manager
} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
index 2f4ec3e..b548690 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
@@ -5,7 +5,9 @@
#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
+#include "mojo/services/public/cpp/view_manager/util.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,7 +21,9 @@ typedef testing::Test ViewTreeNodeTest;
// Subclass with public ctor/dtor.
class TestViewTreeNode : public ViewTreeNode {
public:
- TestViewTreeNode() {}
+ TestViewTreeNode() {
+ ViewTreeNodePrivate(this).set_id(1);
+ }
~TestViewTreeNode() {}
private:
@@ -342,5 +346,79 @@ TEST_F(ViewTreeNodeObserverTest, TreeChange_Reparent) {
EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
}
+namespace {
+
+typedef std::vector<std::string> Changes;
+
+std::string NodeIdToString(TransportNodeId id) {
+ return (id == 0) ? "null" :
+ base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
+}
+
+std::string RectToString(const gfx::Rect& rect) {
+ return base::StringPrintf("%d,%d %dx%d",
+ rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+std::string PhaseToString(ViewTreeNodeObserver::DispositionChangePhase phase) {
+ return phase == ViewTreeNodeObserver::DISPOSITION_CHANGING ?
+ "changing" : "changed";
+}
+
+class BoundsChangeObserver : public ViewTreeNodeObserver {
+ public:
+ explicit BoundsChangeObserver(ViewTreeNode* node) : node_(node) {
+ node_->AddObserver(this);
+ }
+ virtual ~BoundsChangeObserver() {
+ node_->RemoveObserver(this);
+ }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes.swap(changes_);
+ return changes;
+ }
+
+ private:
+ // Overridden from ViewTreeNodeObserver:
+ virtual void OnNodeBoundsChange(ViewTreeNode* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ DispositionChangePhase phase) OVERRIDE {
+ changes_.push_back(
+ base::StringPrintf(
+ "node=%s old_bounds=%s new_bounds=%s phase=%s",
+ NodeIdToString(node->id()).c_str(),
+ RectToString(old_bounds).c_str(),
+ RectToString(new_bounds).c_str(),
+ PhaseToString(phase).c_str()));
+ }
+
+ ViewTreeNode* node_;
+ Changes changes_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
+};
+
+} // namespace
+
+TEST_F(ViewTreeNodeObserverTest, SetBounds) {
+ TestViewTreeNode v1;
+ {
+ BoundsChangeObserver observer(&v1);
+ v1.SetBounds(gfx::Rect(0, 0, 100, 100));
+
+ Changes changes = observer.GetAndClearChanges();
+ EXPECT_EQ(2U, changes.size());
+ EXPECT_EQ(
+ "node=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing",
+ changes[0]);
+ EXPECT_EQ(
+ "node=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed",
+ changes[1]);
+ }
+}
+
} // namespace view_manager
} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/util.h b/mojo/services/public/cpp/view_manager/util.h
index 1c85035..87382e2 100644
--- a/mojo/services/public/cpp/view_manager/util.h
+++ b/mojo/services/public/cpp/view_manager/util.h
@@ -7,6 +7,14 @@
#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
+// TODO(beng): #$*&@#(@ MacOSX SDK!
+#if defined(HiWord)
+#undef HiWord
+#endif
+#if defined(LoWord)
+#undef LoWord
+#endif
+
namespace mojo {
namespace view_manager {
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node.h b/mojo/services/public/cpp/view_manager/view_tree_node.h
index 695b450..a5d9b36 100644
--- a/mojo/services/public/cpp/view_manager/view_tree_node.h
+++ b/mojo/services/public/cpp/view_manager/view_tree_node.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
+#include "ui/gfx/geometry/rect.h"
namespace mojo {
namespace view_manager {
@@ -34,6 +35,10 @@ class ViewTreeNode {
// Configuration.
TransportNodeId id() const { return id_; }
+ // Geometric disposition.
+ const gfx::Rect& bounds() { return bounds_; }
+ void SetBounds(const gfx::Rect& bounds);
+
// Observation.
void AddObserver(ViewTreeNodeObserver* observer);
void RemoveObserver(ViewTreeNodeObserver* observer);
@@ -68,6 +73,7 @@ class ViewTreeNode {
void LocalAddChild(ViewTreeNode* child);
void LocalRemoveChild(ViewTreeNode* child);
void LocalSetActiveView(View* view);
+ void LocalSetBounds(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds);
ViewManager* manager_;
TransportNodeId id_;
@@ -76,6 +82,7 @@ class ViewTreeNode {
ObserverList<ViewTreeNodeObserver> observers_;
+ gfx::Rect bounds_;
View* active_view_;
DISALLOW_COPY_AND_ASSIGN(ViewTreeNode);
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node_observer.h b/mojo/services/public/cpp/view_manager/view_tree_node_observer.h
index 461d29d..116e156 100644
--- a/mojo/services/public/cpp/view_manager/view_tree_node_observer.h
+++ b/mojo/services/public/cpp/view_manager/view_tree_node_observer.h
@@ -9,6 +9,10 @@
#include "base/basictypes.h"
+namespace gfx {
+class Rect;
+}
+
namespace mojo {
namespace view_manager {
@@ -41,6 +45,11 @@ class ViewTreeNodeObserver {
View* new_view,
DispositionChangePhase phase) {}
+ virtual void OnNodeBoundsChange(ViewTreeNode* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ DispositionChangePhase phase) {}
+
protected:
virtual ~ViewTreeNodeObserver() {}
};
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
index 39748a1..7e0f9f7 100644
--- a/mojo/services/public/interfaces/view_manager/view_manager.mojom
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import "../../../../public/interfaces/geometry/geometry.mojom"
+
module mojo.view_manager {
struct INode {
@@ -33,6 +35,9 @@ interface IViewManager {
// delete it.
DeleteNode(uint32 node_id) => (bool success);
+ // Sets the specified bounds of the specified node.
+ SetNodeBounds(uint32 node_id, mojo.Rect bounds) => (bool success);
+
// Reparents a node. See description above class for details of |change_id|.
// This fails for any of the following reasons:
// . |server_change_id| is not the expected id.
@@ -108,6 +113,9 @@ interface IViewManagerClient {
// OnServerChangeIdAdvanced().
OnServerChangeIdAdvanced(uint32 next_server_change_id);
+ // Invoked when a node's bounds have changed.
+ OnNodeBoundsChanged(uint32 node, mojo.Rect old_bounds, mojo.Rect new_bounds);
+
// Invoked when a change is done to the hierarchy. A value of 0 is used to
// identify a null node. For example, if the old_parent is NULL, 0 is
// supplied. See description above ViewManager for details on the change ids.
diff --git a/mojo/services/view_manager/DEPS b/mojo/services/view_manager/DEPS
index 248384f..81d1c97 100644
--- a/mojo/services/view_manager/DEPS
+++ b/mojo/services/view_manager/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+mojo/aura",
+ "+mojo/geometry",
"+mojo/services",
"+third_party/skia",
"+ui/aura",
diff --git a/mojo/services/view_manager/root_node_manager.cc b/mojo/services/view_manager/root_node_manager.cc
index 791576e..710839b 100644
--- a/mojo/services/view_manager/root_node_manager.cc
+++ b/mojo/services/view_manager/root_node_manager.cc
@@ -81,6 +81,16 @@ View* RootNodeManager::GetView(const ViewId& id) {
return i == connection_map_.end() ? NULL : i->second->GetView(id);
}
+void RootNodeManager::ProcessNodeBoundsChanged(const Node* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ for (ConnectionMap::iterator i = connection_map_.begin();
+ i != connection_map_.end(); ++i) {
+ i->second->ProcessNodeBoundsChanged(node, old_bounds, new_bounds,
+ IsChangeSource(i->first));
+ }
+}
+
void RootNodeManager::ProcessNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) {
diff --git a/mojo/services/view_manager/root_node_manager.h b/mojo/services/view_manager/root_node_manager.h
index 75ad4e0..1163ca1 100644
--- a/mojo/services/view_manager/root_node_manager.h
+++ b/mojo/services/view_manager/root_node_manager.h
@@ -82,6 +82,9 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
// These functions trivially delegate to all ViewManagerConnections, which in
// term notify their clients.
+ void ProcessNodeBoundsChanged(const Node* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds);
void ProcessNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent);
@@ -116,7 +119,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
return connection_id == change_source_;
}
- // Overriden from NodeDelegate:
+ // Overridden from NodeDelegate:
virtual void OnNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) OVERRIDE;
diff --git a/mojo/services/view_manager/view_manager_connection.cc b/mojo/services/view_manager/view_manager_connection.cc
index bb9c4de..e8ce02c 100644
--- a/mojo/services/view_manager/view_manager_connection.cc
+++ b/mojo/services/view_manager/view_manager_connection.cc
@@ -5,6 +5,7 @@
#include "mojo/services/view_manager/view_manager_connection.h"
#include "base/stl_util.h"
+#include "mojo/geometry/geometry_type_converters.h"
#include "mojo/public/cpp/bindings/allocation_scope.h"
#include "mojo/services/view_manager/node.h"
#include "mojo/services/view_manager/root_node_manager.h"
@@ -99,6 +100,20 @@ const View* ViewManagerConnection::GetView(const ViewId& id) const {
return root_node_manager_->GetView(id);
}
+void ViewManagerConnection::ProcessNodeBoundsChanged(
+ const Node* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ bool originated_change) {
+ if (originated_change)
+ return;
+ TransportNodeId node_id = NodeIdToTransportId(node->id());
+ if (known_nodes_.count(node_id) > 0) {
+ AllocationScope scope;
+ client()->OnNodeBoundsChanged(node_id, old_bounds, new_bounds);
+ }
+}
+
void ViewManagerConnection::ProcessNodeHierarchyChanged(
const Node* node,
const Node* new_parent,
@@ -582,6 +597,30 @@ void ViewManagerConnection::SetRoots(
connection->ProcessSetRoots(id_, transport_node_ids));
}
+void ViewManagerConnection::SetNodeBounds(
+ TransportNodeId node_id,
+ const Rect& bounds,
+ const Callback<void(bool)>& callback) {
+ if (NodeIdFromTransportId(node_id).connection_id != id_) {
+ callback.Run(false);
+ return;
+ }
+
+ Node* node = GetNode(NodeIdFromTransportId(node_id));
+ if (!node) {
+ callback.Run(false);
+ return;
+ }
+
+ RootNodeManager::ScopedChange change(
+ this, root_node_manager_,
+ RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false);
+ gfx::Rect old_bounds = node->window()->bounds();
+ node->window()->SetBounds(bounds);
+ root_node_manager_->ProcessNodeBoundsChanged(node, old_bounds, bounds);
+ callback.Run(true);
+}
+
void ViewManagerConnection::OnNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) {
diff --git a/mojo/services/view_manager/view_manager_connection.h b/mojo/services/view_manager/view_manager_connection.h
index 7aae7d8..5653ac5 100644
--- a/mojo/services/view_manager/view_manager_connection.h
+++ b/mojo/services/view_manager/view_manager_connection.h
@@ -16,6 +16,10 @@
#include "mojo/services/view_manager/node_delegate.h"
#include "mojo/services/view_manager/view_manager_export.h"
+namespace gfx {
+class Rect;
+}
+
namespace mojo {
namespace view_manager {
namespace service {
@@ -60,6 +64,10 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
// The following methods are invoked after the corresponding change has been
// processed. They do the appropriate bookkeeping and update the client as
// necessary.
+ void ProcessNodeBoundsChanged(const Node* node,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ bool originated_change);
void ProcessNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent,
@@ -157,6 +165,9 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
TransportConnectionId connection_id,
const Array<TransportNodeId>& transport_node_ids,
const Callback<void(bool)>& callback) OVERRIDE;
+ virtual void SetNodeBounds(TransportNodeId node_id,
+ const Rect& bounds,
+ const Callback<void(bool)>& callback) OVERRIDE;
// Overridden from NodeDelegate:
virtual void OnNodeHierarchyChanged(const Node* node,
diff --git a/mojo/services/view_manager/view_manager_connection_unittest.cc b/mojo/services/view_manager/view_manager_connection_unittest.cc
index 56ab6a3..56caa8b 100644
--- a/mojo/services/view_manager/view_manager_connection_unittest.cc
+++ b/mojo/services/view_manager/view_manager_connection_unittest.cc
@@ -11,6 +11,7 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "mojo/common/common_type_converters.h"
+#include "mojo/geometry/geometry_type_converters.h"
#include "mojo/public/cpp/bindings/allocation_scope.h"
#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/cpp/shell/connect.h"
@@ -19,6 +20,7 @@
#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
#include "mojo/shell/shell_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/rect.h"
namespace mojo {
@@ -60,6 +62,15 @@ std::string NodeIdToString(TransportNodeId id) {
base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
}
+// Converts |rect| into a string.
+std::string RectToString(const Rect& rect) {
+ return base::StringPrintf("%d,%d %dx%d",
+ rect.position().x(),
+ rect.position().y(),
+ rect.size().width(),
+ rect.size().height());
+}
+
// Boolean callback. Sets |result_cache| to the value of |result| and quits
// the run loop.
void BooleanCallback(bool* result_cache, bool result) {
@@ -139,6 +150,16 @@ bool DeleteView(IViewManager* view_manager, TransportViewId view_id) {
return result;
}
+bool SetNodeBounds(IViewManager* view_manager,
+ TransportNodeId node_id,
+ const gfx::Rect& bounds) {
+ bool result = false;
+ view_manager->SetNodeBounds(node_id, bounds,
+ base::Bind(&BooleanCallback, &result));
+ DoRunLoop();
+ return result;
+}
+
// Adds a node, blocking until done.
bool AddNode(IViewManager* view_manager,
TransportNodeId parent,
@@ -270,6 +291,17 @@ class ViewManagerClientImpl : public IViewManagerClient {
static_cast<int>(next_server_change_id)));
QuitIfNecessary();
}
+ virtual void OnNodeBoundsChanged(TransportNodeId node_id,
+ const Rect& old_bounds,
+ const Rect& new_bounds) OVERRIDE {
+ changes_.push_back(
+ base::StringPrintf(
+ "BoundsChanged node=%s old_bounds=%s new_bounds=%s",
+ NodeIdToString(node_id).c_str(),
+ RectToString(old_bounds).c_str(),
+ RectToString(new_bounds).c_str()));
+ QuitIfNecessary();
+ }
virtual void OnNodeHierarchyChanged(
TransportNodeId node,
TransportNodeId new_parent,
@@ -1146,6 +1178,32 @@ TEST_F(ViewManagerConnectionTest, GetNodeTree) {
}
}
+TEST_F(ViewManagerConnectionTest, SetNodeBounds) {
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
+ ASSERT_TRUE(AddNode(view_manager_.get(),
+ CreateNodeId(0, 1),
+ CreateNodeId(1, 1),
+ 1));
+ EstablishSecondConnection();
+
+ AllocationScope scope;
+ ASSERT_TRUE(SetNodeBounds(view_manager_.get(),
+ CreateNodeId(1, 1),
+ gfx::Rect(0, 0, 100, 100)));
+
+ client2_.DoRunLoopUntilChangesCount(1);
+ Changes changes(client2_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("BoundsChanged node=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100",
+ changes[0]);
+
+ // Should not be possible to change the bounds of a node created by another
+ // connection.
+ ASSERT_FALSE(SetNodeBounds(view_manager2_.get(),
+ CreateNodeId(1, 1),
+ gfx::Rect(0, 0, 0, 0)));
+}
+
// Various assertions around SetRoots.
TEST_F(ViewManagerConnectionTest, SetRoots) {
// Create 1, 2, and 3 in the first connection.