summaryrefslogtreecommitdiff
path: root/athena/screen
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-11-12 17:59:43 +0000
committerTorne (Richard Coles) <torne@google.com>2014-11-12 17:59:43 +0000
commit1850ca92fc5c5faa2907b3befcf40067265148cc (patch)
tree7d10585f25356b3ee63b5ab4255161fe27725ee4 /athena/screen
parente9e1f6521e4fef99aa1a1928c70ef3dfb55a8d9e (diff)
downloadchromium_org-1850ca92fc5c5faa2907b3befcf40067265148cc.tar.gz
Merge from Chromium at DEPS revision 03655fd3f6d7
This commit was generated by merge_to_master.py. Change-Id: Ifba5396691b9164ba027be04398f7bc8e938750d
Diffstat (limited to 'athena/screen')
-rw-r--r--athena/screen/modal_window_controller.cc6
-rw-r--r--athena/screen/screen_manager_impl.cc44
-rw-r--r--athena/screen/screen_manager_unittest.cc88
3 files changed, 133 insertions, 5 deletions
diff --git a/athena/screen/modal_window_controller.cc b/athena/screen/modal_window_controller.cc
index 90357e9ce4..140b2c9aba 100644
--- a/athena/screen/modal_window_controller.cc
+++ b/athena/screen/modal_window_controller.cc
@@ -111,6 +111,12 @@ void ModalWindowController::UpdateDimming(aura::Window* ignore) {
// invisible, but don't delete it until next event execution
// because the call stack may still have and use the pointer.
modal_container_->RemoveObserver(this);
+
+ // Hide the window before removing it, so the focus manager which will run
+ // in RemoveChild handler can know that this container is no longer
+ // available.
+ modal_container_->Hide();
+
modal_container_->parent()->RemoveChild(modal_container_);
base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, modal_container_);
modal_container_ = nullptr;
diff --git a/athena/screen/screen_manager_impl.cc b/athena/screen/screen_manager_impl.cc
index 471df3b29d..20a4bd5d33 100644
--- a/athena/screen/screen_manager_impl.cc
+++ b/athena/screen/screen_manager_impl.cc
@@ -51,7 +51,7 @@ struct HigherPriorityFinder {
bool BlockEvents(aura::Window* container) {
ScreenManager::ContainerParams* params =
container->GetProperty(kContainerParamsKey);
- return params && params->block_events;
+ return params && params->block_events && container->IsVisible();
}
bool DefaultContainer(aura::Window* container) {
@@ -109,11 +109,47 @@ class AthenaFocusRules : public wm::BaseFocusRules {
return BaseFocusRules::CanActivateWindow(window);
}
+ aura::Window* GetTopmostWindowToActivateInContainer(
+ aura::Window* container,
+ aura::Window* ignore) const {
+ for (aura::Window::Windows::const_reverse_iterator i =
+ container->children().rbegin();
+ i != container->children().rend();
+ ++i) {
+ if (*i != ignore && CanActivateWindow(*i))
+ return *i;
+ }
+ return NULL;
+ }
+
virtual aura::Window* GetNextActivatableWindow(
aura::Window* ignore) const override {
- aura::Window* next = wm::BaseFocusRules::GetNextActivatableWindow(ignore);
- // TODO(oshima): Search from activatable containers if |next| is nullptr.
- // crbug.com/424750.
+ const aura::Window::Windows& containers =
+ ignore->GetRootWindow()->children();
+ auto starting_container_iter = containers.begin();
+ for (auto container_iter = containers.begin();
+ container_iter != containers.end();
+ container_iter++) {
+ if ((*container_iter)->Contains(ignore)) {
+ starting_container_iter = container_iter;
+ break;
+ }
+ }
+
+ // Find next window from the front containers.
+ aura::Window* next = nullptr;
+ for (auto container_iter = starting_container_iter;
+ !next && container_iter != containers.end();
+ container_iter++) {
+ next = GetTopmostWindowToActivateInContainer(*container_iter, ignore);
+ }
+
+ // Find next window from the back containers.
+ auto container_iter = starting_container_iter;
+ while (!next && container_iter != containers.begin()) {
+ container_iter--;
+ next = GetTopmostWindowToActivateInContainer(*container_iter, ignore);
+ }
return next;
}
diff --git a/athena/screen/screen_manager_unittest.cc b/athena/screen/screen_manager_unittest.cc
index dd634ba44a..15588d34e4 100644
--- a/athena/screen/screen_manager_unittest.cc
+++ b/athena/screen/screen_manager_unittest.cc
@@ -15,7 +15,8 @@
#include "ui/events/test/event_generator.h"
#include "ui/wm/core/window_util.h"
-typedef athena::test::AthenaTestBase ScreenManagerTest;
+using ScreenManagerTest = athena::test::AthenaTestBase;
+using AthenaFocusRuleTest = athena::test::AthenaTestBase;
namespace athena {
namespace {
@@ -163,6 +164,91 @@ TEST_F(ScreenManagerTest, DefaultContainer) {
parent->AddChild(original_default);
}
+TEST_F(AthenaFocusRuleTest, FocusTravarsalFromSameContainer) {
+ ScreenManager::ContainerParams params("contaier", kTestZOrderPriority);
+ params.can_activate_children = true;
+ scoped_ptr<aura::Window>
+ container(ScreenManager::Get()->CreateContainer(params));
+
+ scoped_ptr<aura::Window> w1(CreateWindow(
+ container.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+ wm::ActivateWindow(w1.get());
+ EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+
+ scoped_ptr<aura::Window> w2(CreateWindow(
+ container.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+ EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+
+ container->RemoveChild(w1.get());
+ EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
+}
+
+TEST_F(AthenaFocusRuleTest, FocusTravarsalFromOtherContainer) {
+ ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 1);
+ params2.can_activate_children = true;
+ scoped_ptr<aura::Window>
+ container2(ScreenManager::Get()->CreateContainer(params2));
+ scoped_ptr<aura::Window> w2(CreateWindow(
+ container2.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+ wm::ActivateWindow(w2.get());
+ EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
+
+ ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority);
+ params1.can_activate_children = true;
+ scoped_ptr<aura::Window>
+ container1(ScreenManager::Get()->CreateContainer(params1));
+ ScreenManager::ContainerParams params3("contaier3", kTestZOrderPriority + 2);
+ params3.can_activate_children = true;
+ scoped_ptr<aura::Window>
+ container3(ScreenManager::Get()->CreateContainer(params3));
+ scoped_ptr<aura::Window> w1(CreateWindow(
+ container1.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+ scoped_ptr<aura::Window> w3(CreateWindow(
+ container3.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+
+ EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
+
+ container2->RemoveChild(w2.get());
+ // Focus moves to a window in the front contaier.
+ EXPECT_TRUE(wm::IsActiveWindow(w3.get()));
+
+ container3->RemoveChild(w3.get());
+ // Focus moves to a window in the back contaier.
+ EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+}
+
+TEST_F(AthenaFocusRuleTest, FocusTravarsalFromEventBlockedContainer) {
+ ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority + 1);
+ params1.can_activate_children = true;
+ scoped_ptr<aura::Window>
+ container1(ScreenManager::Get()->CreateContainer(params1));
+
+ ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 2);
+ params2.can_activate_children = true;
+ params2.block_events = true;
+ scoped_ptr<aura::Window>
+ container2(ScreenManager::Get()->CreateContainer(params2));
+
+ scoped_ptr<aura::Window> w1(CreateWindow(
+ container1.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+ scoped_ptr<aura::Window> w2(CreateWindow(
+ container2.get(), nullptr, gfx::Rect(0, 0, 100, 100)));
+
+ wm::ActivateWindow(w2.get());
+ EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
+
+ // Confirm that w1 can't get the focus.
+ wm::ActivateWindow(w1.get());
+ EXPECT_FALSE(wm::IsActiveWindow(w1.get()));
+ EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
+
+ container2->Hide();
+ w2.reset();
+ container2.reset();
+
+ EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+}
+
namespace {
class ScreenManagerTargeterTest