Commit 70206ac0 authored by pkotwicz@chromium.org's avatar pkotwicz@chromium.org

This is part 1 of implemeting phantom windows for the window controls when...

This is part 1 of implemeting phantom windows for the window controls when using --ash-enable-alternate-caption-button

Other notable changes:
- Switched to using layer animations instead of gfx::SlideAnimation
- Renamed PhantomWindowController::phantom_widget_ and PhantomWindowController::phantom_widget_start_ to PhantomWindowController::phantom_widget_in_target_root_ and PhantomWindowController::phantom_widget_in_start_root_ respectively.
- Removed PhantomWindowController::Hide(). Hiding the phantom window can now only be done via destroying the PhantomWindowController

BUG=328930
TEST=PhantomWindowControllerTest.*

Review URL: https://codereview.chromium.org/101773004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244050 0039d316-1c4b-4281-b951-d872f2087c98
parent 465d36fe
......@@ -874,6 +874,7 @@
'wm/window_util_unittest.cc',
'wm/workspace/magnetism_matcher_unittest.cc',
'wm/workspace/multi_window_resize_controller_unittest.cc',
'wm/workspace/phantom_window_controller_unittest.cc',
'wm/workspace/snap_sizer_unittest.cc',
'wm/workspace/workspace_event_handler_test_helper.cc',
'wm/workspace/workspace_event_handler_test_helper.h',
......
......@@ -30,7 +30,6 @@ const int SystemPinchHandler::kSystemGesturePoints = 4;
SystemPinchHandler::SystemPinchHandler(aura::Window* target)
: target_(target),
phantom_(target),
phantom_state_(PHANTOM_WINDOW_NORMAL),
pinch_factor_(1.) {
widget_ = views::Widget::GetWidgetForNativeWindow(target_);
......@@ -72,13 +71,16 @@ SystemGestureStatus SystemPinchHandler::ProcessGestureEvent(
pinch_factor_ *= event.details().scale();
gfx::Rect bounds =
GetPhantomWindowScreenBounds(target_, event.location());
if (phantom_state_ != PHANTOM_WINDOW_NORMAL || phantom_.IsShowing())
phantom_.Show(bounds);
if (phantom_state_ != PHANTOM_WINDOW_NORMAL || phantom_.get()) {
if (!phantom_.get())
phantom_.reset(new internal::PhantomWindowController(target_));
phantom_->Show(bounds);
}
break;
}
case ui::ET_GESTURE_MULTIFINGER_SWIPE: {
phantom_.Hide();
phantom_.reset();
pinch_factor_ = 1.0;
phantom_state_ = PHANTOM_WINDOW_NORMAL;
......
......@@ -6,6 +6,7 @@
#define ASH_WM_GESTURES_SYSTEM_PINCH_HANDLER_H_
#include "ash/wm/workspace/phantom_window_controller.h"
#include "base/memory/scoped_ptr.h"
namespace aura {
class Window;
......@@ -64,7 +65,7 @@ class SystemPinchHandler {
// A phantom window is used to provide visual cues for
// pinch-to-resize/maximize/minimize gestures.
PhantomWindowController phantom_;
scoped_ptr<PhantomWindowController> phantom_;
// When the phantom window is in minimized or maximized state, moving the
// target window should not move the phantom window. So |phantom_state_| is
......
......@@ -12,7 +12,6 @@
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/background.h"
......@@ -23,10 +22,30 @@
namespace ash {
namespace internal {
// EdgePainter ----------------------------------------------------------------
namespace {
// The duration of the show animation.
const int kAnimationDurationMs = 200;
// Starts an animation of |widget| to |new_bounds_in_screen|. No-op if |widget|
// is NULL.
void AnimateToBounds(views::Widget* widget,
const gfx::Rect& new_bounds_in_screen) {
if (!widget)
return;
ui::ScopedLayerAnimationSettings scoped_setter(
widget->GetNativeWindow()->layer()->GetAnimator());
scoped_setter.SetTweenType(gfx::Tween::EASE_IN);
scoped_setter.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
scoped_setter.SetTransitionDuration(
base::TimeDelta::FromMilliseconds(kAnimationDurationMs));
widget->SetBounds(new_bounds_in_screen);
}
// EdgePainter ----------------------------------------------------------------
// Paints the background of the phantom window for window snapping.
class EdgePainter : public views::Painter {
public:
......@@ -41,9 +60,6 @@ class EdgePainter : public views::Painter {
DISALLOW_COPY_AND_ASSIGN(EdgePainter);
};
} // namespace
EdgePainter::EdgePainter() {
}
......@@ -86,95 +102,75 @@ void EdgePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
SkIntToScalar(kRoundRectSize), paint);
}
} // namespace
// PhantomWindowController ----------------------------------------------------
PhantomWindowController::PhantomWindowController(aura::Window* window)
: window_(window),
phantom_below_window_(NULL),
phantom_widget_(NULL),
phantom_widget_start_(NULL) {
phantom_below_window_(NULL) {
}
PhantomWindowController::~PhantomWindowController() {
Hide();
}
void PhantomWindowController::Show(const gfx::Rect& bounds_in_screen) {
if (bounds_in_screen == bounds_in_screen_)
if (bounds_in_screen == target_bounds_in_screen_)
return;
bounds_in_screen_ = bounds_in_screen;
aura::Window* target_root = wm::GetRootWindowMatching(bounds_in_screen);
// Show the phantom at the current bounds of the window. We'll animate to the
// target bounds. If phantom exists, update the start bounds.
if (!phantom_widget_)
start_bounds_ = window_->GetBoundsInScreen();
else
start_bounds_ = phantom_widget_->GetWindowBoundsInScreen();
if (phantom_widget_ &&
phantom_widget_->GetNativeWindow()->GetRootWindow() != target_root) {
phantom_widget_->Close();
phantom_widget_ = NULL;
target_bounds_in_screen_ = bounds_in_screen;
gfx::Rect start_bounds_in_screen;
if (!phantom_widget_in_target_root_) {
start_bounds_in_screen = window_->GetBoundsInScreen();
} else {
start_bounds_in_screen =
phantom_widget_in_target_root_->GetWindowBoundsInScreen();
}
aura::Window* target_root =
wm::GetRootWindowMatching(target_bounds_in_screen_);
if (!phantom_widget_in_target_root_ ||
phantom_widget_in_target_root_->GetNativeWindow()->GetRootWindow() !=
target_root) {
phantom_widget_in_target_root_ =
CreatePhantomWidget(target_root, start_bounds_in_screen);
}
if (!phantom_widget_)
phantom_widget_ = CreatePhantomWidget(target_root, start_bounds_);
AnimateToBounds(phantom_widget_in_target_root_.get(),
target_bounds_in_screen_);
// Create a secondary widget in a second screen if start_bounds_ lie at least
// partially in that other screen. This allows animations to start or restart
// in one root window and progress into another root.
aura::Window* start_root = wm::GetRootWindowMatching(start_bounds_);
// Create a secondary widget in a second screen if |start_bounds_in_screen|
// lies at least partially in another screen. This allows animations to start
// or restart in one root window and progress to another root.
aura::Window* start_root = wm::GetRootWindowMatching(start_bounds_in_screen);
if (start_root == target_root) {
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
for (size_t i = 0; i < root_windows.size(); ++i) {
if (root_windows[i] != target_root &&
root_windows[i]->GetBoundsInScreen().Intersects(start_bounds_)) {
root_windows[i]->GetBoundsInScreen().Intersects(
start_bounds_in_screen)) {
start_root = root_windows[i];
break;
}
}
}
if (phantom_widget_start_ &&
(phantom_widget_start_->GetNativeWindow()->GetRootWindow() != start_root
|| start_root == target_root)) {
phantom_widget_start_->Close();
phantom_widget_start_ = NULL;
if (start_root == target_root) {
phantom_widget_in_start_root_.reset();
} else {
if (!phantom_widget_in_start_root_ ||
phantom_widget_in_start_root_->GetNativeWindow()->GetRootWindow() !=
start_root) {
phantom_widget_in_start_root_ =
CreatePhantomWidget(start_root, start_bounds_in_screen);
}
AnimateToBounds(phantom_widget_in_start_root_.get(),
target_bounds_in_screen_);
}
if (!phantom_widget_start_ && start_root != target_root)
phantom_widget_start_ = CreatePhantomWidget(start_root, start_bounds_);
animation_.reset(new gfx::SlideAnimation(this));
animation_->SetTweenType(gfx::Tween::EASE_IN);
const int kAnimationDurationMS = 200;
animation_->SetSlideDuration(kAnimationDurationMS);
animation_->Show();
}
void PhantomWindowController::Hide() {
if (phantom_widget_)
phantom_widget_->Close();
phantom_widget_ = NULL;
if (phantom_widget_start_)
phantom_widget_start_->Close();
phantom_widget_start_ = NULL;
}
bool PhantomWindowController::IsShowing() const {
return phantom_widget_ != NULL;
}
void PhantomWindowController::AnimationProgressed(
const gfx::Animation* animation) {
const gfx::Rect current_bounds =
animation->CurrentValueBetween(start_bounds_, bounds_in_screen_);
if (phantom_widget_start_)
phantom_widget_start_->SetBounds(current_bounds);
phantom_widget_->SetBounds(current_bounds);
}
views::Widget* PhantomWindowController::CreatePhantomWidget(
scoped_ptr<views::Widget> PhantomWindowController::CreatePhantomWidget(
aura::Window* root_window,
const gfx::Rect& bounds_in_screen) {
views::Widget* phantom_widget = new views::Widget;
scoped_ptr<views::Widget> phantom_widget(new views::Widget);
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
// PhantomWindowController is used by FrameMaximizeButton to highlight the
......@@ -184,6 +180,7 @@ views::Widget* PhantomWindowController::CreatePhantomWidget(
kShellWindowId_ShelfContainer);
params.can_activate = false;
params.keep_on_top = true;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
phantom_widget->set_focus_on_creation(false);
phantom_widget->Init(params);
phantom_widget->SetVisibilityChangedAnimationsEnabled(false);
......@@ -206,8 +203,11 @@ views::Widget* PhantomWindowController::CreatePhantomWidget(
ui::Layer* widget_layer = phantom_widget->GetNativeWindow()->layer();
widget_layer->SetOpacity(0);
ui::ScopedLayerAnimationSettings scoped_setter(widget_layer->GetAnimator());
scoped_setter.SetTransitionDuration(
base::TimeDelta::FromMilliseconds(kAnimationDurationMs));
widget_layer->SetOpacity(1);
return phantom_widget;
return phantom_widget.Pass();
}
} // namespace internal
......
......@@ -9,17 +9,12 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/rect.h"
namespace aura {
class Window;
}
namespace gfx {
class SlideAnimation;
}
namespace views {
class Widget;
}
......@@ -28,14 +23,14 @@ namespace ash {
namespace internal {
// PhantomWindowController is responsible for showing a phantom representation
// of a window. It's used used during dragging a window to show a snap location.
class ASH_EXPORT PhantomWindowController : public gfx::AnimationDelegate {
// of a window. It's used to show a preview of how snapping or docking a window
// will affect the window's bounds.
class ASH_EXPORT PhantomWindowController {
public:
explicit PhantomWindowController(aura::Window* window);
virtual ~PhantomWindowController();
// Bounds last passed to Show().
const gfx::Rect& bounds_in_screen() const { return bounds_in_screen_; }
// Hides the phantom window without any animation.
virtual ~PhantomWindowController();
// Animates the phantom window towards |bounds_in_screen|.
// Creates two (if start bounds intersect any root window other than the
......@@ -44,28 +39,20 @@ class ASH_EXPORT PhantomWindowController : public gfx::AnimationDelegate {
// This does not immediately show the window.
void Show(const gfx::Rect& bounds_in_screen);
// Hides the phantom.
void Hide();
// Returns true if the phantom is showing.
bool IsShowing() const;
// If set, the phantom window is stacked below this window, otherwise it
// is stacked above the window passed to the constructor.
void set_phantom_below_window(aura::Window* phantom_below_window) {
phantom_below_window_ = phantom_below_window;
}
// gfx::AnimationDelegate overrides:
virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
private:
FRIEND_TEST_ALL_PREFIXES(WorkspaceWindowResizerTest, PhantomWindowShow);
friend class PhantomWindowControllerTest;
// Creates, shows and returns a phantom widget at |bounds|
// with kShellWindowId_ShelfContainer in |root_window| as a parent.
views::Widget* CreatePhantomWidget(aura::Window* root_window,
const gfx::Rect& bounds_in_screen);
scoped_ptr<views::Widget> CreatePhantomWidget(
aura::Window* root_window,
const gfx::Rect& bounds_in_screen);
// Window the phantom is placed beneath.
aura::Window* window_;
......@@ -73,26 +60,18 @@ class ASH_EXPORT PhantomWindowController : public gfx::AnimationDelegate {
// If set, the phantom window should get stacked below this window.
aura::Window* phantom_below_window_;
// Initially the bounds of |window_| (in screen coordinates).
// Each time Show() is invoked |start_bounds_| is then reset to the bounds of
// |phantom_widget_| and |bounds_| is set to the value passed into Show().
// The animation animates between these two values.
gfx::Rect start_bounds_;
// Target bounds of the animation in screen coordinates.
gfx::Rect bounds_in_screen_;
// The primary phantom representation of the window. It is parented by the
// root window matching the target bounds.
views::Widget* phantom_widget_;
gfx::Rect target_bounds_in_screen_;
// If the animation starts on another display, this is the secondary phantom
// representation of the window used on the initial display, otherwise this is
// NULL. This allows animation to progress from one display into the other.
views::Widget* phantom_widget_start_;
// Phantom representation of the window which is in the root window matching
// |target_bounds_in_screen_|.
scoped_ptr<views::Widget> phantom_widget_in_target_root_;
// Used to transition the bounds.
scoped_ptr<gfx::SlideAnimation> animation_;
// Phantom representation of the window which is in the root window matching
// the window's initial bounds. This allows animations to progress from one
// display to the other. NULL if the phantom window starts and ends in the
// same root window.
scoped_ptr<views::Widget> phantom_widget_in_start_root_;
DISALLOW_COPY_AND_ASSIGN(PhantomWindowController);
};
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/ash_switches.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace internal {
namespace {
// Returns true if |window| is non-NULL and is visible.
bool IsVisible(aura::Window* window) {
return window && window->IsVisible();
}
// Observes |window|'s deletion.
class WindowDeletionObserver : public aura::WindowObserver {
public:
WindowDeletionObserver(aura::Window* window) : window_(window) {
window_->AddObserver(this);
}
virtual ~WindowDeletionObserver() {
if (window_)
window_->RemoveObserver(this);
}
// Returns true if the window has not been deleted yet.
bool IsWindowAlive() {
return !!window_;
}
// aura::WindowObserver:
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
window_->RemoveObserver(this);
window_ = NULL;
}
private:
aura::Window* window_;
DISALLOW_COPY_AND_ASSIGN(WindowDeletionObserver);
};
} // namespace
class PhantomWindowControllerTest : public ash::test::AshTestBase {
public:
PhantomWindowControllerTest() {
}
virtual ~PhantomWindowControllerTest() {
}
// ash::test::AshTestBase:
virtual void SetUp() OVERRIDE {
ash::test::AshTestBase::SetUp();
UpdateDisplay("500x400,500x400");
window_ = CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 50, 60));
controller_.reset(new PhantomWindowController(window_));
}
void DeleteController() {
controller_.reset();
}
PhantomWindowController* controller() {
return controller_.get();
}
aura::Window* window() { return window_; }
aura::Window* phantom_window_in_target_root() {
return controller_->phantom_widget_in_target_root_ ?
controller_->phantom_widget_in_target_root_->GetNativeView() :
NULL;
}
aura::Window* phantom_window_in_start_root() {
return controller_->phantom_widget_in_start_root_ ?
controller_->phantom_widget_in_start_root_->GetNativeView() :
NULL;
}
private:
aura::Window* window_;
scoped_ptr<PhantomWindowController> controller_;
DISALLOW_COPY_AND_ASSIGN(PhantomWindowControllerTest);
};
// Test that two phantom windows are used when animating to bounds at least
// partially in another display.
TEST_F(PhantomWindowControllerTest, PhantomWindowShow) {
if (!SupportsMultipleDisplays())
return;
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
EXPECT_EQ(root_windows[0], window()->GetRootWindow());
// Phantom preview only in the left screen.
controller()->Show(gfx::Rect(100, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
// Move phantom preview into the right screen. Test that 2 windows got
// created.
controller()->Show(gfx::Rect(600, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
EXPECT_EQ(root_windows[0], phantom_window_in_start_root()->GetRootWindow());
// Move phantom preview only in the right screen. Start window should close.
controller()->Show(gfx::Rect(700, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
// Move phantom preview into the left screen. Start window should open.
controller()->Show(gfx::Rect(100, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
EXPECT_EQ(root_windows[1], phantom_window_in_start_root()->GetRootWindow());
// Move phantom preview while in the left screen. Start window should close.
controller()->Show(gfx::Rect(200, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
// Move phantom preview spanning both screens with most of the preview in the
// right screen. Two windows are created.
controller()->Show(gfx::Rect(495, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
EXPECT_EQ(root_windows[0], phantom_window_in_start_root()->GetRootWindow());
// Move phantom preview back into the left screen. Phantom windows should
// swap.
controller()->Show(gfx::Rect(200, 100, 50, 60));
EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
EXPECT_EQ(root_windows[1], phantom_window_in_start_root()->GetRootWindow());
// Destroy phantom controller. Both windows should close.
WindowDeletionObserver target_deletion_observer(
phantom_window_in_target_root());
WindowDeletionObserver start_deletion_observer(
phantom_window_in_start_root());
DeleteController();
EXPECT_FALSE(target_deletion_observer.IsWindowAlive());
EXPECT_FALSE(start_deletion_observer.IsWindowAlive());
}
} // namespace internal
} // namespace ash
......@@ -562,15 +562,6 @@ WorkspaceWindowResizer::WorkspaceWindowResizer(
instance_ = this;
}
gfx::Rect WorkspaceWindowResizer::GetFinalBounds(
const gfx::Rect& bounds) const {
if (snap_phantom_window_controller_.get() &&
snap_phantom_window_controller_->IsShowing()) {
return snap_phantom_window_controller_->bounds_in_screen();
}
return bounds;
}
void WorkspaceWindowResizer::LayoutAttachedWindows(
gfx::Rect* bounds) {
gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window()));
......
......@@ -76,10 +76,6 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
private:
friend class WorkspaceWindowResizerTest;
// Returns the final bounds to place the window at. This differs from
// the current when snapping.
gfx::Rect GetFinalBounds(const gfx::Rect& bounds) const;
// Lays out the attached windows. |bounds| is the bounds of the main window.
void LayoutAttachedWindows(gfx::Rect* bounds);
......
......@@ -30,37 +30,6 @@
#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
namespace gfx {
// Class to provide access to SlideAnimation internals for testing.
// TODO: this should be next to SlideAnimation, not here.
class SlideAnimation::TestApi {
public:
explicit TestApi(SlideAnimation* animation) : animation_(animation) {}
void SetStartTime(base::TimeTicks ticks) {
animation_->SetStartTime(ticks);
}
void Step(base::TimeTicks ticks) {
animation_->Step(ticks);
}
void RunTillComplete() {
SetStartTime(base::TimeTicks());
Step(base::TimeTicks() +
base::TimeDelta::FromMilliseconds(animation_->GetSlideDuration()));
EXPECT_EQ(1.0, animation_->GetCurrentValue());
}
private:
SlideAnimation* animation_;
DISALLOW_COPY_AND_ASSIGN(TestApi);
};
}
namespace ash {
namespace internal {
namespace {
......@@ -219,12 +188,6 @@ class WorkspaceWindowResizerTest : public test::AshTestBase {
touch_outer_insets);
}
// Simulate running the animation.
void RunAnimationTillComplete(gfx::SlideAnimation* animation) {
gfx::SlideAnimation::TestApi test_api(animation);
test_api.RunTillComplete();
}
TestWindowDelegate delegate_;
TestWindowDelegate delegate2_;
TestWindowDelegate delegate3_;
......@@ -1905,111 +1868,5 @@ TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
touch_resize_window_->bounds().ToString());
}
TEST_F(WorkspaceWindowResizerTest, PhantomWindowShow) {
if (!SupportsMultipleDisplays())
return;
UpdateDisplay("500x400,500x400");
window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
Shell::GetScreen()->GetPrimaryDisplay());
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
EXPECT_EQ(root_windows[0], window_->GetRootWindow());
scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
window_.get(), gfx::Point(), HTCAPTION));
ASSERT_TRUE(resizer.get());
EXPECT_FALSE(snap_phantom_window_controller());
// The pointer is on the edge but not shared. The snap phantom window
// controller should be non-NULL.
resizer->Drag(CalculateDragPoint(*resizer, -1, 0), 0);
EXPECT_TRUE(snap_phantom_window_controller());
PhantomWindowController* phantom_controller(snap_phantom_window_controller());
// phantom widget only in the left screen.
phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_FALSE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
// Move phantom widget into the right screen. Test that 2 widgets got created.
phantom_controller->Show(gfx::Rect(600, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_TRUE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[1],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_start_->GetNativeWindow()->
GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Move phantom widget only in the right screen. Start widget should close.
phantom_controller->Show(gfx::Rect(700, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_FALSE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[1],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Move phantom widget into the left screen. Start widget should open.
phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_TRUE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
EXPECT_EQ(
root_windows[1],
phantom_controller->phantom_widget_start_->GetNativeWindow()->
GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Move phantom widget while in the left screen. Start widget should close.
phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_FALSE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Move phantom widget spanning both screens with most of the window in the
// right screen. Two widgets are created.
phantom_controller->Show(gfx::Rect(495, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_TRUE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[1],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_start_->GetNativeWindow()->
GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Move phantom widget back into the left screen. Phantom widgets should swap.
phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
EXPECT_TRUE(phantom_controller->phantom_widget_);
EXPECT_TRUE(phantom_controller->phantom_widget_start_);
EXPECT_EQ(
root_windows[0],
phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
EXPECT_EQ(
root_windows[1],
phantom_controller->phantom_widget_start_->GetNativeWindow()->
GetRootWindow());
RunAnimationTillComplete(phantom_controller->animation_.get());
// Hide phantom controller. Both widgets should close.
phantom_controller->Hide();
EXPECT_FALSE(phantom_controller->phantom_widget_);
EXPECT_FALSE(phantom_controller->phantom_widget_start_);
}
} // namespace internal
} // namespace ash
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment