This source file includes following definitions.
- ShouldActivate
- IsWindowAbove
- GetWindowByName
- GetCopyWindow
- CancelDrag
- SetUp
- CreateWindow
- CreateNonActivatableWindow
- CreatePanelWindow
- WindowsOverlapping
- ToggleOverview
- Cycle
- StopCycling
- FireOverviewStartTimer
- GetTransformRelativeTo
- GetTransformedBounds
- GetTransformedTargetBounds
- GetTransformedBoundsInRootWindow
- ClickWindow
- IsSelecting
- GetFocusedWindow
- shelf_view_test
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/shelf_test_api.h"
#include "ash/test/shelf_view_test_api.h"
#include "ash/test/shell_test_api.h"
#include "ash/test/test_shelf_delegate.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/transform.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_delegate.h"
namespace ash {
namespace {
class NonActivatableActivationDelegate
: public aura::client::ActivationDelegate {
public:
virtual bool ShouldActivate() const OVERRIDE {
return false;
}
};
bool IsWindowAbove(aura::Window* w1, aura::Window* w2) {
aura::Window* parent = w1->parent();
DCHECK_EQ(parent, w2->parent());
for (aura::Window::Windows::const_iterator iter = parent->children().begin();
iter != parent->children().end(); ++iter) {
if (*iter == w1)
return false;
if (*iter == w2)
return true;
}
NOTREACHED();
return false;
}
aura::Window* GetWindowByName(aura::Window* container,
const std::string& name) {
aura::Window* window = NULL;
for (aura::Window::Windows::const_iterator iter =
container->children().begin(); iter != container->children().end();
++iter) {
if ((*iter)->name() == name) {
DCHECK(!window);
window = *iter;
}
}
return window;
}
aura::Window* GetCopyWindow(aura::Window* window) {
aura::Window* copy_window = NULL;
std::string copy_name = window->name() + " (Copy)";
std::vector<aura::Window*> containers(
Shell::GetContainersFromAllRootWindows(window->parent()->id(), NULL));
for (std::vector<aura::Window*>::iterator iter = containers.begin();
iter != containers.end(); ++iter) {
aura::Window* found = GetWindowByName(*iter, copy_name);
if (found) {
DCHECK(!copy_window);
copy_window = found;
}
}
return copy_window;
}
void CancelDrag(DragDropController* controller, bool* canceled) {
if (controller->IsDragDropInProgress()) {
*canceled = true;
controller->DragCancel();
}
}
}
class WindowSelectorTest : public test::AshTestBase {
public:
WindowSelectorTest() {}
virtual ~WindowSelectorTest() {}
virtual void SetUp() OVERRIDE {
test::AshTestBase::SetUp();
ASSERT_TRUE(test::TestShelfDelegate::instance());
shelf_view_test_.reset(new test::ShelfViewTestAPI(
test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view()));
shelf_view_test_->SetAnimationDuration(1);
}
aura::Window* CreateWindow(const gfx::Rect& bounds) {
return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
}
aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) {
aura::Window* window = CreateWindow(bounds);
aura::client::SetActivationDelegate(window,
&non_activatable_activation_delegate_);
EXPECT_FALSE(ash::wm::CanActivateWindow(window));
return window;
}
aura::Window* CreatePanelWindow(const gfx::Rect& bounds) {
aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
NULL, ui::wm::WINDOW_TYPE_PANEL, 0, bounds);
test::TestShelfDelegate::instance()->AddShelfItem(window);
shelf_view_test()->RunMessageLoopUntilAnimationsDone();
return window;
}
bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) {
gfx::RectF window1_bounds = GetTransformedTargetBounds(window1);
gfx::RectF window2_bounds = GetTransformedTargetBounds(window2);
return window1_bounds.Intersects(window2_bounds);
}
void ToggleOverview() {
ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview();
}
void Cycle(WindowSelector::Direction direction) {
ash::Shell::GetInstance()->window_selector_controller()->
HandleCycleWindow(direction);
}
void StopCycling() {
ash::Shell::GetInstance()->window_selector_controller()->window_selector_->
SelectWindow();
}
void FireOverviewStartTimer() {
ash::Shell::GetInstance()->window_selector_controller()->window_selector_->
StartOverview();
}
gfx::Transform GetTransformRelativeTo(gfx::PointF origin,
const gfx::Transform& transform) {
gfx::Transform t;
t.Translate(origin.x(), origin.y());
t.PreconcatTransform(transform);
t.Translate(-origin.x(), -origin.y());
return t;
}
gfx::RectF GetTransformedBounds(aura::Window* window) {
gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
window->parent(), window->layer()->bounds()));
gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
window->layer()->transform()));
transform.TransformRect(&bounds);
return bounds;
}
gfx::RectF GetTransformedTargetBounds(aura::Window* window) {
gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
window->parent(), window->layer()->GetTargetBounds()));
gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
window->layer()->GetTargetTransform()));
transform.TransformRect(&bounds);
return bounds;
}
gfx::RectF GetTransformedBoundsInRootWindow(aura::Window* window) {
gfx::RectF bounds = gfx::Rect(window->bounds().size());
aura::Window* root = window->GetRootWindow();
CHECK(window->layer());
CHECK(root->layer());
gfx::Transform transform;
if (!window->layer()->GetTargetTransformRelativeTo(root->layer(),
&transform)) {
return gfx::RectF();
}
transform.TransformRect(&bounds);
return bounds;
}
void ClickWindow(aura::Window* window) {
aura::test::EventGenerator event_generator(window->GetRootWindow(), window);
gfx::RectF target = GetTransformedBounds(window);
event_generator.ClickLeftButton();
}
bool IsSelecting() {
return ash::Shell::GetInstance()->window_selector_controller()->
IsSelecting();
}
aura::Window* GetFocusedWindow() {
return aura::client::GetFocusClient(
Shell::GetPrimaryRootWindow())->GetFocusedWindow();
}
test::ShelfViewTestAPI* shelf_view_test() {
return shelf_view_test_.get();
}
private:
aura::test::TestWindowDelegate delegate_;
NonActivatableActivationDelegate non_activatable_activation_delegate_;
scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_;
DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest);
};
TEST_F(WindowSelectorTest, Basic) {
gfx::Rect bounds(0, 0, 400, 400);
aura::Window* root_window = Shell::GetPrimaryRootWindow();
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
wm::ActivateWindow(window2.get());
EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
EXPECT_EQ(window2.get(), GetFocusedWindow());
aura::client::GetCursorClient(root_window)->HideCursor();
ToggleOverview();
EXPECT_EQ(NULL, GetFocusedWindow());
EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
EXPECT_FALSE(WindowsOverlapping(window1.get(), panel1.get()));
EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
EXPECT_EQ(ui::kCursorPointer,
root_window->GetHost()->last_cursor().native_type());
EXPECT_TRUE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
EXPECT_TRUE(aura::client::GetCursorClient(root_window)->IsCursorVisible());
ClickWindow(window1.get());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
EXPECT_EQ(window1.get(), GetFocusedWindow());
EXPECT_FALSE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
}
TEST_F(WindowSelectorTest, FullscreenWindow) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
wm::ActivateWindow(window1.get());
const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
wm::GetWindowState(window1.get())->OnWMEvent(&toggle_fullscreen_event);
EXPECT_FALSE(panel1->IsVisible());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
ToggleOverview();
EXPECT_TRUE(panel1->IsVisible());
ClickWindow(window1.get());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
EXPECT_FALSE(panel1->IsVisible());
ToggleOverview();
ClickWindow(window2.get());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
Cycle(WindowSelector::FORWARD);
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::GetWindowState(panel1.get())->IsActive());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
EXPECT_TRUE(panel1->IsVisible());
}
TEST_F(WindowSelectorTest, OverviewUndimsShelf) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
wm::WindowState* window_state = wm::GetWindowState(window1.get());
window_state->Maximize();
ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
EXPECT_TRUE(shelf->GetDimsShelf());
ToggleOverview();
EXPECT_FALSE(shelf->GetDimsShelf());
ToggleOverview();
EXPECT_TRUE(shelf->GetDimsShelf());
}
TEST_F(WindowSelectorTest, SelectingHidesAppList) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
Shell::GetInstance()->ToggleAppList(NULL);
EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
ToggleOverview();
EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
ToggleOverview();
RunAllPendingInMessageLoop();
Shell::GetInstance()->ToggleAppList(NULL);
EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
Cycle(WindowSelector::FORWARD);
EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
StopCycling();
}
TEST_F(WindowSelectorTest, MinimizedWindowVisibility) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
wm::WindowState* window_state = wm::GetWindowState(window1.get());
window_state->Minimize();
EXPECT_FALSE(window1->IsVisible());
EXPECT_FALSE(window1->layer()->GetTargetVisibility());
{
ui::ScopedAnimationDurationScaleMode normal_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ToggleOverview();
EXPECT_TRUE(window1->IsVisible());
EXPECT_TRUE(window1->layer()->GetTargetVisibility());
}
{
ui::ScopedAnimationDurationScaleMode normal_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ToggleOverview();
EXPECT_FALSE(window1->IsVisible());
EXPECT_FALSE(window1->layer()->GetTargetVisibility());
}
}
TEST_F(WindowSelectorTest, BoundsChangeDuringOverview) {
scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400)));
ToggleOverview();
gfx::Rect overview_bounds =
ToEnclosingRect(GetTransformedTargetBounds(window.get()));
window->SetBounds(gfx::Rect(200, 0, 200, 200));
gfx::Rect new_overview_bounds =
ToEnclosingRect(GetTransformedTargetBounds(window.get()));
EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
ToggleOverview();
}
TEST_F(WindowSelectorTest, BasicCycle) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> window3(CreateWindow(bounds));
wm::ActivateWindow(window3.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
EXPECT_FALSE(wm::IsActiveWindow(window3.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(IsSelecting());
EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
StopCycling();
EXPECT_FALSE(IsSelecting());
EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
}
TEST_F(WindowSelectorTest, CyclePreservesStackingOrder) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> window3(CreateWindow(bounds));
wm::ActivateWindow(window3.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(IsWindowAbove(window2.get(), window1.get()));
EXPECT_TRUE(IsWindowAbove(window1.get(), window3.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(IsWindowAbove(window3.get(), window1.get()));
EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
StopCycling();
}
TEST_F(WindowSelectorTest, CyclePreservesMinimization) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
wm::ActivateWindow(window2.get());
wm::GetWindowState(window2.get())->Minimize();
wm::ActivateWindow(window1.get());
EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_FALSE(wm::IsWindowMinimized(window2.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
StopCycling();
EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
}
TEST_F(WindowSelectorTest, OverviewTransitionToCycle) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
ToggleOverview();
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
EXPECT_EQ(window2.get(), GetFocusedWindow());
}
TEST_F(WindowSelectorTest, CyclePanels) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
wm::ActivateWindow(panel2.get());
wm::ActivateWindow(panel1.get());
EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
}
TEST_F(WindowSelectorTest, CyclePanelVisibility) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
wm::ActivateWindow(panel1.get());
wm::ActivateWindow(window1.get());
Cycle(WindowSelector::FORWARD);
FireOverviewStartTimer();
EXPECT_EQ(1.0f, panel1->layer()->GetTargetOpacity());
StopCycling();
}
TEST_F(WindowSelectorTest, CyclePanelsDestroyed) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> window3(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
wm::ActivateWindow(window3.get());
wm::ActivateWindow(panel2.get());
wm::ActivateWindow(panel1.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
Cycle(WindowSelector::FORWARD);
panel1.reset();
panel2.reset();
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
}
TEST_F(WindowSelectorTest, CycleMruPanelDestroyed) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
wm::ActivateWindow(panel2.get());
wm::ActivateWindow(panel1.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
Cycle(WindowSelector::FORWARD);
panel1.reset();
Cycle(WindowSelector::FORWARD);
StopCycling();
EXPECT_TRUE(wm::IsActiveWindow(panel2.get()));
}
TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
ToggleOverview();
EXPECT_TRUE(IsSelecting());
scoped_ptr<aura::Window> window3(CreateWindow(bounds));
EXPECT_FALSE(IsSelecting());
}
TEST_F(WindowSelectorTest, ActivationCancelsOveriew) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
window2->Focus();
ToggleOverview();
EXPECT_TRUE(IsSelecting());
window1->Focus();
EXPECT_FALSE(IsSelecting());
EXPECT_EQ(window1.get(), GetFocusedWindow());
}
TEST_F(WindowSelectorTest, CycleOverviewDelay) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(IsSelecting());
EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
FireOverviewStartTimer();
EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
StopCycling();
}
TEST_F(WindowSelectorTest, CancelRestoresFocus) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window(CreateWindow(bounds));
wm::ActivateWindow(window.get());
EXPECT_EQ(window.get(), GetFocusedWindow());
ToggleOverview();
EXPECT_EQ(NULL, GetFocusedWindow());
ToggleOverview();
EXPECT_EQ(window.get(), GetFocusedWindow());
}
TEST_F(WindowSelectorTest, LastWindowDestroyed) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
ToggleOverview();
window1.reset();
window2.reset();
EXPECT_FALSE(IsSelecting());
}
TEST_F(WindowSelectorTest, QuickReentryRestoresInitialTransform) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window(CreateWindow(bounds));
gfx::Rect initial_bounds = ToEnclosingRect(
GetTransformedBounds(window.get()));
ToggleOverview();
{
ui::ScopedAnimationDurationScaleMode normal_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ToggleOverview();
ToggleOverview();
}
EXPECT_NE(initial_bounds, ToEnclosingRect(
GetTransformedTargetBounds(window.get())));
ToggleOverview();
EXPECT_FALSE(IsSelecting());
EXPECT_EQ(initial_bounds, ToEnclosingRect(
GetTransformedTargetBounds(window.get())));
}
TEST_F(WindowSelectorTest, NonActivatableWindowsHidden) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> window2(CreateWindow(bounds));
scoped_ptr<aura::Window> non_activatable_window(
CreateNonActivatableWindow(Shell::GetPrimaryRootWindow()->bounds()));
EXPECT_TRUE(non_activatable_window->IsVisible());
ToggleOverview();
EXPECT_FALSE(non_activatable_window->IsVisible());
ToggleOverview();
EXPECT_TRUE(non_activatable_window->IsVisible());
non_activatable_window->parent()->StackChildAtTop(
non_activatable_window.get());
ToggleOverview();
ClickWindow(window1.get());
EXPECT_FALSE(IsSelecting());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
}
TEST_F(WindowSelectorTest, ModalChild) {
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds));
scoped_ptr<aura::Window> child1(CreateWindow(bounds));
child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
::wm::AddTransientChild(window1.get(), child1.get());
EXPECT_EQ(window1->parent(), child1->parent());
ToggleOverview();
EXPECT_TRUE(window1->IsVisible());
EXPECT_TRUE(child1->IsVisible());
EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1.get())),
ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
ToggleOverview();
}
TEST_F(WindowSelectorTest, ClickModalWindowParent) {
scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 180, 180)));
scoped_ptr<aura::Window> child1(CreateWindow(gfx::Rect(200, 0, 180, 180)));
child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
::wm::AddTransientChild(window1.get(), child1.get());
EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
EXPECT_EQ(window1->parent(), child1->parent());
ToggleOverview();
EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
ClickWindow(window1.get());
EXPECT_FALSE(IsSelecting());
EXPECT_TRUE(wm::IsActiveWindow(child1.get()));
}
TEST_F(WindowSelectorTest, MultipleDisplays) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("600x400,600x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
gfx::Rect bounds1(0, 0, 400, 400);
gfx::Rect bounds2(650, 0, 400, 400);
scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1));
scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds1));
scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds2));
scoped_ptr<aura::Window> panel4(CreatePanelWindow(bounds2));
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[0], window2->GetRootWindow());
EXPECT_EQ(root_windows[1], window3->GetRootWindow());
EXPECT_EQ(root_windows[1], window4->GetRootWindow());
EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
ToggleOverview();
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[0], window2->GetRootWindow());
EXPECT_EQ(root_windows[1], window3->GetRootWindow());
EXPECT_EQ(root_windows[1], window4->GetRootWindow());
EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window3.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window4.get()))));
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(panel1.get()))));
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(panel2.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(panel3.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(panel4.get()))));
EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get()));
EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get()));
}
TEST_F(WindowSelectorTest, CycleOverviewUsesCurrentDisplay) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("400x400,400x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[1], window2->GetRootWindow());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow());
Cycle(WindowSelector::FORWARD);
FireOverviewStartTimer();
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
StopCycling();
}
TEST_F(WindowSelectorTest, CycleMultipleDisplaysCopiesWindows) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("400x400,400x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
gfx::Rect root1_rect(0, 0, 100, 100);
gfx::Rect root2_rect(450, 0, 100, 100);
scoped_ptr<aura::Window> unmoved1(CreateWindow(root2_rect));
scoped_ptr<aura::Window> unmoved2(CreateWindow(root2_rect));
scoped_ptr<aura::Window> moved1_trans_parent(CreateWindow(root1_rect));
scoped_ptr<aura::Window> moved1(CreateWindow(root1_rect));
unmoved1->SetName("unmoved1");
unmoved2->SetName("unmoved2");
moved1->SetName("moved1");
moved1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
::wm::AddTransientChild(moved1_trans_parent.get(), moved1.get());
moved1_trans_parent->SetName("moved1_trans_parent");
EXPECT_EQ(root_windows[0], moved1->GetRootWindow());
EXPECT_EQ(root_windows[0], moved1_trans_parent->GetRootWindow());
EXPECT_EQ(root_windows[1], unmoved1->GetRootWindow());
EXPECT_EQ(root_windows[1], unmoved2->GetRootWindow());
wm::ActivateWindow(unmoved2.get());
wm::ActivateWindow(unmoved1.get());
Cycle(WindowSelector::FORWARD);
FireOverviewStartTimer();
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(unmoved1.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(unmoved2.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(moved1.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(moved1_trans_parent.get()))));
EXPECT_TRUE(!GetCopyWindow(unmoved1.get()));
EXPECT_TRUE(!GetCopyWindow(unmoved2.get()));
aura::Window* copy1 = GetCopyWindow(moved1.get());
aura::Window* copy1_trans_parent = GetCopyWindow(moved1_trans_parent.get());
ASSERT_FALSE(!copy1);
ASSERT_FALSE(!copy1_trans_parent);
EXPECT_EQ(root_windows[1], copy1->GetRootWindow());
EXPECT_EQ(moved1->GetBoundsInScreen().ToString(),
copy1->GetBoundsInScreen().ToString());
EXPECT_EQ(moved1->layer()->GetTargetTransform().ToString(),
copy1->layer()->GetTargetTransform().ToString());
StopCycling();
RunAllPendingInMessageLoop();
EXPECT_TRUE(!GetCopyWindow(moved1.get()));
EXPECT_TRUE(!GetCopyWindow(moved1_trans_parent.get()));
}
TEST_F(WindowSelectorTest, MultipleDisplaysOverviewTransitionToCycle) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("400x400,400x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[1], window2->GetRootWindow());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
ToggleOverview();
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
Cycle(WindowSelector::FORWARD);
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
StopCycling();
}
TEST_F(WindowSelectorTest, BoundsChangeDuringCycleOnOtherDisplay) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("400x400,400x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
scoped_ptr<aura::Window> window3(CreateWindow(gfx::Rect(450, 0, 100, 100)));
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[1], window2->GetRootWindow());
EXPECT_EQ(root_windows[1], window3->GetRootWindow());
wm::ActivateWindow(window1.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window3.get());
Cycle(WindowSelector::FORWARD);
FireOverviewStartTimer();
gfx::Rect overview_bounds(
ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(overview_bounds));
window1->SetBounds(gfx::Rect(100, 0, 200, 200));
gfx::Rect new_overview_bounds =
ToEnclosingRect(GetTransformedTargetBounds(window1.get()));
EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
StopCycling();
}
TEST_F(WindowSelectorTest, Shutdown) {
gfx::Rect bounds(0, 0, 400, 400);
aura::Window* window1(CreateWindow(bounds));
aura::Window* window2(CreateWindow(bounds));
aura::Window* window3(CreatePanelWindow(bounds));
aura::Window* window4(CreatePanelWindow(bounds));
wm::ActivateWindow(window4);
wm::ActivateWindow(window3);
wm::ActivateWindow(window2);
wm::ActivateWindow(window1);
ToggleOverview();
}
TEST_F(WindowSelectorTest, RemoveDisplay) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("400x400,400x400");
gfx::Rect bounds1(0, 0, 100, 100);
gfx::Rect bounds2(450, 0, 100, 100);
scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
scoped_ptr<aura::Window> window3(CreatePanelWindow(bounds1));
scoped_ptr<aura::Window> window4(CreatePanelWindow(bounds2));
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[1], window2->GetRootWindow());
EXPECT_EQ(root_windows[0], window3->GetRootWindow());
EXPECT_EQ(root_windows[1], window4->GetRootWindow());
wm::ActivateWindow(window4.get());
wm::ActivateWindow(window3.get());
wm::ActivateWindow(window2.get());
wm::ActivateWindow(window1.get());
ToggleOverview();
EXPECT_TRUE(IsSelecting());
UpdateDisplay("400x400");
EXPECT_FALSE(IsSelecting());
}
TEST_F(WindowSelectorTest, DISABLED_DragDropInProgress) {
bool drag_canceled_by_test = false;
gfx::Rect bounds(0, 0, 400, 400);
scoped_ptr<aura::Window> window(CreateWindow(bounds));
test::ShellTestApi shell_test_api(Shell::GetInstance());
ash::DragDropController* drag_drop_controller =
shell_test_api.drag_drop_controller();
ui::OSExchangeData data;
base::MessageLoopForUI::current()->PostTask(FROM_HERE,
base::Bind(&WindowSelectorTest::ToggleOverview,
base::Unretained(this)));
base::MessageLoopForUI::current()->PostTask(FROM_HERE,
base::Bind(&CancelDrag, drag_drop_controller, &drag_canceled_by_test));
data.SetString(base::UTF8ToUTF16("I am being dragged"));
drag_drop_controller->StartDragAndDrop(data, window->GetRootWindow(),
window.get(), gfx::Point(5, 5), ui::DragDropTypes::DRAG_MOVE,
ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(drag_canceled_by_test);
ASSERT_TRUE(IsSelecting());
RunAllPendingInMessageLoop();
}
TEST_F(WindowSelectorTest, HitTestingInOverview) {
gfx::Rect window_bounds(20, 10, 200, 300);
aura::Window* root_window = Shell::GetPrimaryRootWindow();
scoped_ptr<aura::Window> window1(CreateWindow(window_bounds));
scoped_ptr<aura::Window> window2(CreateWindow(window_bounds));
ToggleOverview();
gfx::RectF bounds1 = GetTransformedBoundsInRootWindow(window1.get());
gfx::RectF bounds2 = GetTransformedBoundsInRootWindow(window2.get());
EXPECT_NE(bounds1.ToString(), bounds2.ToString());
ui::EventTarget* root_target = root_window;
ui::EventTargeter* targeter = root_target->GetEventTargeter();
aura::Window* windows[] = { window1.get(), window2.get() };
for (size_t w = 0; w < arraysize(windows); ++w) {
gfx::RectF bounds = GetTransformedBoundsInRootWindow(windows[w]);
gfx::Point points[] = {
gfx::Point(bounds.x(), bounds.y()),
gfx::Point(bounds.x(), bounds.bottom() - 1),
gfx::Point(bounds.right() - 1, bounds.bottom() - 1),
};
for (size_t p = 0; p < arraysize(points); ++p) {
ui::MouseEvent event(ui::ET_MOUSE_MOVED, points[p], points[p],
ui::EF_NONE, ui::EF_NONE);
EXPECT_EQ(windows[w],
targeter->FindTargetForEvent(root_target, &event));
}
}
}
}