#include "ash/wm/tablet_mode/tablet_mode_window_manager.h"
#include <string>
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/public/cpp/overview_test_api.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shelf_prefs.h"
#include "ash/public/cpp/test/shell_test_api.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/session/test_session_controller_client.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_metrics.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/splitview/split_view_constants.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/splitview/split_view_divider.h"
#include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/switchable_windows.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_observer.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "ash/wm/work_area_insets.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chromeos/ui/base/window_state_type.h"
#include "chromeos/ui/frame/caption_buttons/snap_controller.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/base/mojom/window_show_state.mojom.h"
#include "ui/compositor/layer.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/ime_util_chromeos.h"
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
namespace ash {
using ::chromeos::WindowStateType;
void SetShelfAutoHideBehaviorPref(int64_t display_id,
ShelfAutoHideBehavior behavior) {
PrefService* prefs =
Shell::Get()->session_controller()->GetLastActiveUserPrefService();
if (!prefs)
return;
SetShelfAutoHideBehaviorPref(prefs, display_id, behavior);
}
class TabletModeWindowManagerTest : public AshTestBase {
public:
TabletModeWindowManagerTest() = default;
TabletModeWindowManagerTest(const TabletModeWindowManagerTest&) = delete;
TabletModeWindowManagerTest& operator=(const TabletModeWindowManagerTest&) =
delete;
~TabletModeWindowManagerTest() override = default;
struct InitParams {
explicit InitParams(aura::client::WindowType t) : type(t) {}
aura::client::WindowType type = aura::client::WINDOW_TYPE_NORMAL;
gfx::Rect bounds;
gfx::Size max_size;
bool can_maximize = true;
bool can_resize = true;
bool show_on_creation = true;
};
aura::Window* CreateFixedSizeNonMaximizableWindow(
aura::client::WindowType type,
const gfx::Rect& bounds) {
InitParams params(type);
params.bounds = bounds;
params.can_maximize = false;
params.can_resize = false;
return CreateWindowInWatchedContainer(params);
}
aura::Window* CreateNonMaximizableWindow(aura::client::WindowType type,
const gfx::Rect& bounds,
const gfx::Size& max_size) {
InitParams params(type);
params.bounds = bounds;
params.max_size = max_size;
params.can_maximize = false;
return CreateWindowInWatchedContainer(params);
}
aura::Window* CreateWindow(aura::client::WindowType type,
const gfx::Rect bounds) {
InitParams params(type);
params.bounds = bounds;
return CreateWindowInWatchedContainer(params);
}
aura::Window* CreateWindowWithWidget(const gfx::Rect& bounds) {
views::Widget* widget =
views::Widget::CreateWindowWithContext(nullptr, GetContext(), bounds);
widget->Show();
return widget->GetNativeWindow();
}
TabletModeWindowManager* CreateTabletModeWindowManager() {
EXPECT_FALSE(TabletModeControllerTestApi().tablet_mode_window_manager());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
return TabletModeControllerTestApi().tablet_mode_window_manager();
}
void DestroyTabletModeWindowManager() {
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_FALSE(TabletModeControllerTestApi().tablet_mode_window_manager());
}
void ResizeDesktop(int width_delta) {
gfx::Size size =
display::Screen::Get()
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow())
.size();
size.Enlarge(0, width_delta);
UpdateDisplay(size.ToString());
}
aura::Window* CreateWindowInWatchedContainer(const InitParams& params) {
aura::test::TestWindowDelegate* delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate();
if (!params.can_maximize) {
delegate->set_window_component(HTCAPTION);
if (!params.max_size.IsEmpty())
delegate->set_maximum_size(params.max_size);
}
aura::Window* window =
aura::test::CreateTestWindow({.delegate = delegate,
.bounds = params.bounds,
.window_type = params.type,
.show = params.show_on_creation})
.release();
int32_t behavior = aura::client::kResizeBehaviorNone |
aura::client::kResizeBehaviorCanFullscreen;
behavior |= params.can_resize ? aura::client::kResizeBehaviorCanResize : 0;
behavior |=
params.can_maximize ? aura::client::kResizeBehaviorCanMaximize : 0;
window->SetProperty(aura::client::kResizeBehaviorKey, behavior);
aura::Window* container =
GetSwitchableContainersForRoot(Shell::GetPrimaryRootWindow(),
true)[0];
container->AddChild(window);
return window;
}
SplitViewController* split_view_controller() {
return SplitViewController::Get(Shell::GetPrimaryRootWindow());
}
};
TEST_F(TabletModeWindowManagerTest, SimpleStart) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, PreCreateWindows) {
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(10, 60, 200, 50);
gfx::Rect rect3(20, 140, 100, 100);
gfx::Rect rect(80, 90, 100, 110);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect3));
std::unique_ptr<aura::Window> w4(
CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
std::unique_ptr<aura::Window> w5(
CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
std::unique_ptr<aura::Window> w6(
CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_TRUE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_NE(rect3.origin().ToString(), w3->bounds().origin().ToString());
EXPECT_EQ(rect3.size().ToString(), w3->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(w4.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w5.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w6.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, GoingToMaximizedWithModalDialogPresent) {
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(10, 60, 200, 50);
gfx::Rect rect3(20, 140, 100, 100);
gfx::Rect rect(80, 90, 100, 110);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect3));
std::unique_ptr<aura::Window> w4(
CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
std::unique_ptr<aura::Window> w5(
CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
std::unique_ptr<aura::Window> w6(
CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
ShellTestApi().SimulateModalWindowOpenForTest(true);
EXPECT_TRUE(Shell::IsSystemModalWindowOpen());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_TRUE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_NE(rect3.origin().ToString(), w3->bounds().origin().ToString());
EXPECT_EQ(rect3.size().ToString(), w3->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(w4.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w5.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w6.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest,
PreCreateNonMaximizableButResizableWindows) {
gfx::Rect rect(10, 10, 200, 50);
gfx::Size max_size(300, 200);
gfx::Size empty_size;
std::unique_ptr<aura::Window> unlimited_window(CreateNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect, empty_size));
std::unique_ptr<aura::Window> limited_window(CreateNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect, max_size));
std::unique_ptr<aura::Window> fixed_window(
CreateFixedSizeNonMaximizableWindow(aura::client::WINDOW_TYPE_NORMAL,
rect));
EXPECT_FALSE(WindowState::Get(unlimited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(limited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(fixed_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_FALSE(WindowState::Get(unlimited_window.get())->IsMaximized());
EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
const gfx::Size workspace_size_tablet_mode =
screen_util::GetMaximizedWindowBoundsInParent(unlimited_window.get())
.size();
EXPECT_EQ(workspace_size_tablet_mode.ToString(),
unlimited_window->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(limited_window.get())->IsMaximized());
EXPECT_NE(rect.origin().ToString(),
limited_window->bounds().origin().ToString());
EXPECT_EQ(max_size.ToString(), limited_window->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(fixed_window.get())->IsMaximized());
EXPECT_NE(rect.origin().ToString(),
fixed_window->bounds().origin().ToString());
EXPECT_EQ(rect.size().ToString(), fixed_window->bounds().size().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(unlimited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(limited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(fixed_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, CreateWindows) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(10, 60, 200, 50);
gfx::Rect rect3(20, 140, 100, 100);
gfx::Rect rect(80, 90, 100, 110);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect3));
std::unique_ptr<aura::Window> w4(
CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
std::unique_ptr<aura::Window> w5(
CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
std::unique_ptr<aura::Window> w6(
CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
EXPECT_TRUE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_TRUE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
gfx::Size work_area_size =
screen_util::GetDisplayWorkAreaBoundsInParent(w3.get()).size();
gfx::Point center =
gfx::Point((work_area_size.width() - rect3.size().width()) / 2,
(work_area_size.height() - rect3.size().height()) / 2);
gfx::Rect centered_window_bounds = gfx::Rect(center, rect3.size());
EXPECT_EQ(centered_window_bounds.ToString(), w3->bounds().ToString());
EXPECT_FALSE(WindowState::Get(w4.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w5.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w6.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest,
CreateWindowInTabletModeRestoresToUsefulSize) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
gfx::Rect empty_rect(0, 0, 0, 0);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, empty_rect));
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
EXPECT_NE(empty_rect.ToString(), window->bounds().ToString());
gfx::Rect maximized_size = window->bounds();
const gfx::Insets tablet_insets =
WorkAreaInsets::ForWindow(window.get())->user_work_area_insets();
DestroyTabletModeWindowManager();
const gfx::Insets clamshell_insets =
WorkAreaInsets::ForWindow(window.get())->user_work_area_insets();
const gfx::Insets offset_difference = clamshell_insets - tablet_insets;
maximized_size.Inset(offset_difference);
EXPECT_FALSE(WindowState::Get(window.get())->IsMaximized());
EXPECT_EQ(maximized_size.ToString(), window->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, CreateNonMaximizableButResizableWindows) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
gfx::Rect rect(10, 10, 200, 50);
gfx::Size max_size(300, 200);
gfx::Size empty_size;
std::unique_ptr<aura::Window> unlimited_window(CreateNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect, empty_size));
std::unique_ptr<aura::Window> limited_window(CreateNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect, max_size));
std::unique_ptr<aura::Window> fixed_window(
CreateFixedSizeNonMaximizableWindow(aura::client::WINDOW_TYPE_NORMAL,
rect));
gfx::Size workspace_size =
screen_util::GetMaximizedWindowBoundsInParent(unlimited_window.get())
.size();
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_FALSE(WindowState::Get(unlimited_window.get())->IsMaximized());
EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
EXPECT_EQ(workspace_size.ToString(),
unlimited_window->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(limited_window.get())->IsMaximized());
EXPECT_NE(rect.origin().ToString(),
limited_window->bounds().origin().ToString());
EXPECT_EQ(max_size.ToString(), limited_window->bounds().size().ToString());
EXPECT_FALSE(WindowState::Get(fixed_window.get())->IsMaximized());
EXPECT_NE(rect.origin().ToString(),
fixed_window->bounds().origin().ToString());
EXPECT_EQ(rect.size().ToString(), fixed_window->bounds().size().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(unlimited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(limited_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
EXPECT_FALSE(WindowState::Get(fixed_window.get())->IsMaximized());
EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
}
std::string GetPlacementString(const gfx::Rect& bounds,
ui::mojom::WindowShowState state) {
return bounds.ToString() + ' ' +
base::NumberToString(static_cast<int>(state));
}
std::string GetPlacementOverride(aura::Window* window) {
gfx::Rect* bounds = window->GetProperty(kRestoreBoundsOverrideKey);
if (!bounds)
return std::string();
const auto type = window->GetProperty(kRestoreWindowStateTypeOverrideKey);
return GetPlacementString(*bounds, ToWindowShowState(type));
}
TEST_F(TabletModeWindowManagerTest, TestRestoreIntegrety) {
gfx::Rect bounds(10, 10, 200, 50);
std::unique_ptr<aura::Window> normal_window(CreateWindowWithWidget(bounds));
std::unique_ptr<aura::Window> maximized_window(
CreateWindowWithWidget(bounds));
WindowState::Get(maximized_window.get())->Maximize();
EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(GetPlacementString(bounds, ui::mojom::WindowShowState::kDefault),
GetPlacementOverride(normal_window.get()));
EXPECT_EQ(GetPlacementString(bounds, ui::mojom::WindowShowState::kMaximized),
GetPlacementOverride(maximized_window.get()));
WindowState::Get(maximized_window.get())->Minimize();
EXPECT_EQ(GetPlacementString(bounds, ui::mojom::WindowShowState::kMaximized),
GetPlacementOverride(maximized_window.get()));
DestroyTabletModeWindowManager();
EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
WindowState::Get(maximized_window.get())->Restore();
gfx::Rect new_bounds(10, 10, 200, 50);
maximized_window->SetBounds(new_bounds);
EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
}
TEST_F(TabletModeWindowManagerTest, PreCreateWindowsDeleteWhileActive) {
TabletModeWindowManager* manager = NULL;
{
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(10, 60, 200, 50);
gfx::Rect rect3(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect3));
manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
}
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, CreateWindowsAndDeleteWhileActive) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
{
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(10, 60, 200, 50);
gfx::Rect rect3(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect3));
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_TRUE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w3.get())->IsMaximized());
}
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, MaximizedShouldRemainMaximized) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState::Get(window.get())->Maximize();
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
DestroyTabletModeWindowManager();
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
WindowState::Get(window.get())->Restore();
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, MinimizedWindowBehavior) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> initially_minimized_window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> initially_normal_window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> initially_maximized_window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState::Get(initially_minimized_window.get())->Minimize();
WindowState::Get(initially_maximized_window.get())->Maximize();
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(
WindowState::Get(initially_minimized_window.get())->IsMinimized());
EXPECT_TRUE(WindowState::Get(initially_normal_window.get())->IsMaximized());
EXPECT_TRUE(
WindowState::Get(initially_maximized_window.get())->IsMaximized());
WindowState::Get(initially_normal_window.get())->Minimize();
WindowState::Get(initially_maximized_window.get())->Minimize();
EXPECT_TRUE(
WindowState::Get(initially_minimized_window.get())->IsMinimized());
EXPECT_TRUE(WindowState::Get(initially_normal_window.get())->IsMinimized());
EXPECT_TRUE(
WindowState::Get(initially_maximized_window.get())->IsMinimized());
DestroyTabletModeWindowManager();
EXPECT_TRUE(
WindowState::Get(initially_minimized_window.get())->IsMinimized());
EXPECT_FALSE(WindowState::Get(initially_normal_window.get())->IsMinimized());
EXPECT_TRUE(
WindowState::Get(initially_maximized_window.get())->IsMaximized());
}
TEST_F(TabletModeWindowManagerTest, DesktopSizeChangeMovesUnmaximizable) {
UpdateDisplay("500x400");
gfx::Rect rect(20, 300, 100, 100);
std::unique_ptr<aura::Window> window1(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
EXPECT_EQ(rect.ToString(), window1->bounds().ToString());
gfx::Rect rect2(20, 140, 100, 100);
std::unique_ptr<aura::Window> window2(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect2));
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(2, manager->GetNumberOfManagedWindows());
gfx::Rect moved_bounds(window1->bounds());
EXPECT_NE(rect.origin().ToString(), moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), moved_bounds.size().ToString());
UpdateDisplay("400x300");
gfx::Rect new_moved_bounds(window1->bounds());
EXPECT_NE(rect.origin().ToString(), new_moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), new_moved_bounds.size().ToString());
EXPECT_NE(moved_bounds.origin().ToString(), new_moved_bounds.ToString());
DestroyTabletModeWindowManager();
EXPECT_NE(rect.ToString(), window1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), window2->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, SizeChangeReturnWindowToOriginalPos) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> window(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
gfx::Rect moved_bounds(window->bounds());
EXPECT_NE(rect.origin().ToString(), moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), moved_bounds.size().ToString());
ResizeDesktop(-10);
gfx::Rect new_moved_bounds(window->bounds());
EXPECT_NE(rect.origin().ToString(), new_moved_bounds.origin().ToString());
EXPECT_EQ(rect.size().ToString(), new_moved_bounds.size().ToString());
EXPECT_NE(moved_bounds.origin().ToString(), new_moved_bounds.ToString());
ResizeDesktop(10);
DestroyTabletModeWindowManager();
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, ModeChangeKeepsMRUOrder) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> w2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> w3(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> w4(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> w5(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
{
aura::Window::Windows windows =
Shell::Get()->mru_window_tracker()->BuildMruWindowList(kAllDesks);
EXPECT_EQ(w1.get(), windows[4]);
EXPECT_EQ(w2.get(), windows[3]);
EXPECT_EQ(w3.get(), windows[2]);
EXPECT_EQ(w4.get(), windows[1]);
EXPECT_EQ(w5.get(), windows[0]);
}
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(5, manager->GetNumberOfManagedWindows());
{
aura::Window::Windows windows =
Shell::Get()->mru_window_tracker()->BuildMruWindowList(kAllDesks);
EXPECT_EQ(w1.get(), windows[4]);
EXPECT_EQ(w2.get(), windows[3]);
EXPECT_EQ(w3.get(), windows[2]);
EXPECT_EQ(w4.get(), windows[1]);
EXPECT_EQ(w5.get(), windows[0]);
}
DestroyTabletModeWindowManager();
{
aura::Window::Windows windows =
Shell::Get()->mru_window_tracker()->BuildMruWindowList(kAllDesks);
EXPECT_EQ(w1.get(), windows[4]);
EXPECT_EQ(w2.get(), windows[3]);
EXPECT_EQ(w3.get(), windows[2]);
EXPECT_EQ(w4.get(), windows[1]);
EXPECT_EQ(w5.get(), windows[0]);
}
}
TEST_F(TabletModeWindowManagerTest, IgnoreRestoreStateChages) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsMaximized());
window_state->Minimize();
EXPECT_TRUE(window_state->IsMinimized());
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, TestMinimize) {
gfx::Rect rect(10, 10, 100, 100);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
window_state->Minimize();
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_TRUE(window_state->IsMinimized());
EXPECT_FALSE(window->IsVisible());
window_state->Maximize();
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
}
TEST_F(TabletModeWindowManagerTest, MinimizedEnterAndLeaveTabletMode) {
gfx::Rect rect(10, 10, 100, 100);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
window_state->Minimize();
EXPECT_TRUE(window_state->IsMinimized());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_TRUE(window_state->IsMinimized());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_TRUE(window_state->IsMinimized());
window_state->Unminimize();
EXPECT_FALSE(window_state->IsMinimized());
window_state->Minimize();
EXPECT_TRUE(window_state->IsMinimized());
}
TEST_F(TabletModeWindowManagerTest, PersistPreMinimizedShowState) {
gfx::Rect rect(10, 10, 100, 100);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
window_state->Maximize();
window_state->Minimize();
EXPECT_EQ(ui::mojom::WindowShowState::kMaximized,
window->GetProperty(aura::client::kRestoreShowStateKey));
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
window_state->Unminimize();
EXPECT_EQ(ui::mojom::WindowShowState::kMaximized,
window->GetProperty(aura::client::kRestoreShowStateKey));
window_state->Minimize();
EXPECT_EQ(ui::mojom::WindowShowState::kMaximized,
window->GetProperty(aura::client::kRestoreShowStateKey));
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
window_state->Unminimize();
EXPECT_TRUE(window_state->IsMaximized());
}
TEST_F(TabletModeWindowManagerTest, UnminimizeInTabletMode) {
gfx::Rect rect(10, 10, 100, 100);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
window_state->Maximize();
window_state->Minimize();
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
window_state->Unminimize();
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_TRUE(window_state->IsMaximized());
window_state->Restore();
EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->GetBoundsInScreen());
window_state->Minimize();
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
window_state->Unminimize();
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->GetBoundsInScreen());
}
TEST_F(TabletModeWindowManagerTest, UnminimizeSnapInTabletMode) {
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
std::unique_ptr<aura::Window> window = CreateAppWindow();
auto* window_state = WindowState::Get(window.get());
WindowSnapWMEvent event(WM_EVENT_SNAP_PRIMARY);
window_state->OnWMEvent(&event);
ASSERT_TRUE(window_state->IsSnapped());
window_state->Minimize();
window_state->Unminimize();
EXPECT_TRUE(window_state->IsSnapped());
}
TEST_F(TabletModeWindowManagerTest, KeepFullScreenModeOn) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
Shelf* shelf = GetPrimaryShelf();
SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
ShelfAutoHideBehavior::kAlways);
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event);
EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
window_state->OnWMEvent(&event);
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
}
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case1) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_FALSE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_PIN);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
window_state->Restore();
EXPECT_FALSE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
}
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case2) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_FALSE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_PIN);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
window_state->Restore();
EXPECT_FALSE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
}
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case3) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_FALSE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_PIN);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
window_state->Restore();
EXPECT_FALSE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case4) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_FALSE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_PIN);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsPinned());
window_state->Restore();
EXPECT_FALSE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
}
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case5) {
std::unique_ptr<aura::Window> w1(CreateWindow(
aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(20, 140, 100, 100)));
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_FALSE(window_state->IsPinned());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_PIN);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
{
WMEvent event(WM_EVENT_ADDED_TO_WORKSPACE);
window_state->OnWMEvent(&event);
}
EXPECT_TRUE(window_state->IsPinned());
window_state->Restore();
EXPECT_FALSE(window_state->IsPinned());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsPinned());
}
TEST_F(TabletModeWindowManagerTest, MinimizePreservedAfterLeavingFullscreen) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
Shelf* shelf = GetPrimaryShelf();
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event);
ASSERT_FALSE(window_state->IsMinimized());
CreateTabletModeWindowManager();
window_state->OnWMEvent(&event);
window_state->Minimize();
ASSERT_TRUE(window_state->IsMinimized());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsMinimized());
}
TEST_F(TabletModeWindowManagerTest, DoNotDisableAutoHideBehaviorOnTabletMode) {
Shelf* shelf = GetPrimaryShelf();
SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
ShelfAutoHideBehavior::kAlways);
EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());
CreateTabletModeWindowManager();
EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());
DestroyTabletModeWindowManager();
EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());
}
TEST_F(TabletModeWindowManagerTest, AllowFullScreenMode) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
Shelf* shelf = GetPrimaryShelf();
SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
ShelfAutoHideBehavior::kAlways);
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
CreateTabletModeWindowManager();
EXPECT_FALSE(window_state->IsFullscreen());
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event);
EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
}
TEST_F(TabletModeWindowManagerTest,
FullScreenModeRemainsWhenCreatedInTabletMode) {
CreateTabletModeWindowManager();
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
WMEvent event_full_screen(WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event_full_screen);
EXPECT_TRUE(window_state->IsFullscreen());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen());
}
TEST_F(TabletModeWindowManagerTest,
FullScreenModeRemainsThroughTabletModeSwitch) {
gfx::Rect rect(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(w1.get());
WMEvent event_full_screen(WM_EVENT_TOGGLE_FULLSCREEN);
window_state->OnWMEvent(&event_full_screen);
EXPECT_TRUE(window_state->IsFullscreen());
CreateTabletModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen());
DestroyTabletModeWindowManager();
EXPECT_TRUE(window_state->IsFullscreen());
}
TEST_F(TabletModeWindowManagerTest,
CreateAndMaximizeInTabletModeShouldRetoreToGoodSizeGoingToDefault) {
CreateTabletModeWindowManager();
gfx::Rect rect;
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
w1->Show();
WindowState* window_state = WindowState::Get(w1.get());
EXPECT_TRUE(window_state->IsMaximized());
window_state->SetRestoreBoundsInScreen(rect);
EXPECT_TRUE(window_state->GetRestoreBoundsInScreen().IsEmpty());
gfx::Rect requested_bounds(10, 20, 50, 70);
w1->SetBounds(requested_bounds);
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(requested_bounds.ToString(),
window_state->GetRestoreBoundsInScreen().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(w1->bounds().ToString(), requested_bounds.ToString());
}
TEST_F(TabletModeWindowManagerTest, TryToDesktopSizeDragUnmaximizable) {
gfx::Rect rect(10, 10, 100, 100);
std::unique_ptr<aura::Window> window(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
generator.MoveMouseTo(gfx::Point(rect.x() + 2, rect.y() + 2));
generator.PressLeftButton();
generator.MoveMouseBy(10, 5);
base::RunLoop().RunUntilIdle();
generator.ReleaseLeftButton();
gfx::Point first_dragged_origin = window->bounds().origin();
EXPECT_EQ(rect.x() + 10, first_dragged_origin.x());
EXPECT_EQ(rect.y() + 5, first_dragged_origin.y());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
gfx::Rect center_bounds(window->bounds());
EXPECT_NE(rect.origin().ToString(), center_bounds.origin().ToString());
generator.MoveMouseTo(
gfx::Point(center_bounds.x() + 1, center_bounds.y() + 1));
generator.PressLeftButton();
generator.MoveMouseBy(10, 5);
base::RunLoop().RunUntilIdle();
generator.ReleaseLeftButton();
EXPECT_EQ(center_bounds.x(), window->bounds().x());
EXPECT_EQ(center_bounds.y(), window->bounds().y());
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
generator.MoveMouseTo(
gfx::Point(first_dragged_origin.x() + 1, first_dragged_origin.y() + 1));
generator.PressLeftButton();
generator.MoveMouseBy(10, 5);
base::RunLoop().RunUntilIdle();
generator.ReleaseLeftButton();
EXPECT_EQ(first_dragged_origin.x() + 10, window->bounds().x());
EXPECT_EQ(first_dragged_origin.y() + 5, window->bounds().y());
}
TEST_F(TabletModeWindowManagerTest, AlwaysOnTopWindows) {
gfx::Rect rect1(10, 10, 200, 50);
gfx::Rect rect2(20, 140, 100, 100);
std::unique_ptr<aura::Window> w1(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
std::unique_ptr<aura::Window> w2(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect2));
w1->SetProperty(aura::client::kZOrderingKey,
ui::ZOrderLevel::kFloatingWindow);
w2->SetProperty(aura::client::kZOrderingKey,
ui::ZOrderLevel::kFloatingWindow);
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
w1->SetProperty(aura::client::kZOrderingKey, ui::ZOrderLevel::kNormal);
w2->SetProperty(aura::client::kZOrderingKey, ui::ZOrderLevel::kNormal);
EXPECT_EQ(2, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_NE(rect1.origin().ToString(), w1->bounds().origin().ToString());
EXPECT_NE(rect1.size().ToString(), w1->bounds().size().ToString());
EXPECT_NE(rect2.origin().ToString(), w2->bounds().origin().ToString());
EXPECT_EQ(rect2.size().ToString(), w2->bounds().size().ToString());
w1->SetProperty(aura::client::kZOrderingKey,
ui::ZOrderLevel::kFloatingWindow);
w2->SetProperty(aura::client::kZOrderingKey,
ui::ZOrderLevel::kFloatingWindow);
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(w1.get())->IsMaximized());
EXPECT_FALSE(WindowState::Get(w2.get())->IsMaximized());
EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
}
TEST_F(TabletModeWindowManagerTest, DontMaximizeClientManagedWindows) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState::Get(window.get())->set_allow_set_bounds_direct(true);
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(window.get())->IsMaximized());
EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
}
TEST_F(TabletModeWindowManagerTest, CreateManagerInLockScreen) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
ASSERT_FALSE(WindowState::Get(window.get())->IsMaximized());
GetSessionControllerClient()->RequestLockScreen();
CreateTabletModeWindowManager();
GetSessionControllerClient()->UnlockScreen();
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
DestroyTabletModeWindowManager();
EXPECT_FALSE(WindowState::Get(window.get())->IsMaximized());
}
namespace {
class TestObserver : public WindowStateObserver {
public:
TestObserver() = default;
TestObserver(const TestObserver&) = delete;
TestObserver& operator=(const TestObserver&) = delete;
~TestObserver() override = default;
void OnPreWindowStateTypeChange(WindowState* window_state,
WindowStateType old_type) override {
pre_count_++;
last_old_state_ = old_type;
}
void OnPostWindowStateTypeChange(WindowState* window_state,
WindowStateType old_type) override {
post_count_++;
post_layer_visibility_ = window_state->window()->layer()->visible();
EXPECT_EQ(last_old_state_, old_type);
}
int GetPreCountAndReset() {
int r = pre_count_;
pre_count_ = 0;
return r;
}
int GetPostCountAndReset() {
int r = post_count_;
post_count_ = 0;
return r;
}
bool GetPostLayerVisibilityAndReset() {
bool r = post_layer_visibility_;
post_layer_visibility_ = false;
return r;
}
WindowStateType GetLastOldStateAndReset() {
WindowStateType r = last_old_state_;
last_old_state_ = WindowStateType::kDefault;
return r;
}
private:
int pre_count_ = 0;
int post_count_ = 0;
bool post_layer_visibility_ = false;
WindowStateType last_old_state_ = WindowStateType::kDefault;
};
}
TEST_F(TabletModeWindowManagerTest, StateTypeChange) {
TestObserver observer;
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
CreateTabletModeWindowManager();
WindowState* window_state = WindowState::Get(window.get());
window_state->AddObserver(&observer);
window->Show();
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_EQ(0, observer.GetPreCountAndReset());
EXPECT_EQ(0, observer.GetPostCountAndReset());
WMEvent maximize_event(WM_EVENT_MAXIMIZE);
window_state->OnWMEvent(&maximize_event);
EXPECT_EQ(0, observer.GetPreCountAndReset());
EXPECT_EQ(0, observer.GetPostCountAndReset());
WMEvent fullscreen_event(WM_EVENT_FULLSCREEN);
window_state->OnWMEvent(&fullscreen_event);
EXPECT_EQ(1, observer.GetPreCountAndReset());
EXPECT_EQ(1, observer.GetPostCountAndReset());
EXPECT_EQ(WindowStateType::kMaximized, observer.GetLastOldStateAndReset());
window_state->OnWMEvent(&maximize_event);
EXPECT_EQ(1, observer.GetPreCountAndReset());
EXPECT_EQ(1, observer.GetPostCountAndReset());
EXPECT_EQ(WindowStateType::kFullscreen, observer.GetLastOldStateAndReset());
WMEvent minimize_event(WM_EVENT_MINIMIZE);
window_state->OnWMEvent(&minimize_event);
EXPECT_EQ(1, observer.GetPreCountAndReset());
EXPECT_EQ(1, observer.GetPostCountAndReset());
EXPECT_EQ(WindowStateType::kMaximized, observer.GetLastOldStateAndReset());
WMEvent restore_event(WM_EVENT_NORMAL);
window_state->OnWMEvent(&restore_event);
EXPECT_EQ(1, observer.GetPreCountAndReset());
EXPECT_EQ(1, observer.GetPostCountAndReset());
EXPECT_EQ(WindowStateType::kMinimized, observer.GetLastOldStateAndReset());
EXPECT_EQ(true, observer.GetPostLayerVisibilityAndReset());
window_state->RemoveObserver(&observer);
DestroyTabletModeWindowManager();
}
TEST_F(TabletModeWindowManagerTest, SetPropertyOnUnmanagedWindow) {
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
InitParams params(aura::client::WINDOW_TYPE_NORMAL);
params.bounds = {10, 10, 100, 100};
params.show_on_creation = false;
std::unique_ptr<aura::Window> window(CreateWindowInWatchedContainer(params));
WindowState::Get(window.get())->set_allow_set_bounds_direct(true);
window->SetProperty(aura::client::kZOrderingKey,
ui::ZOrderLevel::kFloatingWindow);
window->Show();
}
TEST_F(TabletModeWindowManagerTest, ShowAfterCreateionKeepsFullscreenState) {
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
InitParams params(aura::client::WINDOW_TYPE_NORMAL);
params.bounds = {10, 10, 100, 100};
params.show_on_creation = false;
std::unique_ptr<aura::Window> window(CreateWindowInWatchedContainer(params));
::wm::SetWindowFullscreen(window.get(), true);
window->Show();
EXPECT_TRUE(::wm::WindowStateIs(window.get(),
ui::mojom::WindowShowState::kFullscreen));
}
TEST_F(TabletModeWindowManagerTest, DontChangeBoundsForMinimizedWindow) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
window_state->Minimize();
EXPECT_TRUE(window_state->IsMinimized());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
ASSERT_TRUE(manager);
EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(window_state->IsMinimized());
EXPECT_EQ(window->bounds(), rect);
EnterOverview();
EXPECT_EQ(window->bounds(), rect);
ExitOverview();
EXPECT_EQ(window->bounds(), rect);
}
TEST_F(TabletModeWindowManagerTest, DontMaximizeTransientChild) {
gfx::Rect rect(0, 0, 200, 200);
std::unique_ptr<aura::Window> parent(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<aura::Window> child(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
::wm::TransientWindowManager::GetOrCreate(parent.get())
->AddTransientChild(child.get());
ASSERT_TRUE(CreateTabletModeWindowManager());
EXPECT_TRUE(WindowState::Get(parent.get())->IsMaximized());
EXPECT_NE(rect.size(), parent->bounds().size());
EXPECT_FALSE(WindowState::Get(child.get())->IsMaximized());
EXPECT_EQ(rect.size(), child->bounds().size());
}
TEST_F(TabletModeWindowManagerTest, AllowNormalWindowBoundsChangeByVK) {
UpdateDisplay("1200x800");
gfx::Rect rect(0, 0, 1200, 600);
std::unique_ptr<aura::Window> window(CreateFixedSizeNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect));
ASSERT_TRUE(CreateTabletModeWindowManager());
WindowState* window_state = WindowState::Get(window.get());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(WindowStateType::kNormal, window_state->GetStateType());
gfx::Rect window_bounds = window->bounds();
wm::EnsureWindowNotInRect(window.get(), gfx::Rect(0, 600, 1200, 200));
EXPECT_NE(window->bounds(), window_bounds);
wm::RestoreWindowBoundsOnClientFocusLost(window.get());
EXPECT_EQ(window->bounds(), window_bounds);
}
TEST_F(TabletModeWindowManagerTest, ClamshellTabletTransitionTest) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
OverviewController* overview_controller = OverviewController::Get();
EXPECT_TRUE(EnterOverview());
EXPECT_TRUE(overview_controller->InOverviewSession());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
EXPECT_TRUE(manager);
EXPECT_TRUE(overview_controller->InOverviewSession());
DestroyTabletModeWindowManager();
EXPECT_TRUE(overview_controller->InOverviewSession());
EXPECT_TRUE(ExitOverview());
EXPECT_FALSE(overview_controller->InOverviewSession());
CreateTabletModeWindowManager();
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
DestroyTabletModeWindowManager();
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_FALSE(WindowState::Get(window.get())->IsMaximized());
const WindowSnapWMEvent event(WM_EVENT_SNAP_PRIMARY);
WindowState::Get(window.get())->OnWMEvent(&event);
EXPECT_TRUE(WindowState::Get(window.get())->IsSnapped());
CreateTabletModeWindowManager();
EXPECT_TRUE(overview_controller->InOverviewSession());
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(WindowState::Get(window.get())->IsSnapped());
DestroyTabletModeWindowManager();
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_FALSE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(WindowState::Get(window.get())->IsSnapped());
std::unique_ptr<aura::Window> window2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
wm::ActivateWindow(window2.get());
CreateTabletModeWindowManager();
EXPECT_TRUE(WindowState::Get(window.get())->IsMaximized());
EXPECT_TRUE(WindowState::Get(window2.get())->IsMaximized());
split_view_controller()->SnapWindow(window.get(), SnapPosition::kPrimary);
split_view_controller()->SnapWindow(window2.get(), SnapPosition::kSecondary);
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_FALSE(overview_controller->InOverviewSession());
DestroyTabletModeWindowManager();
EXPECT_TRUE(WindowState::Get(window.get())->IsSnapped());
EXPECT_TRUE(WindowState::Get(window2.get())->IsSnapped());
EXPECT_FALSE(split_view_controller()->InSplitViewMode());
EXPECT_FALSE(overview_controller->InOverviewSession());
CreateTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_TRUE(WindowState::Get(window.get())->IsSnapped());
EXPECT_TRUE(WindowState::Get(window2.get())->IsSnapped());
EnterOverview();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(overview_controller->InOverviewSession());
DestroyTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(overview_controller->InOverviewSession());
CreateTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(overview_controller->InOverviewSession());
}
TEST_F(TabletModeWindowManagerTest,
ClamshellTabletTransitionDividerPositionTest) {
UpdateDisplay("1200x800");
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
OverviewController* overview_controller = OverviewController::Get();
const WindowSnapWMEvent left_snap_event(WM_EVENT_SNAP_PRIMARY);
WindowState::Get(window.get())->OnWMEvent(&left_snap_event);
const gfx::Rect left_snapped_bounds =
gfx::Rect(1200 / 2, 800 - ShelfConfig::Get()->shelf_size());
EXPECT_EQ(window->bounds().width(), left_snapped_bounds.width());
window->SetBounds(gfx::Rect(400, left_snapped_bounds.height()));
CreateTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_TRUE(overview_controller->InOverviewSession());
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window.get()));
EXPECT_EQ(window->bounds().width(),
std::round(1200 * chromeos::kOneThirdSnapRatio) -
kSplitviewDividerShortSideLength / 2);
DestroyTabletModeWindowManager();
EXPECT_NEAR(window->bounds().width(),
std::round(1200 * chromeos::kOneThirdSnapRatio),
kSplitviewDividerShortSideLength / 2);
std::unique_ptr<aura::Window> window2(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState::Get(window.get())->OnWMEvent(&left_snap_event);
const WindowSnapWMEvent right_snap_event(WM_EVENT_SNAP_SECONDARY);
WindowState::Get(window2.get())->OnWMEvent(&right_snap_event);
window->SetBounds(gfx::Rect(400, left_snapped_bounds.height()));
window2->SetBounds(gfx::Rect(400, 0, 800, left_snapped_bounds.height()));
CreateTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->InSplitViewMode());
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window.get()));
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window2.get()));
EXPECT_EQ(window->bounds().width(),
std::round(1200 * chromeos::kOneThirdSnapRatio) -
kSplitviewDividerShortSideLength / 2);
EXPECT_EQ(window2->bounds().width(),
1200 - window->bounds().width() - kSplitviewDividerShortSideLength);
DestroyTabletModeWindowManager();
EXPECT_NEAR(window->bounds().width(),
std::round(1200 * chromeos::kOneThirdSnapRatio),
kSplitviewDividerShortSideLength / 2);
EXPECT_NEAR(window2->bounds().width(), 1200 - window->bounds().width(),
kSplitviewDividerShortSideLength / 2);
}
TEST_F(TabletModeWindowManagerTest, PartialClamshellTabletTransitionTest) {
auto window1 = CreateTestWindow();
OverviewController* overview_controller = OverviewController::Get();
const WindowSnapWMEvent snap_primary_two_third(WM_EVENT_SNAP_PRIMARY,
chromeos::kTwoThirdSnapRatio);
WindowState::Get(window1.get())->OnWMEvent(&snap_primary_two_third);
CreateTabletModeWindowManager();
EXPECT_TRUE(overview_controller->InOverviewSession());
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window1.get()));
const gfx::Rect work_area_bounds =
display::Screen::Get()->GetPrimaryDisplay().work_area();
int divider_origin_x = split_view_controller()
->split_view_divider()
->GetDividerBoundsInScreen(
false)
.x();
int divider_delta = kSplitviewDividerShortSideLength / 2;
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio),
window1->bounds().width() + divider_delta);
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio),
divider_origin_x + divider_delta);
DestroyTabletModeWindowManager();
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio),
window1->bounds().width());
auto window2 = CreateTestWindow();
const WindowSnapWMEvent snap_secondary_one_third(
WM_EVENT_SNAP_SECONDARY, chromeos::kOneThirdSnapRatio);
WindowState::Get(window2.get())->OnWMEvent(&snap_secondary_one_third);
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kOneThirdSnapRatio),
window2->bounds().width());
CreateTabletModeWindowManager();
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window1.get()));
EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window2.get()));
divider_origin_x = split_view_controller()
->split_view_divider()
->GetDividerBoundsInScreen(
false)
.x();
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio),
window1->bounds().width() + divider_delta);
EXPECT_EQ(std::round(work_area_bounds.width() * chromeos::kOneThirdSnapRatio),
window2->bounds().width() + divider_delta);
EXPECT_EQ(
std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio) -
divider_delta,
divider_origin_x);
DestroyTabletModeWindowManager();
if (!display::Screen::Get()->InTabletMode()) {
EXPECT_NEAR(
std::round(work_area_bounds.width() * chromeos::kTwoThirdSnapRatio),
window1->bounds().width(), divider_delta);
EXPECT_NEAR(
std::round(work_area_bounds.width() * chromeos::kOneThirdSnapRatio),
window2->bounds().width(), divider_delta);
} else {
EXPECT_EQ(
std::round(work_area_bounds.width() * chromeos::kOneThirdSnapRatio),
window2->bounds().width() + divider_delta);
}
}
TEST_F(TabletModeWindowManagerTest, HomeLauncherVisibilityTest) {
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
OverviewController* overview_controller = OverviewController::Get();
EXPECT_TRUE(EnterOverview());
EXPECT_TRUE(overview_controller->InOverviewSession());
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
EXPECT_TRUE(manager);
EXPECT_TRUE(overview_controller->InOverviewSession());
ShellTestApi().WaitForOverviewAnimationState(
OverviewAnimationState::kEnterAnimationComplete);
aura::Window* home_screen_window =
Shell::Get()->app_list_controller()->GetHomeScreenWindow();
EXPECT_FALSE(home_screen_window->TargetVisibility());
base::HistogramTester tester;
tester.ExpectBucketCount(
kHotseatGestureHistogramName,
InAppShelfGestures::kHotseatHiddenDueToInteractionOutsideOfShelf, 0);
GetEventGenerator()->GestureTapAt(window->GetBoundsInScreen().CenterPoint());
ShellTestApi().WaitForOverviewAnimationState(
OverviewAnimationState::kExitAnimationComplete);
tester.ExpectBucketCount(
kHotseatGestureHistogramName,
InAppShelfGestures::kHotseatHiddenDueToInteractionOutsideOfShelf, 0);
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_TRUE(home_screen_window->TargetVisibility());
}
TEST_F(TabletModeWindowManagerTest, BasicRestoreBehaviors) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
EXPECT_TRUE(manager);
gfx::Rect rect(10, 10, 200, 50);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
WindowState* window_state = WindowState::Get(window.get());
EXPECT_TRUE(window_state->IsMaximized());
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
const WindowSnapWMEvent snap_left(WM_EVENT_SNAP_PRIMARY);
window_state->OnWMEvent(&snap_left);
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
const WMEvent fullscreen_event(WM_EVENT_FULLSCREEN);
window_state->OnWMEvent(&fullscreen_event);
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
const WMEvent minimized_event(WM_EVENT_MINIMIZE);
window_state->OnWMEvent(&minimized_event);
window_state->Restore();
EXPECT_TRUE(window_state->IsMaximized());
window_state->OnWMEvent(&snap_left);
window_state->OnWMEvent(&fullscreen_event);
window_state->Restore();
EXPECT_TRUE(window_state->IsSnapped());
window_state->OnWMEvent(&minimized_event);
window_state->Restore();
EXPECT_TRUE(window_state->IsSnapped());
}
TEST_F(TabletModeWindowManagerTest, NonMaximizableWindowRestore) {
TabletModeWindowManager* manager = CreateTabletModeWindowManager();
EXPECT_TRUE(manager);
gfx::Rect rect(10, 10, 200, 50);
gfx::Size max_size(300, 200);
std::unique_ptr<aura::Window> window(CreateNonMaximizableWindow(
aura::client::WINDOW_TYPE_NORMAL, rect, max_size));
WindowState* window_state = WindowState::Get(window.get());
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_EQ(window_state->GetStateType(), WindowStateType::kNormal);
const WMEvent maximize_event(WM_EVENT_MAXIMIZE);
window_state->OnWMEvent(&maximize_event);
EXPECT_EQ(window_state->GetStateType(), WindowStateType::kNormal);
const WMEvent fullscreen_event(WM_EVENT_FULLSCREEN);
window_state->OnWMEvent(&fullscreen_event);
EXPECT_EQ(window_state->GetStateType(), WindowStateType::kFullscreen);
window_state->Restore();
EXPECT_EQ(window_state->GetStateType(), WindowStateType::kNormal);
window_state->Restore();
EXPECT_EQ(window_state->GetStateType(), WindowStateType::kNormal);
}
TEST_F(TabletModeWindowManagerTest, StateTypeOnAttachNewDragWindow) {
CreateTabletModeWindowManager();
{
std::unique_ptr<aura::Window> source_window =
CreateAppWindow(gfx::Rect(), chromeos::AppType::BROWSER);
WindowState* source_window_state = WindowState::Get(source_window.get());
std::unique_ptr<aura::Window> drag_window = CreateAppWindow(
gfx::Rect(), chromeos::AppType::BROWSER, kShellWindowId_Invalid,
nullptr, false);
WindowState* drag_window_state = WindowState::Get(drag_window.get());
drag_window->SetProperty(ash::kIsDraggingTabsKey, true);
drag_window->SetProperty(ash::kTabDraggingSourceWindowKey,
source_window.get());
EXPECT_EQ(source_window_state->GetStateType(), WindowStateType::kMaximized);
EXPECT_EQ(drag_window_state->GetStateType(), WindowStateType::kDefault);
drag_window->Show();
EXPECT_EQ(drag_window_state->GetStateType(), WindowStateType::kMaximized);
}
{
std::unique_ptr<aura::Window> source_window =
CreateAppWindow(gfx::Rect(), chromeos::AppType::BROWSER);
WindowState* source_window_state = WindowState::Get(source_window.get());
const WindowSnapWMEvent primary_snap_event(WM_EVENT_SNAP_PRIMARY);
source_window_state->OnWMEvent(&primary_snap_event);
std::unique_ptr<aura::Window> drag_window = CreateAppWindow(
gfx::Rect(), chromeos::AppType::BROWSER, kShellWindowId_Invalid,
nullptr, false);
WindowState* drag_window_state = WindowState::Get(drag_window.get());
drag_window->SetProperty(ash::kIsDraggingTabsKey, true);
drag_window->SetProperty(ash::kTabDraggingSourceWindowKey,
source_window.get());
EXPECT_EQ(source_window_state->GetStateType(),
WindowStateType::kPrimarySnapped);
EXPECT_EQ(drag_window_state->GetStateType(), WindowStateType::kDefault);
drag_window->Show();
EXPECT_EQ(drag_window_state->GetStateType(),
WindowStateType::kPrimarySnapped);
}
DestroyTabletModeWindowManager();
}
}