15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace/workspace_layout_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string>
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/display/display_layout.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/display/display_manager.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shell_observer.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_window_ids.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h"
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/wm_event.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/workspace/workspace_window_resizer.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/compiler_specific.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_windows.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/base/ime/dummy_text_input_client.h"
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/base/ime/input_method.h"
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/ime/text_input_focus_manager.h"
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/ui_base_switches_util.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/ui_base_types.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/insets.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/screen.h"
37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/widget/widget.h"
38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/widget/widget_delegate.h"
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass MaximizeDelegateView : public views::WidgetDelegateView {
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit MaximizeDelegateView(const gfx::Rect& initial_bounds)
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      : initial_bounds_(initial_bounds) {
48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual ~MaximizeDelegateView() {}
50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual bool GetSavedWindowPlacement(
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const views::Widget* widget,
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      gfx::Rect* bounds,
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ui::WindowShowState* show_state) const OVERRIDE {
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    *bounds = initial_bounds_;
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    *show_state = ui::SHOW_STATE_MAXIMIZED;
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return true;
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const gfx::Rect initial_bounds_;
62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MaximizeDelegateView);
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TestShellObserver : public ShellObserver {
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestShellObserver() : call_count_(0),
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        is_fullscreen_(false) {
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Shell::GetInstance()->AddShellObserver(this);
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~TestShellObserver() {
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Shell::GetInstance()->RemoveShellObserver(this);
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnFullscreenStateChanged(bool is_fullscreen,
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        aura::Window* root_window) OVERRIDE {
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    call_count_++;
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    is_fullscreen_ = is_fullscreen;
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int call_count() const {
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return call_count_;
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool is_fullscreen() const {
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return is_fullscreen_;
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int call_count_;
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool is_fullscreen_;
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestShellObserver);
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace
99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef test::AshTestBase WorkspaceLayoutManagerTest;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that a window containing a restore coordinate will be restored to
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the size prior to minimize, keeping the restore rectangle in tact (if
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there is one).
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, RestoreFromMinimizeKeepsRestore) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window(
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 3, 4)));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds(10, 15, 25, 35);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetBounds(bounds);
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This will not be used for un-minimizing window.
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(0, 0, 100, 100));
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Minimize();
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", window_state->GetRestoreBoundsInScreen().ToString());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,15 25x35", window.get()->bounds().ToString());
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateDisplay("400x300,500x400");
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            ScreenUtil::GetSecondaryDisplay());
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(Shell::GetAllRootWindows()[1], window->GetRootWindow());
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Minimize();
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This will not be used for un-minimizing window.
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(0, 0, 100, 100));
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("600,0 100x100", window->GetBoundsInScreen().ToString());
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the unminimized window moves inside the display when
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 2nd display is disconnected.
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Minimize();
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateDisplay("400x300");
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(Shell::GetPrimaryRootWindow(), window->GetRootWindow());
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, KeepMinimumVisibilityInDisplays) {
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!SupportsMultipleDisplays())
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  UpdateDisplay("300x400,400x500");
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DisplayLayout layout(DisplayLayout::TOP, 0);
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Shell::GetInstance()->display_manager()->
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SetLayoutForCurrentDisplays(layout);
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("0,-500 400x500", root_windows[1]->GetBoundsInScreen().ToString());
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<aura::Window> window1(
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(10, -400, 200, 200)));
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("10,-400 200x200", window1->GetBoundsInScreen().ToString());
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Make sure the caption is visible.
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<aura::Window> window2(
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(10, -600, 200, 200)));
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("10,-500 200x200", window2->GetBoundsInScreen().ToString());
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
165116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(WorkspaceLayoutManagerTest, NoMinimumVisibilityForPopupWindows) {
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdateDisplay("300x400");
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Create a popup window out of display boundaries and make sure it is not
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // moved to have minimum visibility.
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<aura::Window> window(
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      CreateTestWindowInShellWithDelegateAndType(NULL,
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 ui::wm::WINDOW_TYPE_POPUP,
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 0,
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 gfx::Rect(400, 100, 50, 50)));
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ("400,100 50x50", window->GetBoundsInScreen().ToString());
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
178bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(WorkspaceLayoutManagerTest, KeepRestoredWindowInDisplay) {
179bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!SupportsHostWindowResize())
180bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return;
181bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<aura::Window> window(
182bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
185bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Maximized -> Normal transition.
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Maximize();
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(-100, -100, 30, 40));
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
189bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(
190bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Y bounds should not be negative.
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
193bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Minimized -> Normal transition.
195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window->SetBounds(gfx::Rect(-100, -100, 30, 40));
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Minimize();
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_FALSE(
198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_EQ("-100,-100 30x40", window->bounds().ToString());
200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window->Show();
201bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(
202bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Y bounds should not be negative.
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
205bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
206bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Fullscreen -> Normal transition.
207bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window->SetBounds(gfx::Rect(0, 0, 30, 40));  // reset bounds.
208bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ASSERT_EQ("0,0 30x40", window->bounds().ToString());
209bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
210bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_EQ(window->bounds(), window->GetRootWindow()->bounds());
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(-100, -100, 30, 40));
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
213bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(
214bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Y bounds should not be negative.
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
217bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(WorkspaceLayoutManagerTest, MaximizeInDisplayToBeRestored) {
220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!SupportsMultipleDisplays())
221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return;
222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  UpdateDisplay("300x400,400x500");
223ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
225ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<aura::Window> window(
227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
228ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[0], window->GetRootWindow());
229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));
232ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Maximize the window in 2nd display as the restore bounds
233ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // is inside 2nd display.
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Maximize();
235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("300,0 400x453", window->GetBoundsInScreen().ToString());
237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("400,0 30x40", window->GetBoundsInScreen().ToString());
241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If the restore bounds intersects with the current display,
243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // don't move.
24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Maximize();
246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("300,0 400x453", window->GetBoundsInScreen().ToString());
248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("280,0 30x40", window->GetBoundsInScreen().ToString());
252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Restoring widget state.
254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<views::Widget> w1(new views::Widget);
255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::Widget::InitParams params;
256ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  params.delegate = new MaximizeDelegateView(gfx::Rect(400, 0, 30, 40));
258ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  params.context = root_windows[0];
259ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  w1->Init(params);
260ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  w1->Show();
261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(w1->IsMaximized());
262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("300,0 400x453", w1->GetWindowBoundsInScreen().ToString());
264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  w1->Restore();
265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("400,0 30x40", w1->GetWindowBoundsInScreen().ToString());
267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(WorkspaceLayoutManagerTest, FullscreenInDisplayToBeRestored) {
270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!SupportsMultipleDisplays())
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return;
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  UpdateDisplay("300x400,400x500");
273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<aura::Window> window(
277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[0], window->GetRootWindow());
279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));
282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Maximize the window in 2nd display as the restore bounds
283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // is inside 2nd display.
284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window->SetProperty(aura::client::kShowStateKey,
285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      ui::SHOW_STATE_FULLSCREEN);
286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("300,0 400x500", window->GetBoundsInScreen().ToString());
288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("400,0 30x40", window->GetBoundsInScreen().ToString());
292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If the restore bounds intersects with the current display,
294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // don't move.
29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window->SetProperty(aura::client::kShowStateKey,
297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      ui::SHOW_STATE_FULLSCREEN);
298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("300,0 400x500", window->GetBoundsInScreen().ToString());
300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(root_windows[1], window->GetRootWindow());
303ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("280,0 30x40", window->GetBoundsInScreen().ToString());
304ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
305ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowObserver implementation used by DontClobberRestoreBoundsWindowObserver.
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This code mirrors what BrowserFrameAsh does. In particular when this code
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sees the window was maximized it changes the bounds of a secondary
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window. The secondary window mirrors the status window.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DontClobberRestoreBoundsWindowObserver : public aura::WindowObserver {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DontClobberRestoreBoundsWindowObserver() : window_(NULL) {}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_window(aura::Window* window) { window_ = window; }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowPropertyChanged(aura::Window* window,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const void* key,
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       intptr_t old) OVERRIDE {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!window_)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (wm::GetWindowState(window)->IsMaximized()) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aura::Window* w = window_;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_ = NULL;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect shelf_bounds(Shell::GetPrimaryRootWindowController()->
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             GetShelfLayoutManager()->GetIdealBounds());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Rect& window_bounds(w->bounds());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      w->SetBounds(gfx::Rect(window_bounds.x(), shelf_bounds.y() - 1,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             window_bounds.width(), window_bounds.height()));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window* window_;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DontClobberRestoreBoundsWindowObserver);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a window, maximized the window and from within the maximized
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notification sets the bounds of a window to overlap the shelf. Verifies this
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't effect the restore bounds.
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, DontClobberRestoreBounds) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DontClobberRestoreBoundsWindowObserver window_observer;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window(new aura::Window(NULL));
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Init(aura::WINDOW_LAYER_TEXTURED);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetBounds(gfx::Rect(10, 20, 30, 40));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: for this test to exercise the failure the observer needs to be added
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // before the parent set. This mimics what BrowserFrameAsh does.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->AddObserver(&window_observer);
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ParentWindowInPrimaryRootWindow(window.get());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Show();
35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Activate();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window2(
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(12, 20, 30, 40)));
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ::wm::AddTransientChild(window.get(), window2.get());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2->Show();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_observer.set_window(window2.get());
36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Maximize();
36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ("10,20 30x40",
36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            window_state->GetRestoreBoundsInScreen().ToString());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->RemoveObserver(&window_observer);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies when a window is maximized all descendant windows have a size.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, ChildBoundsResetOnMaximize) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window(
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 30, 40)));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Show();
37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
37668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Activate();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> child_window(
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aura::test::CreateTestWindowWithBounds(gfx::Rect(5, 6, 7, 8),
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             window.get()));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_window->Show();
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Maximize();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("5,6 7x8", child_window->bounds().ToString());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verifies a window created with maximized state has the maximized
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// bounds.
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, MaximizeWithEmptySize) {
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<aura::Window> window(
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      aura::test::CreateTestWindowWithBounds(gfx::Rect(0, 0, 0, 0),
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             NULL));
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wm::GetWindowState(window.get())->Maximize();
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* default_container = Shell::GetContainer(
393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetPrimaryRootWindow(), kShellWindowId_DefaultContainer);
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  default_container->AddChild(window.get());
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window->Show();
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect work_area(
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().work_area());
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(work_area.ToString(), window->GetBoundsInScreen().ToString());
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, WindowShouldBeOnScreenWhenAdded) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Normal window bounds shouldn't be changed.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect window_bounds(100, 100, 200, 200);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(window_bounds));
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(window_bounds, window->bounds());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the window is out of the workspace, it would be moved on screen.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect root_window_bounds =
410bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetInstance()->GetPrimaryRootWindow()->bounds();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_bounds.Offset(root_window_bounds.width(), root_window_bounds.height());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(window_bounds.Intersects(root_window_bounds));
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> out_window(
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(window_bounds));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(window_bounds.size(), out_window->bounds().size());
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds = out_window->bounds();
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.Intersect(root_window_bounds);
418bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
419bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // 30% of the window edge must be visible.
420bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
421bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
422bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  aura::Window* parent = out_window->parent();
4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  parent->RemoveChild(out_window.get());
4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  out_window->SetBounds(gfx::Rect(-200, -200, 200, 200));
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // UserHasChangedWindowPositionOrSize flag shouldn't turn off this behavior.
42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::GetWindowState(window.get())->set_bounds_changed_by_user(true);
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  parent->AddChild(out_window.get());
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Make sure we always make more than 1/3 of the window edge visible even
433bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // if the initial bounds intersects with display.
434bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window_bounds.SetRect(-150, -150, 200, 200);
435bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds = window_bounds;
436bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds.Intersect(root_window_bounds);
437bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
438bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Make sure that the initial bounds' visible area is less than 26%
439bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // so that the auto adjustment logic kicks in.
440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ASSERT_LT(bounds.width(), out_window->bounds().width() * 0.26);
441bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ASSERT_LT(bounds.height(), out_window->bounds().height() * 0.26);
442bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ASSERT_TRUE(window_bounds.Intersects(root_window_bounds));
443bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<aura::Window> partially_out_window(
445bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      CreateTestWindowInShellWithBounds(window_bounds));
446bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_EQ(window_bounds.size(), partially_out_window->bounds().size());
447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds = partially_out_window->bounds();
448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds.Intersect(root_window_bounds);
449bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
450bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
451bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
452bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Make sure the window whose 30% width/height is bigger than display
453bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // will be placed correctly.
454bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  window_bounds.SetRect(-1900, -1900, 3000, 3000);
455bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<aura::Window> window_bigger_than_display(
456bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      CreateTestWindowInShellWithBounds(window_bounds));
457bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GE(root_window_bounds.width(),
458bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            window_bigger_than_display->bounds().width());
459bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GE(root_window_bounds.height(),
460bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            window_bigger_than_display->bounds().height());
461bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
462bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds = window_bigger_than_display->bounds();
463bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bounds.Intersect(root_window_bounds);
464bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
465bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies the size of a window is enforced to be smaller than the work area.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, SizeToWorkArea) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Normal window bounds shouldn't be changed.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size work_area(
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().work_area().size());
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect window_bounds(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      100, 101, work_area.width() + 1, work_area.height() + 2);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window(
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithBounds(window_bounds));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(gfx::Point(100, 101), work_area).ToString(),
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->bounds().ToString());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Directly setting the bounds triggers a slightly different code path. Verify
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that too.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetBounds(window_bounds);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(gfx::Point(100, 101), work_area).ToString(),
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->bounds().ToString());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerTest, NotifyFullscreenChanges) {
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestShellObserver observer;
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<aura::Window> window1(
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<aura::Window> window2(
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wm::WindowState* window_state1 = wm::GetWindowState(window1.get());
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wm::WindowState* window_state2 = wm::GetWindowState(window2.get());
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  window_state2->Activate();
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_state2->OnWMEvent(&toggle_fullscreen_event);
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(1, observer.call_count());
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(observer.is_fullscreen());
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // When window1 moves to the front the fullscreen state should change.
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  window_state1->Activate();
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2, observer.call_count());
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(observer.is_fullscreen());
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // It should change back if window2 becomes active again.
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  window_state2->Activate();
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(3, observer.call_count());
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(observer.is_fullscreen());
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_state2->OnWMEvent(&toggle_fullscreen_event);
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(4, observer.call_count());
514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(observer.is_fullscreen());
515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_state2->OnWMEvent(&toggle_fullscreen_event);
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(5, observer.call_count());
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(observer.is_fullscreen());
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Closing the window should change the fullscreen state.
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  window2.reset();
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(6, observer.call_count());
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(observer.is_fullscreen());
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Following "Solo" tests were originally written for BaseLayoutManager.
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class WorkspaceLayoutManagerSoloTest : public test::AshTestBase {
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkspaceLayoutManagerSoloTest() {}
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~WorkspaceLayoutManagerSoloTest() {}
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return CreateTestWindowInShellWithBounds(bounds);
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerSoloTest);
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests normal->maximize->normal.
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, Maximize) {
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(100, 100, 200, 200);
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maximized window fills the work area, not the whole display.
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window->bounds().ToString());
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests normal->minimize->normal.
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, Minimize) {
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(100, 100, 200, 200);
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note: Currently minimize doesn't do anything except set the state.
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // See crbug.com/104571.
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A WindowDelegate which sets the focus when the window
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// becomes visible.
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FocusDelegate : public aura::test::TestWindowDelegate {
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FocusDelegate()
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : window_(NULL),
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        show_state_(ui::SHOW_STATE_END) {
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~FocusDelegate() {}
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void set_window(aura::Window* window) { window_ = window; }
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // aura::test::TestWindowDelegate overrides:
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_) {
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (visible)
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        window_->Focus();
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      show_state_ = window_->GetProperty(aura::client::kShowStateKey);
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::WindowShowState GetShowStateAndReset() {
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::WindowShowState ret = show_state_;
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    show_state_ = ui::SHOW_STATE_END;
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return ret;
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window_;
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::WindowShowState show_state_;
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusDelegate);
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Make sure that the window's show state is correct in
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |WindowDelegate::OnWindowTargetVisibilityChanged|, and setting
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// focus in this callback doesn't cause DCHECK error.  See
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// crbug.com/168383.
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, FocusDuringUnminimize) {
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FocusDelegate delegate;
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &delegate, 0, gfx::Rect(100, 100, 100, 100)));
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate.set_window(window.get());
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(window->IsVisible());
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_MINIMIZED, delegate.GetShowStateAndReset());
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Show();
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(window->IsVisible());
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, delegate.GetShowStateAndReset());
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests maximized window size during root window resize.
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeRootWindowResize) {
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(100, 100, 200, 200);
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect initial_work_area_bounds =
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get());
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(initial_work_area_bounds.ToString(), window->bounds().ToString());
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enlarge the root window.  We should still match the work area size.
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateDisplay("900x700");
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window->bounds().ToString());
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      initial_work_area_bounds.ToString(),
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString());
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests normal->fullscreen->normal.
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, Fullscreen) {
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(100, 100, 200, 200);
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Fullscreen window fills the whole display.
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                window.get()).bounds().ToString(),
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window->bounds().ToString());
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests fullscreen window size during root window resize.
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, FullscreenRootWindowResize) {
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(100, 100, 200, 200);
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Fullscreen window fills the whole display.
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                window.get()).bounds().ToString(),
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window->bounds().ToString());
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enlarge the root window.  We should still match the display size.
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateDisplay("800x600");
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                window.get()).bounds().ToString(),
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window->bounds().ToString());
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that when the screen gets smaller the windows aren't bigger than
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the screen.
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, RootWindowResizeShrinksWindows) {
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CreateTestWindow(gfx::Rect(10, 20, 500, 400)));
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window.get()).work_area();
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Invariant: Window is smaller than work area.
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().width(), work_area.width());
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().height(), work_area.height());
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make the root window narrower than our window.
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateDisplay("300x400");
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  work_area = Shell::GetScreen()->GetDisplayNearestWindow(
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window.get()).work_area();
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().width(), work_area.width());
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().height(), work_area.height());
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make the root window shorter than our window.
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateDisplay("300x200");
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  work_area = Shell::GetScreen()->GetDisplayNearestWindow(
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window.get()).work_area();
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().width(), work_area.width());
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LE(window->bounds().height(), work_area.height());
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enlarging the root window does not change the window bounds.
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect old_bounds = window->bounds();
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateDisplay("800x600");
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(old_bounds.width(), window->bounds().width());
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(old_bounds.height(), window->bounds().height());
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies maximizing sets the restore bounds, and restoring
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// restores the bounds.
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeSetsRestoreBounds) {
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(10, 20, 30, 40)));
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maximize it, which will keep the previous restore bounds.
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("10,20 30x40", window_state->GetRestoreBoundsInParent().ToString());
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Restore it, which should restore bounds and reset restore bounds.
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("10,20 30x40", window->bounds().ToString());
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(window_state->HasRestoreBounds());
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies maximizing keeps the restore bounds if set.
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeResetsRestoreBounds) {
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state->SetRestoreBoundsInParent(gfx::Rect(10, 11, 12, 13));
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maximize it, which will keep the previous restore bounds.
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("10,11 12x13", window_state->GetRestoreBoundsInParent().ToString());
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies that the restore bounds do not get reset when restoring to a
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// maximzied state from a minimized state.
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest,
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       BoundsAfterRestoringToMaximizeFromMinimize) {
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(10, 15, 25, 35);
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetBounds(bounds);
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maximize it, which should reset restore bounds.
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state->Maximize();
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window_state->GetRestoreBoundsInParent().ToString());
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Minimize the window. The restore bounds should not change.
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state->Minimize();
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window_state->GetRestoreBoundsInParent().ToString());
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Show the window again. The window should be maximized, and the restore
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // bounds should not change.
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Show();
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            window_state->GetRestoreBoundsInParent().ToString());
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(window_state->IsMaximized());
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state->Restore();
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify if the window is not resized during screen lock. See: crbug.com/173127
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerSoloTest, NotResizeWhenScreenIsLocked) {
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetCanLockScreen(true);
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // window with AlwaysOnTop will be managed by BaseLayoutManager.
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetProperty(aura::client::kAlwaysOnTopKey, true);
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Show();
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
764c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ShelfLayoutManager* shelf = ShelfLayoutManager::ForShelf(window.get());
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetBounds(ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()));
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect window_bounds = window->bounds();
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window_bounds.ToString());
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->session_state_delegate()->LockScreen();
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shelf->UpdateVisibilityState();
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window_bounds.ToString());
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shelf->UpdateVisibilityState();
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(window_bounds.ToString(), window->bounds().ToString());
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Following tests are written to test the backdrop functionality.
785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
787a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class WorkspaceLayoutManagerBackdropTest : public test::AshTestBase {
789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WorkspaceLayoutManagerBackdropTest() {}
791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~WorkspaceLayoutManagerBackdropTest() {}
792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::AshTestBase::SetUp();
795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UpdateDisplay("800x600");
796c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    default_container_ = Shell::GetContainer(Shell::GetPrimaryRootWindow(),
797c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                             kShellWindowId_DefaultContainer);
798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    aura::Window* window = CreateTestWindowInShellWithBounds(bounds);
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return window;
803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Turn the top window back drop on / off.
806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ShowTopWindowBackdrop(bool show) {
807c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_ptr<ash::WorkspaceLayoutManagerDelegate> backdrop;
808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (show) {
809c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      backdrop.reset(new ash::WorkspaceBackdropDelegate(default_container_));
810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
811c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    (static_cast<WorkspaceLayoutManager*>(default_container_->layout_manager()))
812c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ->SetMaximizeBackdropDelegate(backdrop.Pass());
813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Closing and / or opening can be a delayed operation.
814a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
816a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Return the default container.
818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* default_container() { return default_container_; }
819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Return the order of windows (top most first) as they are in the default
821a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // container. If the window is visible it will be a big letter, otherwise a
822a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // small one. The backdrop will be an X and unknown windows will be shown as
823a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // '!'.
824a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string GetWindowOrderAsString(aura::Window* backdrop,
825a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     aura::Window* wa,
826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     aura::Window* wb,
827a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     aura::Window* wc) {
828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::string result;
829a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (int i = static_cast<int>(default_container()->children().size()) - 1;
830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         i >= 0;
831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         --i) {
832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!result.empty())
833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += ",";
834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (default_container()->children()[i] == wa)
835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += default_container()->children()[i]->IsVisible() ? "A" : "a";
836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else if (default_container()->children()[i] == wb)
837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += default_container()->children()[i]->IsVisible() ? "B" : "b";
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else if (default_container()->children()[i] == wc)
839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += default_container()->children()[i]->IsVisible() ? "C" : "c";
840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else if (default_container()->children()[i] == backdrop)
841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += default_container()->children()[i]->IsVisible() ? "X" : "x";
842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else
843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        result += "!";
844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return result;
846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The default container.
850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* default_container_;
851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerBackdropTest);
853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Check that creating the BackDrop without destroying it does not lead into
858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// a crash.
859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerBackdropTest, BackdropCrashTest) {
860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ShowTopWindowBackdrop(true);
861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verify basic assumptions about the backdrop.
864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerBackdropTest, BasicBackdropTests) {
865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Create a backdrop and see that there is one window (the backdrop) and
866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // that the size is the same as the default container as well as that it is
867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // not visible.
868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ShowTopWindowBackdrop(true);
869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, default_container()->children().size());
870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(default_container()->children()[0]->IsVisible());
871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Add a window and make sure that the backdrop is the second child.
874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    window->Show();
876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(2U, default_container()->children().size());
877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(default_container()->children()[0]->IsVisible());
878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(default_container()->children()[1]->IsVisible());
879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(window.get(), default_container()->children()[1]);
880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(default_container()->bounds().ToString(),
881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              default_container()->children()[0]->bounds().ToString());
882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // With the window gone the backdrop should be invisible again.
885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, default_container()->children().size());
886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(default_container()->children()[0]->IsVisible());
887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Destroying the Backdrop should empty the container.
889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ShowTopWindowBackdrop(false);
890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0U, default_container()->children().size());
891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
892a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
893a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verify that the backdrop gets properly created and placed.
894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerBackdropTest, VerifyBackdropAndItsStacking) {
895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window1->Show();
897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Get the default container and check that only a single window is in there.
899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, default_container()->children().size());
900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(window1.get(), default_container()->children()[0]);
901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("A", GetWindowOrderAsString(NULL, window1.get(), NULL, NULL));
902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Create 2 more windows and check that they are also in the container.
904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateTestWindow(gfx::Rect(10, 2, 3, 4)));
905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<aura::Window> window3(CreateTestWindow(gfx::Rect(20, 2, 3, 4)));
906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window2->Show();
907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window3->Show();
908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* backdrop = NULL;
910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("C,B,A",
911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Turn on the backdrop mode and check that the window shows up where it
915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should be (second highest number).
916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ShowTopWindowBackdrop(true);
917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backdrop = default_container()->children()[2];
918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("C,X,B,A",
919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Switch the order of windows and check that it still remains in that
923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // location.
924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  default_container()->StackChildAtTop(window2.get());
925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("B,X,C,A",
926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make the top window invisible and check.
930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window2.get()->Hide();
931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("b,C,X,A",
932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
933a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Then delete window after window and see that everything is in order.
935a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window1.reset();
936a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("b,C,X",
937a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window3.reset();
940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("b,x",
941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(backdrop, window1.get(), window2.get(),
942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ShowTopWindowBackdrop(false);
944a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("b",
945a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetWindowOrderAsString(NULL, window1.get(), window2.get(),
946a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   window3.get()));
947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
949f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Tests that when hidding the shelf, that the backdrop resizes to fill the
950f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// entire workspace area.
951f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(WorkspaceLayoutManagerBackdropTest, ShelfVisibilityChangesBounds) {
952f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ShelfLayoutManager* shelf_layout_manager =
953f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
954f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ShowTopWindowBackdrop(true);
955f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunAllPendingInMessageLoop();
956f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
957f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
958f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Rect initial_bounds = default_container()->children()[0]->bounds();
959f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
960f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->UpdateVisibilityState();
961f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
962f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // When the shelf is re-shown WorkspaceLayoutManager shrinks all children
963f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // including the backdrop.
964f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
965f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->UpdateVisibilityState();
966f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Rect reduced_bounds = default_container()->children()[0]->bounds();
967f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_LT(reduced_bounds.height(), initial_bounds.height());
968f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
969f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
970f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shelf_layout_manager->UpdateVisibilityState();
971f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
972f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_GT(default_container()->children()[0]->bounds().height(),
973f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            reduced_bounds.height());
974f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
975f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
97646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class WorkspaceLayoutManagerKeyboardTest : public test::AshTestBase {
97746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
97846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WorkspaceLayoutManagerKeyboardTest() {}
97946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~WorkspaceLayoutManagerKeyboardTest() {}
98046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
98146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
98246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test::AshTestBase::SetUp();
98346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    UpdateDisplay("800x600");
98446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    aura::Window* default_container = Shell::GetContainer(
98546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        Shell::GetPrimaryRootWindow(), kShellWindowId_DefaultContainer);
9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    layout_manager_ = static_cast<WorkspaceLayoutManager*>(
9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        default_container->layout_manager());
98846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
98946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
99046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
99146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return CreateTestWindowInShellWithBounds(bounds);
99246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
99346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
99446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void ShowKeyboard() {
99503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    layout_manager_->OnKeyboardBoundsChanging(keyboard_bounds_);
99646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    restore_work_area_insets_ = Shell::GetScreen()->GetPrimaryDisplay().
99746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GetWorkAreaInsets();
99846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Shell::GetInstance()->SetDisplayWorkAreaInsets(
99946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        Shell::GetPrimaryRootWindow(),
100046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        gfx::Insets(0, 0, keyboard_bounds_.height(), 0));
100146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
100246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
100346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void HideKeyboard() {
100446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Shell::GetInstance()->SetDisplayWorkAreaInsets(
100546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        Shell::GetPrimaryRootWindow(),
100646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        restore_work_area_insets_);
100746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    layout_manager_->OnKeyboardBoundsChanging(gfx::Rect());
100846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
100946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
101046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SetKeyboardBounds(const gfx::Rect& bounds) {
101146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    keyboard_bounds_ = bounds;
101246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
101346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Focus(ui::TextInputClient* text_input_client) {
10151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (switches::IsTextInputFocusManagerEnabled()) {
10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
10171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          text_input_client);
10181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
10191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      aura::Window* root_window =
10201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ash::Shell::GetInstance()->GetPrimaryRootWindow();
10211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::InputMethod* input_method =
10221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
10231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      input_method->SetFocusedTextInputClient(text_input_client);
10241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
10251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
10261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Blur(ui::TextInputClient* text_input_client) {
10281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (switches::IsTextInputFocusManagerEnabled()) {
10291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::TextInputFocusManager::GetInstance()->BlurTextInputClient(
10301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          text_input_client);
10311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
10321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      aura::Window* root_window =
10331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ash::Shell::GetInstance()->GetPrimaryRootWindow();
10341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::InputMethod* input_method =
10351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
10361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      input_method->SetFocusedTextInputClient(NULL);
10371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
10381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
10391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
104046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
104146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::Insets restore_work_area_insets_;
104246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::Rect keyboard_bounds_;
1043f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WorkspaceLayoutManager* layout_manager_;
104446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
104546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerKeyboardTest);
104646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
104746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
104846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class FakeTextInputClient : public ui::DummyTextInputClient {
104946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
1050f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit FakeTextInputClient(gfx::NativeWindow window) : window_(window) {}
105146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~FakeTextInputClient() {}
105246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
105346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE {
105446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return window_;
105546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
105646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
105746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
105846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::NativeWindow window_;
105946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
106046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeTextInputClient);
106146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
106246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that when a child window gains focus the top level window containing it
10641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// is resized to fit the remaining workspace area.
10651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(WorkspaceLayoutManagerKeyboardTest, ChildWindowFocused) {
10661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect work_area(
10671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Shell::GetScreen()->GetPrimaryDisplay().work_area());
10681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect keyboard_bounds(work_area.x(),
10691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            work_area.y() + work_area.height() / 2,
10701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            work_area.width(),
10711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            work_area.height() / 2);
10721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetKeyboardBounds(keyboard_bounds);
10741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::test::TestWindowDelegate delegate1;
10761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<aura::Window> parent_window(CreateTestWindowInShellWithDelegate(
10771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &delegate1, -1, work_area));
10781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::test::TestWindowDelegate delegate2;
10791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
10801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &delegate2, -1, work_area));
10811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  parent_window->AddChild(window.get());
10821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FakeTextInputClient text_input_client(window.get());
10841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Focus(&text_input_client);
10851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int available_height =
10871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Shell::GetScreen()->GetPrimaryDisplay().bounds().height() -
10881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      keyboard_bounds.height();
10891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect initial_window_bounds(50, 50, 100, 500);
10911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  parent_window->SetBounds(initial_window_bounds);
10921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(initial_window_bounds.ToString(),
10931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            parent_window->bounds().ToString());
10941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ShowKeyboard();
10951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Rect(50, 0, 100, available_height).ToString(),
10961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            parent_window->bounds().ToString());
10971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HideKeyboard();
10981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(initial_window_bounds.ToString(),
10991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            parent_window->bounds().ToString());
11001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
11011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Blur(&text_input_client);
11021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
11031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
110446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(WorkspaceLayoutManagerKeyboardTest, AdjustWindowForA11yKeyboard) {
110546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::Rect work_area(
110646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().work_area());
110746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::Rect keyboard_bounds(work_area.x(),
110846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            work_area.y() + work_area.height() / 2,
110946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            work_area.width(),
111046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            work_area.height() / 2);
111146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
111246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetKeyboardBounds(keyboard_bounds);
111303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
111403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  aura::test::TestWindowDelegate delegate;
111503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
111603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      &delegate, -1, work_area));
111746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
111846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FakeTextInputClient text_input_client(window.get());
11191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Focus(&text_input_client);
112046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
112146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int available_height =
112246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().bounds().height() -
112346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      keyboard_bounds.height();
112446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
112503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(work_area).ToString(), window->bounds().ToString());
112646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ShowKeyboard();
112746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(gfx::Rect(work_area.origin(),
112846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            gfx::Size(work_area.width(), available_height)).ToString(),
112946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            window->bounds().ToString());
113046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HideKeyboard();
113103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(work_area).ToString(), window->bounds().ToString());
113246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
113303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gfx::Rect small_window_bound(50, 50, 100, 500);
113403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  window->SetBounds(small_window_bound);
113503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(small_window_bound.ToString(), window->bounds().ToString());
113646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ShowKeyboard();
113746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(gfx::Rect(50, 0, 100, available_height).ToString(),
113846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            window->bounds().ToString());
113946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HideKeyboard();
114003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(small_window_bound.ToString(), window->bounds().ToString());
114103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect occluded_window_bounds(50,
11431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      keyboard_bounds.y() + keyboard_bounds.height()/2, 50,
11441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      keyboard_bounds.height()/2);
11451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  window->SetBounds(occluded_window_bounds);
11461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(occluded_window_bounds.ToString(),
11471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      occluded_window_bounds.ToString());
11481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ShowKeyboard();
11491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Rect(50,
11501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      keyboard_bounds.y() - keyboard_bounds.height()/2,
11511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      occluded_window_bounds.width(),
11521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      occluded_window_bounds.height()).ToString(),
11531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            window->bounds().ToString());
11541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HideKeyboard();
11551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(occluded_window_bounds.ToString(), window->bounds().ToString());
11561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
11571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Blur(&text_input_client);
115846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
115946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
1161