Commit 6531de85 authored by sky's avatar sky Committed by Commit bot

Removes usage of aura::Window from Node

Each Node no longer creates an aura::Window. Instead RootViewManager
creates a single aura::Window that is responsible for drawing the
entire scene. RootViewManager is told when to redraw certain
areas. When RootViewManager needs to paint is paints the whole
tree.

At some point RootViewManager won't creat an aura::Window at all,
instead it'll take to the surface manager and create the frame data
for the scene.

BUG=none
TEST=none
R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/507563002

Cr-Commit-Position: refs/heads/master@{#291901}
parent 61098b92
......@@ -23,8 +23,8 @@ bool DefaultAccessPolicy::CanRemoveNodeFromParent(const Node* node) const {
if (!WasCreatedByThisConnection(node))
return false; // Can only unparent nodes we created.
const Node* parent = node->GetParent();
return IsNodeInRoots(parent) || WasCreatedByThisConnection(parent);
return IsNodeInRoots(node->parent()) ||
WasCreatedByThisConnection(node->parent());
}
bool DefaultAccessPolicy::CanAddNode(const Node* parent,
......
......@@ -5,184 +5,128 @@
#include "mojo/services/view_manager/node.h"
#include "mojo/services/view_manager/node_delegate.h"
#include "ui/aura/window_property.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
DECLARE_WINDOW_PROPERTY_TYPE(mojo::service::Node*);
namespace mojo {
namespace service {
DEFINE_WINDOW_PROPERTY_KEY(Node*, kNodeKey, NULL);
Node::Node(NodeDelegate* delegate, const NodeId& id)
: delegate_(delegate),
id_(id),
window_(this) {
parent_(NULL),
visible_(true) {
DCHECK(delegate); // Must provide a delegate.
window_.set_owned_by_parent(false);
window_.AddObserver(this);
window_.SetProperty(kNodeKey, this);
window_.Init(aura::WINDOW_LAYER_TEXTURED);
// TODO(sky): this likely needs to be false and add a visibility API.
window_.Show();
}
Node::~Node() {
// This is implicitly done during deletion of the window, but we do it here so
// that we're in a known state.
if (window_.parent())
window_.parent()->RemoveChild(&window_);
while (!children_.empty())
children_.front()->parent()->Remove(children_.front());
if (parent_)
parent_->Remove(this);
delegate_->OnNodeDestroyed(this);
}
// static
Node* Node::NodeForWindow(aura::Window* window) {
return window->GetProperty(kNodeKey);
}
void Node::Add(Node* child) {
// We assume validation checks happened already.
DCHECK(child);
DCHECK(child != this);
DCHECK(!child->Contains(this));
if (child->parent() == this) {
if (children_.size() == 1)
return; // Already in the right position.
Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE);
return;
}
const Node* Node::GetParent() const {
if (!window_.parent())
return NULL;
return window_.parent()->GetProperty(kNodeKey);
}
const Node* old_parent = child->parent();
if (child->parent())
child->parent()->RemoveImpl(child);
void Node::Add(Node* child) {
window_.AddChild(&child->window_);
child->parent_ = this;
children_.push_back(child);
child->delegate_->OnNodeHierarchyChanged(child, this, old_parent);
}
void Node::Remove(Node* child) {
window_.RemoveChild(&child->window_);
// We assume validation checks happened else where.
DCHECK(child);
DCHECK(child != this);
DCHECK(child->parent() == this);
RemoveImpl(child);
child->delegate_->OnNodeHierarchyChanged(child, NULL, this);
}
void Node::Reorder(Node* child, Node* relative, OrderDirection direction) {
if (direction == ORDER_DIRECTION_ABOVE)
window_.StackChildAbove(child->window(), relative->window());
else if (direction == ORDER_DIRECTION_BELOW)
window_.StackChildBelow(child->window(), relative->window());
// We assume validation checks happened else where.
DCHECK(child);
DCHECK(child->parent() == this);
DCHECK_GT(children_.size(), 1u);
children_.erase(std::find(children_.begin(), children_.end(), child));
Nodes::iterator i = std::find(children_.begin(), children_.end(), relative);
if (direction == ORDER_DIRECTION_ABOVE) {
DCHECK(i != children_.end());
children_.insert(++i, child);
} else if (direction == ORDER_DIRECTION_BELOW) {
DCHECK(i != children_.end());
children_.insert(i, child);
}
}
void Node::SetBounds(const gfx::Rect& bounds) {
if (bounds_ == bounds)
return;
const gfx::Rect old_bounds = bounds_;
bounds_ = bounds;
delegate_->OnNodeBoundsChanged(this, old_bounds, bounds);
}
const Node* Node::GetRoot() const {
const aura::Window* window = &window_;
while (window && window->parent())
window = window->parent();
return window->GetProperty(kNodeKey);
const Node* node = this;
while (node && node->parent())
node = node->parent();
return node;
}
std::vector<const Node*> Node::GetChildren() const {
std::vector<const Node*> children;
children.reserve(window_.children().size());
for (size_t i = 0; i < window_.children().size(); ++i)
children.push_back(window_.children()[i]->GetProperty(kNodeKey));
children.reserve(children_.size());
for (size_t i = 0; i < children_.size(); ++i)
children.push_back(children_[i]);
return children;
}
std::vector<Node*> Node::GetChildren() {
std::vector<Node*> children;
children.reserve(window_.children().size());
for (size_t i = 0; i < window_.children().size(); ++i)
children.push_back(window_.children()[i]->GetProperty(kNodeKey));
return children;
// TODO(sky): rename to children() and fix return type.
return children_;
}
bool Node::Contains(const Node* node) const {
return node && window_.Contains(&(node->window_));
}
bool Node::IsVisible() const {
return window_.TargetVisibility();
for (const Node* parent = node; parent; parent = parent->parent_) {
if (parent == this)
return true;
}
return false;
}
void Node::SetVisible(bool value) {
if (value)
window_.Show();
else
window_.Hide();
}
void Node::SetBitmap(const SkBitmap& bitmap) {
bitmap_ = bitmap;
window_.SchedulePaintInRect(gfx::Rect(window_.bounds().size()));
}
void Node::OnWindowHierarchyChanged(
const aura::WindowObserver::HierarchyChangeParams& params) {
if (params.target != &window_ || params.receiver != &window_)
if (visible_ == value)
return;
const Node* new_parent = params.new_parent ?
params.new_parent->GetProperty(kNodeKey) : NULL;
const Node* old_parent = params.old_parent ?
params.old_parent->GetProperty(kNodeKey) : NULL;
// This check is needed because even the root Node's aura::Window has a
// parent, but the Node itself has no parent (so it's possible for us to
// receive this notification from aura when no logical Node hierarchy change
// has actually ocurred).
if (new_parent != old_parent)
delegate_->OnNodeHierarchyChanged(this, new_parent, old_parent);
}
gfx::Size Node::GetMinimumSize() const {
return gfx::Size();
}
gfx::Size Node::GetMaximumSize() const {
return gfx::Size();
visible_ = value;
// TODO(sky): notification, including repaint.
}
void Node::OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
delegate_->OnNodeBoundsChanged(this, old_bounds, new_bounds);
}
gfx::NativeCursor Node::GetCursor(const gfx::Point& point) {
return gfx::kNullCursor;
}
int Node::GetNonClientComponent(const gfx::Point& point) const {
return HTCAPTION;
}
bool Node::ShouldDescendIntoChildForEventHandling(
aura::Window* child,
const gfx::Point& location) {
return true;
}
bool Node::CanFocus() {
return true;
}
void Node::OnCaptureLost() {
}
void Node::OnPaint(gfx::Canvas* canvas) {
canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(bitmap_), 0, 0);
}
void Node::OnDeviceScaleFactorChanged(float device_scale_factor) {
}
void Node::OnWindowDestroying(aura::Window* window) {
}
void Node::OnWindowDestroyed(aura::Window* window) {
}
void Node::OnWindowTargetVisibilityChanged(bool visible) {
}
bool Node::HasHitTestMask() const {
return false;
void Node::SetBitmap(const SkBitmap& bitmap) {
bitmap_ = bitmap;
delegate_->OnNodeBitmapChanged(this);
}
void Node::GetHitTestMask(gfx::Path* mask) const {
void Node::RemoveImpl(Node* node) {
node->parent_ = NULL;
children_.erase(std::find(children_.begin(), children_.end(), node));
}
} // namespace service
......
......@@ -12,9 +12,7 @@
#include "mojo/services/view_manager/ids.h"
#include "mojo/services/view_manager/view_manager_export.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/geometry/rect.h"
namespace mojo {
namespace service {
......@@ -22,30 +20,26 @@ namespace service {
class NodeDelegate;
// Represents a node in the graph. Delegate is informed of interesting events.
class MOJO_VIEW_MANAGER_EXPORT Node
: public aura::WindowObserver,
public aura::WindowDelegate {
//
// It is assumed that all functions that mutate the node tree have validated the
// value. For example, Reorder() assumes the supplied node is a child and not
// already in position.
class MOJO_VIEW_MANAGER_EXPORT Node {
public:
Node(NodeDelegate* delegate, const NodeId& id);
virtual ~Node();
static Node* NodeForWindow(aura::Window* window);
const NodeId& id() const { return id_; }
void Add(Node* child);
void Remove(Node* child);
void Reorder(Node* child, Node* relative, OrderDirection direction);
aura::Window* window() { return &window_; }
const gfx::Rect& bounds() const { return window_.bounds(); }
const gfx::Rect& bounds() const { return bounds_; }
void SetBounds(const gfx::Rect& bounds);
const Node* GetParent() const;
Node* GetParent() {
return const_cast<Node*>(const_cast<const Node*>(this)->GetParent());
}
const Node* parent() const { return parent_; }
Node* parent() { return parent_; }
const Node* GetRoot() const;
Node* GetRoot() {
......@@ -59,41 +53,24 @@ class MOJO_VIEW_MANAGER_EXPORT Node
// Returns true if the window is visible. This does not consider visibility
// of any ancestors.
bool IsVisible() const;
bool visible() const { return visible_; }
void SetVisible(bool value);
void SetBitmap(const SkBitmap& contents);
const SkBitmap& bitmap() const { return bitmap_; }
private:
// WindowObserver overrides:
virtual void OnWindowHierarchyChanged(
const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;
// WindowDelegate overrides:
virtual gfx::Size GetMinimumSize() const OVERRIDE;
virtual gfx::Size GetMaximumSize() const OVERRIDE;
virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE;
virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE;
virtual bool ShouldDescendIntoChildForEventHandling(
aura::Window* child,
const gfx::Point& location) OVERRIDE;
virtual bool CanFocus() OVERRIDE;
virtual void OnCaptureLost() OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE;
virtual bool HasHitTestMask() const OVERRIDE;
virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE;
typedef std::vector<Node*> Nodes;
// Implementation of removing a node. Doesn't send any notification.
void RemoveImpl(Node* node);
NodeDelegate* delegate_;
const NodeId id_;
aura::Window window_;
Node* parent_;
Nodes children_;
bool visible_;
gfx::Rect bounds_;
SkBitmap bitmap_;
DISALLOW_COPY_AND_ASSIGN(Node);
......
......@@ -31,6 +31,8 @@ class MOJO_VIEW_MANAGER_EXPORT NodeDelegate {
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) = 0;
virtual void OnNodeBitmapChanged(const Node* node) = 0;
protected:
virtual ~NodeDelegate() {}
};
......
......@@ -252,6 +252,16 @@ void RootNodeManager::OnNodeBoundsChanged(const Node* node,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
ProcessNodeBoundsChanged(node, old_bounds, new_bounds);
if (!node->parent())
return;
// TODO(sky): optimize this.
root_view_manager_.SchedulePaint(node->parent(), old_bounds);
root_view_manager_.SchedulePaint(node->parent(), new_bounds);
}
void RootNodeManager::OnNodeBitmapChanged(const Node* node) {
root_view_manager_.SchedulePaint(node, gfx::Rect(node->bounds().size()));
}
} // namespace service
......
......@@ -176,6 +176,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
virtual void OnNodeBoundsChanged(const Node* node,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
virtual void OnNodeBitmapChanged(const Node* node) OVERRIDE;
Context context_;
......
......@@ -16,10 +16,98 @@
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
namespace mojo {
namespace service {
namespace {
gfx::Rect ConvertRectToRoot(const Node* node, const gfx::Rect& bounds) {
gfx::Point origin(bounds.origin());
while (node->parent()) {
origin += node->bounds().OffsetFromOrigin();
node = node->parent();
}
return gfx::Rect(origin, bounds.size());
}
void PaintNodeTree(gfx::Canvas* canvas,
const Node* node,
const gfx::Point& origin) {
if (!node->visible())
return;
canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(node->bitmap()),
origin.x(), origin.y());
std::vector<const Node*> children(node->GetChildren());
for (size_t i = 0; i < children.size(); ++i) {
PaintNodeTree(canvas, children[i],
origin + children[i]->bounds().OffsetFromOrigin());
}
}
} // namespace
class RootViewManager::RootWindowDelegateImpl : public aura::WindowDelegate {
public:
explicit RootWindowDelegateImpl(const Node* root_node)
: root_node_(root_node) {}
virtual ~RootWindowDelegateImpl() {}
// aura::WindowDelegate:
virtual gfx::Size GetMinimumSize() const OVERRIDE {
return gfx::Size();
}
virtual gfx::Size GetMaximumSize() const OVERRIDE {
return gfx::Size();
}
virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
}
virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
return gfx::kNullCursor;
}
virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
return HTCAPTION;
}
virtual bool ShouldDescendIntoChildForEventHandling(
aura::Window* child,
const gfx::Point& location) OVERRIDE {
return true;
}
virtual bool CanFocus() OVERRIDE {
return true;
}
virtual void OnCaptureLost() OVERRIDE {
}
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
PaintNodeTree(canvas, root_node_, gfx::Point());
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
}
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
}
virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
}
virtual bool HasHitTestMask() const OVERRIDE {
return false;
}
virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {
}
private:
const Node* root_node_;
DISALLOW_COPY_AND_ASSIGN(RootWindowDelegateImpl);
};
// TODO(sky): Remove once aura is removed from the service.
class FocusClientImpl : public aura::client::FocusClient {
......@@ -76,7 +164,8 @@ RootViewManager::RootViewManager(
const Callback<void()>& native_viewport_closed_callback)
: delegate_(delegate),
root_node_manager_(root_node),
in_setup_(false) {
in_setup_(false),
root_window_(NULL) {
screen_.reset(ScreenImpl::Create());
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
NativeViewportPtr viewport;
......@@ -102,14 +191,26 @@ RootViewManager::~RootViewManager() {
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL);
}
void RootViewManager::SchedulePaint(const Node* node, const gfx::Rect& bounds) {
if (root_window_)
root_window_->SchedulePaintInRect(ConvertRectToRoot(node, bounds));
}
void RootViewManager::OnCompositorCreated() {
base::AutoReset<bool> resetter(&in_setup_, true);
window_tree_host_->InitHost();
aura::Window* root = root_node_manager_->root()->window();
window_tree_host_->window()->AddChild(root);
root->SetBounds(gfx::Rect(window_tree_host_->window()->bounds().size()));
root_node_manager_->root()->window()->Show();
window_delegate_.reset(
new RootWindowDelegateImpl(root_node_manager_->root()));
root_window_ = new aura::Window(window_delegate_.get());
root_window_->Init(aura::WINDOW_LAYER_TEXTURED);
root_window_->Show();
root_window_->SetBounds(
gfx::Rect(window_tree_host_->window()->bounds().size()));
window_tree_host_->window()->AddChild(root_window_);
root_node_manager_->root()->SetBounds(
gfx::Rect(window_tree_host_->window()->bounds().size()));
window_tree_client_.reset(
new WindowTreeClientImpl(window_tree_host_->window()));
......
......@@ -12,11 +12,16 @@
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/services/view_manager/view_manager_export.h"
namespace gfx {
class Rect;
}
namespace aura {
namespace client {
class FocusClient;
class WindowTreeClient;
}
class Window;
class WindowTreeHost;
}
......@@ -30,6 +35,7 @@ class ApplicationConnection;
namespace service {
class Node;
class RootNodeManager;
class RootViewManagerDelegate;
......@@ -42,10 +48,15 @@ class MOJO_VIEW_MANAGER_EXPORT RootViewManager {
const Callback<void()>& native_viewport_closed_callback);
virtual ~RootViewManager();
// Schedules a paint for the specified region of the specified node.
void SchedulePaint(const Node* node, const gfx::Rect& bounds);
// See description above field for details.
bool in_setup() const { return in_setup_; }
private:
class RootWindowDelegateImpl;
void OnCompositorCreated();
RootViewManagerDelegate* delegate_;
......@@ -55,6 +66,11 @@ class MOJO_VIEW_MANAGER_EXPORT RootViewManager {
// Returns true if adding the root node's window to |window_tree_host_|.
bool in_setup_;
scoped_ptr<RootWindowDelegateImpl> window_delegate_;
// Owned by its parent aura::Window.
aura::Window* root_window_;
scoped_ptr<gfx::Screen> screen_;
scoped_ptr<aura::WindowTreeHost> window_tree_host_;
scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
......
......@@ -157,14 +157,13 @@ bool ViewManagerServiceImpl::CanReorderNode(const Node* node,
if (!node || !relative_node)
return false;
const Node* parent = node->GetParent();
if (!parent || parent != relative_node->GetParent())
if (!node->parent() || node->parent() != relative_node->parent())
return false;
if (!access_policy_->CanReorderNode(node, relative_node, direction))
return false;
std::vector<const Node*> children = parent->GetChildren();
std::vector<const Node*> children = node->parent()->GetChildren();
const size_t child_i =
std::find(children.begin(), children.end(), node) - children.begin();
const size_t target_i =
......@@ -256,7 +255,7 @@ void ViewManagerServiceImpl::RemoveRoot(const NodeId& node_id) {
std::vector<Node*> local_nodes;
RemoveFromKnown(GetNode(node_id), &local_nodes);
for (size_t i = 0; i < local_nodes.size(); ++i)
local_nodes[i]->GetParent()->Remove(local_nodes[i]);
local_nodes[i]->parent()->Remove(local_nodes[i]);
}
void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
......@@ -279,7 +278,7 @@ Array<ViewDataPtr> ViewManagerServiceImpl::NodesToViewDatas(
ViewDataPtr ViewManagerServiceImpl::NodeToViewData(const Node* node) {
DCHECK(IsNodeKnown(node));
const Node* parent = node->GetParent();
const Node* parent = node->parent();
// If the parent isn't known, it means the parent is not visible to us (not
// in roots), and should not be sent over.
if (parent && !IsNodeKnown(parent))
......@@ -345,7 +344,7 @@ void ViewManagerServiceImpl::AddView(
bool success = false;
Node* parent = GetNode(NodeIdFromTransportId(parent_id));
Node* child = GetNode(NodeIdFromTransportId(child_id));
if (parent && child && child->GetParent() != parent &&
if (parent && child && child->parent() != parent &&
!child->Contains(parent) && access_policy_->CanAddNode(parent, child)) {
success = true;
RootNodeManager::ScopedChange change(this, root_node_manager_, false);
......@@ -359,11 +358,11 @@ void ViewManagerServiceImpl::RemoveViewFromParent(
const Callback<void(bool)>& callback) {
bool success = false;
Node* node = GetNode(NodeIdFromTransportId(view_id));
if (node && node->GetParent() &&
if (node && node->parent() &&
access_policy_->CanRemoveNodeFromParent(node)) {
success = true;
RootNodeManager::ScopedChange change(this, root_node_manager_, false);
node->GetParent()->Remove(node);
node->parent()->Remove(node);
}
callback.Run(success);
}
......@@ -378,7 +377,7 @@ void ViewManagerServiceImpl::ReorderView(Id view_id,
if (CanReorderNode(node, relative_node, direction)) {
success = true;
RootNodeManager::ScopedChange change(this, root_node_manager_, false);
node->GetParent()->Reorder(node, relative_node, direction);
node->parent()->Reorder(node, relative_node, direction);
root_node_manager_->ProcessNodeReorder(node, relative_node, direction);
}
callback.Run(success);
......@@ -429,8 +428,7 @@ void ViewManagerServiceImpl::SetViewBounds(
const bool success = node && access_policy_->CanSetNodeBounds(node);
if (success) {
RootNodeManager::ScopedChange change(this, root_node_manager_, false);
gfx::Rect old_bounds = node->window()->bounds();
node->window()->SetBounds(bounds.To<gfx::Rect>());
node->SetBounds(bounds.To<gfx::Rect>());
}
callback.Run(success);
}
......@@ -440,7 +438,7 @@ void ViewManagerServiceImpl::SetViewVisibility(
bool visible,
const Callback<void(bool)>& callback) {
Node* node = GetNode(NodeIdFromTransportId(transport_view_id));
const bool success = node && node->IsVisible() != visible &&
const bool success = node && node->visible() != visible &&
access_policy_->CanChangeNodeVisibility(node);
if (success) {
DCHECK(node);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment