summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/workspace/managed_workspace.h2
-rw-r--r--ui/aura/test/test_windows.cc12
-rw-r--r--ui/aura/test/test_windows.h8
-rw-r--r--ui/aura/window.cc85
-rw-r--r--ui/aura/window.h23
-rw-r--r--ui/aura/window_unittest.cc45
-rw-r--r--ui/views/widget/native_widget_aura.cc5
-rw-r--r--ui/views/widget/native_widget_aura.h1
-rw-r--r--ui/views/widget/native_widget_gtk.cc4
-rw-r--r--ui/views/widget/native_widget_gtk.h1
-rw-r--r--ui/views/widget/native_widget_private.h1
-rw-r--r--ui/views/widget/native_widget_win.cc4
-rw-r--r--ui/views/widget/native_widget_win.h1
-rw-r--r--ui/views/widget/widget.cc4
-rw-r--r--ui/views/widget/widget.h3
15 files changed, 154 insertions, 45 deletions
diff --git a/ash/wm/workspace/managed_workspace.h b/ash/wm/workspace/managed_workspace.h
index bf167ee..3b77c12 100644
--- a/ash/wm/workspace/managed_workspace.h
+++ b/ash/wm/workspace/managed_workspace.h
@@ -33,4 +33,4 @@ class ASH_EXPORT ManagedWorkspace : public Workspace {
} // namespace internal
} // namespace ash
-#endif // ASH_WM_WORKPSACE_MANAGED_WORKSPACE_H_
+#endif // ASH_WM_WORKSPACE_MANAGED_WORKSPACE_H_
diff --git a/ui/aura/test/test_windows.cc b/ui/aura/test/test_windows.cc
index 14fd638..3f2390b 100644
--- a/ui/aura/test/test_windows.cc
+++ b/ui/aura/test/test_windows.cc
@@ -4,6 +4,7 @@
#include "ui/aura/test/test_windows.h"
+#include "base/string_number_conversions.h"
#include "ui/aura/window.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/rect.h"
@@ -84,5 +85,16 @@ bool LayerIsAbove(Window* upper, Window* lower) {
return ObjectIsAbove<ui::Layer>(upper->layer(), lower->layer());
}
+std::string ChildWindowIDsAsString(aura::Window* parent) {
+ std::string result;
+ for (Window::Windows::const_iterator i = parent->children().begin();
+ i != parent->children().end(); ++i) {
+ if (!result.empty())
+ result += " ";
+ result += base::IntToString((*i)->id());
+ }
+ return result;
+}
+
} // namespace test
} // namespace aura
diff --git a/ui/aura/test/test_windows.h b/ui/aura/test/test_windows.h
index d0b782d..e0ca117 100644
--- a/ui/aura/test/test_windows.h
+++ b/ui/aura/test/test_windows.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,8 @@
#define UI_AURA_TEST_TEST_WINDOWS_H_
#pragma once
+#include <string>
+
#include "base/compiler_specific.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/client/window_types.h"
@@ -41,6 +43,10 @@ bool WindowIsAbove(Window* upper, Window* lower);
// stacking order.
bool LayerIsAbove(Window* upper, Window* lower);
+// Returns a string containing the id of each of the child windows (bottommost
+// first) of |parent|. The format of the string is "id1 id2 id...".
+std::string ChildWindowIDsAsString(aura::Window* parent);
+
} // namespace test
} // namespace aura
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index facec39..71fedda 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -255,35 +255,11 @@ void Window::StackChildAtTop(Window* child) {
}
void Window::StackChildAbove(Window* child, Window* target) {
- DCHECK_NE(child, target);
- DCHECK(child);
- DCHECK(target);
- DCHECK_EQ(this, child->parent());
- DCHECK_EQ(this, target->parent());
-
- const size_t target_i =
- std::find(children_.begin(), children_.end(), target) - children_.begin();
-
- // By convention we don't stack on top of windows with layers with NULL
- // delegates. Walk backward to find a valid target window.
- // See tests WindowTest.StackingMadrigal and StackOverClosingTransient
- // for an explanation of this.
- size_t final_target_i = target_i;
- while (final_target_i > 0 &&
- children_[final_target_i]->layer()->delegate() == NULL)
- --final_target_i;
- Window* final_target = children_[final_target_i];
-
- // If we couldn't find a valid target position, don't move anything.
- if (final_target->layer()->delegate() == NULL)
- return;
-
- // Don't try to stack a child above itself.
- if (child == final_target)
- return;
+ StackChildRelativeTo(child, target, STACK_ABOVE);
+}
- // Move the child and all its transients.
- StackChildAboveImpl(child, final_target);
+void Window::StackChildBelow(Window* child, Window* target) {
+ StackChildRelativeTo(child, target, STACK_BELOW);
}
void Window::AddChild(Window* child) {
@@ -670,7 +646,43 @@ void Window::OnParentChanged() {
WindowObserver, observers_, OnWindowParentChanged(this, parent_));
}
-void Window::StackChildAboveImpl(Window* child, Window* target) {
+void Window::StackChildRelativeTo(Window* child,
+ Window* target,
+ StackDirection direction) {
+ DCHECK_NE(child, target);
+ DCHECK(child);
+ DCHECK(target);
+ DCHECK_EQ(this, child->parent());
+ DCHECK_EQ(this, target->parent());
+
+ const size_t target_i =
+ std::find(children_.begin(), children_.end(), target) - children_.begin();
+
+ // By convention we don't stack on top of windows with layers with NULL
+ // delegates. Walk backward to find a valid target window.
+ // See tests WindowTest.StackingMadrigal and StackOverClosingTransient
+ // for an explanation of this.
+ size_t final_target_i = target_i;
+ while (final_target_i > 0 &&
+ children_[final_target_i]->layer()->delegate() == NULL)
+ --final_target_i;
+ Window* final_target = children_[final_target_i];
+
+ // If we couldn't find a valid target position, don't move anything.
+ if (final_target->layer()->delegate() == NULL)
+ return;
+
+ // Don't try to stack a child above itself.
+ if (child == final_target)
+ return;
+
+ // Move the child and all its transients.
+ StackChildRelativeToImpl(child, final_target, direction);
+}
+
+void Window::StackChildRelativeToImpl(Window* child,
+ Window* target,
+ StackDirection direction) {
DCHECK_NE(child, target);
DCHECK(child);
DCHECK(target);
@@ -683,14 +695,21 @@ void Window::StackChildAboveImpl(Window* child, Window* target) {
std::find(children_.begin(), children_.end(), target) - children_.begin();
// Don't move the child if it is already in the right place.
- if (child_i == target_i + 1)
+ if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
+ (direction == STACK_BELOW && child_i + 1 == target_i))
return;
- const size_t dest_i = child_i < target_i ? target_i : target_i + 1;
+ const size_t dest_i =
+ direction == STACK_ABOVE ?
+ (child_i < target_i ? target_i : target_i + 1) :
+ (child_i < target_i ? target_i - 1 : target_i);
children_.erase(children_.begin() + child_i);
children_.insert(children_.begin() + dest_i, child);
- layer()->StackAbove(child->layer(), target->layer());
+ if (direction == STACK_ABOVE)
+ layer()->StackAbove(child->layer(), target->layer());
+ else
+ layer()->StackBelow(child->layer(), target->layer());
// Stack any transient children that share the same parent to be in front of
// 'child'.
@@ -699,7 +718,7 @@ void Window::StackChildAboveImpl(Window* child, Window* target) {
it != child->transient_children_.end(); ++it) {
Window* transient_child = *it;
if (transient_child->parent_ == this) {
- StackChildAboveImpl(transient_child, last_transient);
+ StackChildRelativeToImpl(transient_child, last_transient, STACK_ABOVE);
last_transient = transient_child;
}
}
diff --git a/ui/aura/window.h b/ui/aura/window.h
index a3d59b4..ebd3f13 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -164,6 +164,10 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// see WindowTest.StackingMadrigal for details.
void StackChildAbove(Window* child, Window* target);
+ // Stacks |child| below |target|. Does nothing if |child| is already below
+ // |target|.
+ void StackChildBelow(Window* child, Window* target);
+
// Tree operations.
// TODO(beng): Child windows are currently not owned by the hierarchy. We
// should change this.
@@ -321,6 +325,13 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
private:
friend class LayoutManager;
+
+ // Used when stacking windows.
+ enum StackDirection {
+ STACK_ABOVE,
+ STACK_BELOW
+ };
+
// Called by the public {Set,Get,Clear}Property functions.
intptr_t SetPropertyInternal(const void* key,
const char* name,
@@ -352,8 +363,16 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Called when this window's parent has changed.
void OnParentChanged();
- // Stacks |child| above |target| without checking for NULL layer delegates.
- void StackChildAboveImpl(Window* child, Window* target);
+ // Determines the real location for stacking |child| and invokes
+ // StackChildRelativeToImpl().
+ void StackChildRelativeTo(Window* child,
+ Window* target,
+ StackDirection direction);
+
+ // Implementation of StackChildRelativeTo().
+ void StackChildRelativeToImpl(Window* child,
+ Window* target,
+ StackDirection direction);
// Called when this window's stacking order among its siblings is changed.
void OnStackingChanged();
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index f491663..5a17664 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -428,6 +428,38 @@ TEST_F(WindowTest, StackChildAtTop) {
EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
}
+// Make sure StackChildBelow works.
+TEST_F(WindowTest, StackChildBelow) {
+ Window parent(NULL);
+ parent.Init(ui::Layer::LAYER_NOT_DRAWN);
+ Window child1(NULL);
+ child1.Init(ui::Layer::LAYER_NOT_DRAWN);
+ child1.set_id(1);
+ Window child2(NULL);
+ child2.Init(ui::Layer::LAYER_NOT_DRAWN);
+ child2.set_id(2);
+ Window child3(NULL);
+ child3.Init(ui::Layer::LAYER_NOT_DRAWN);
+ child3.set_id(3);
+
+ child1.SetParent(&parent);
+ child2.SetParent(&parent);
+ child3.SetParent(&parent);
+ EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
+
+ parent.StackChildBelow(&child1, &child2);
+ EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
+
+ parent.StackChildBelow(&child2, &child1);
+ EXPECT_EQ("2 1 3", ChildWindowIDsAsString(&parent));
+
+ parent.StackChildBelow(&child3, &child2);
+ EXPECT_EQ("3 2 1", ChildWindowIDsAsString(&parent));
+
+ parent.StackChildBelow(&child3, &child1);
+ EXPECT_EQ("2 3 1", ChildWindowIDsAsString(&parent));
+}
+
// Various assertions for StackChildAbove.
TEST_F(WindowTest, StackChildAbove) {
Window parent(NULL);
@@ -1306,6 +1338,8 @@ TEST_F(WindowTest, StackWindowsWhoseLayersHaveNoDelegate) {
}
TEST_F(WindowTest, StackTransientsWhoseLayersHaveNoDelegate) {
+ RootWindow* root = root_window();
+
// Create a window with several transients, then a couple windows on top.
scoped_ptr<Window> window1(CreateTestWindowWithId(1, NULL));
scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
@@ -1314,6 +1348,8 @@ TEST_F(WindowTest, StackTransientsWhoseLayersHaveNoDelegate) {
scoped_ptr<Window> window2(CreateTestWindowWithId(2, NULL));
scoped_ptr<Window> window3(CreateTestWindowWithId(3, NULL));
+ EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(root));
+
// Remove the delegates of a couple of transients, as if they are closing
// and animating out.
window11->layer()->set_delegate(NULL);
@@ -1321,16 +1357,9 @@ TEST_F(WindowTest, StackTransientsWhoseLayersHaveNoDelegate) {
// Move window1 to the front. All transients should move with it, and their
// order should be preserved.
- RootWindow* root = root_window();
root->StackChildAtTop(window1.get());
- ASSERT_EQ(6u, root->children().size());
- EXPECT_EQ(window2.get(), root->children()[0]);
- EXPECT_EQ(window3.get(), root->children()[1]);
- EXPECT_EQ(window1.get(), root->children()[2]);
- EXPECT_EQ(window11.get(), root->children()[3]);
- EXPECT_EQ(window12.get(), root->children()[4]);
- EXPECT_EQ(window13.get(), root->children()[5]);
+ EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(root));
}
class TestVisibilityClient : public client::VisibilityClient {
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 9e0cefc..63bbe91 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -424,6 +424,11 @@ void NativeWidgetAura::StackAtTop() {
window_->parent()->StackChildAtTop(window_);
}
+void NativeWidgetAura::StackBelow(gfx::NativeView native_view) {
+ if (window_->parent() && window_->parent() == native_view->parent())
+ window_->parent()->StackChildBelow(window_, native_view);
+}
+
void NativeWidgetAura::SetShape(gfx::NativeRegion region) {
// No need for this. Just delete and ignore.
delete region;
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index c8f27a9..7382e0a 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -85,6 +85,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void StackAbove(gfx::NativeView native_view) OVERRIDE;
virtual void StackAtTop() OVERRIDE;
+ virtual void StackBelow(gfx::NativeView native_view) OVERRIDE;
virtual void SetShape(gfx::NativeRegion shape) OVERRIDE;
virtual void Close() OVERRIDE;
virtual void CloseNow() OVERRIDE;
diff --git a/ui/views/widget/native_widget_gtk.cc b/ui/views/widget/native_widget_gtk.cc
index f1948de..975f19e 100644
--- a/ui/views/widget/native_widget_gtk.cc
+++ b/ui/views/widget/native_widget_gtk.cc
@@ -1064,6 +1064,10 @@ void NativeWidgetGtk::StackAtTop() {
gtk_window_present(GTK_WINDOW(GetNativeView()));
}
+void NativeWidgetGtk::StackBelow(gfx::NativeView native_view) {
+ NOTIMPLEMENTED();
+}
+
void NativeWidgetGtk::SetShape(gfx::NativeRegion region) {
if (widget_ && widget_->window) {
gdk_window_shape_combine_region(widget_->window, region, 0, 0);
diff --git a/ui/views/widget/native_widget_gtk.h b/ui/views/widget/native_widget_gtk.h
index 4d7a44c..92ef99c 100644
--- a/ui/views/widget/native_widget_gtk.h
+++ b/ui/views/widget/native_widget_gtk.h
@@ -187,6 +187,7 @@ class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void StackAbove(gfx::NativeView native_view) OVERRIDE;
virtual void StackAtTop() OVERRIDE;
+ virtual void StackBelow(gfx::NativeView native_view) OVERRIDE;
virtual void SetShape(gfx::NativeRegion shape) OVERRIDE;
virtual void Close() OVERRIDE;
virtual void CloseNow() OVERRIDE;
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index f81cf78..6129945 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -171,6 +171,7 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget,
virtual void SetSize(const gfx::Size& size) = 0;
virtual void StackAbove(gfx::NativeView native_view) = 0;
virtual void StackAtTop() = 0;
+ virtual void StackBelow(gfx::NativeView native_view) = 0;
virtual void SetShape(gfx::NativeRegion shape) = 0;
virtual void Close() = 0;
virtual void CloseNow() = 0;
diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc
index 5f61811..a3b7c28 100644
--- a/ui/views/widget/native_widget_win.cc
+++ b/ui/views/widget/native_widget_win.cc
@@ -825,6 +825,10 @@ void NativeWidgetWin::StackAtTop() {
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
+void NativeWidgetWin::StackBelow(gfx::NativeView native_view) {
+ NOTIMPLEMENTED();
+}
+
void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
SetWindowRgn(region, TRUE);
}
diff --git a/ui/views/widget/native_widget_win.h b/ui/views/widget/native_widget_win.h
index a3537c7..6b6fea1 100644
--- a/ui/views/widget/native_widget_win.h
+++ b/ui/views/widget/native_widget_win.h
@@ -216,6 +216,7 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void StackAbove(gfx::NativeView native_view) OVERRIDE;
virtual void StackAtTop() OVERRIDE;
+ virtual void StackBelow(gfx::NativeView native_view) OVERRIDE;
virtual void SetShape(gfx::NativeRegion shape) OVERRIDE;
virtual void Close() OVERRIDE;
virtual void CloseNow() OVERRIDE;
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 6a2fdc9..569fd92 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -485,6 +485,10 @@ void Widget::StackAtTop() {
native_widget_->StackAtTop();
}
+void Widget::StackBelow(gfx::NativeView native_view) {
+ native_widget_->StackBelow(native_view);
+}
+
void Widget::SetShape(gfx::NativeRegion shape) {
native_widget_->SetShape(shape);
}
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index c242cf3..baf7837 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -337,6 +337,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
void StackAbove(gfx::NativeView native_view);
void StackAtTop();
+ // Places the widget below the specified NativeView.
+ void StackBelow(gfx::NativeView native_view);
+
// Sets a shape on the widget. This takes ownership of shape.
void SetShape(gfx::NativeRegion shape);