Commit 4b058b24 authored by yusukes@chromium.org's avatar yusukes@chromium.org

While dragging a window, show a semi-transparent aura window instead of the...

While dragging a window, show a semi-transparent aura window instead of the standard gray phantom window.

BUG=136816
TEST=new unit tests passed on try


Review URL: https://chromiumcodereview.appspot.com/10823199

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151073 0039d316-1c4b-4281-b951-d872f2087c98
parent 924f86d5
...@@ -113,6 +113,7 @@ WindowResizer::Details::Details(aura::Window* window, ...@@ -113,6 +113,7 @@ WindowResizer::Details::Details(aura::Window* window,
: window(window), : window(window),
initial_bounds(window->bounds()), initial_bounds(window->bounds()),
initial_location_in_parent(location), initial_location_in_parent(location),
initial_opacity(window->layer()->opacity()),
window_component(window_component), window_component(window_component),
bounds_change(GetBoundsChangeForWindowComponent(window_component)), bounds_change(GetBoundsChangeForWindowComponent(window_component)),
position_change_direction( position_change_direction(
......
...@@ -74,6 +74,9 @@ class ASH_EXPORT WindowResizer { ...@@ -74,6 +74,9 @@ class ASH_EXPORT WindowResizer {
// Location passed to the constructor, in |window->parent()|'s coordinates. // Location passed to the constructor, in |window->parent()|'s coordinates.
gfx::Point initial_location_in_parent; gfx::Point initial_location_in_parent;
// Initial opacity of the window.
float initial_opacity;
// The component the user pressed on. // The component the user pressed on.
int window_component; int window_component;
......
...@@ -8,12 +8,16 @@ ...@@ -8,12 +8,16 @@
#include "ash/shell_window_ids.h" #include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h" #include "ash/wm/coordinate_conversion.h"
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/animation/slide_animation.h" #include "ui/base/animation/slide_animation.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h" #include "ui/gfx/skia_util.h"
#include "ui/views/painter.h" #include "ui/views/painter.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -30,7 +34,7 @@ const int kInsetSize = 4; ...@@ -30,7 +34,7 @@ const int kInsetSize = 4;
// Size of the round rect used by EdgePainter. // Size of the round rect used by EdgePainter.
const int kRoundRectSize = 4; const int kRoundRectSize = 4;
// Paints the background of the phantom window. // Paints the background of the phantom window for window snapping.
class EdgePainter : public views::Painter { class EdgePainter : public views::Painter {
public: public:
EdgePainter() {} EdgePainter() {}
...@@ -70,18 +74,58 @@ class EdgePainter : public views::Painter { ...@@ -70,18 +74,58 @@ class EdgePainter : public views::Painter {
DISALLOW_COPY_AND_ASSIGN(EdgePainter); DISALLOW_COPY_AND_ASSIGN(EdgePainter);
}; };
// Paints the background of the phantom window for window dragging.
class WindowPainter : public views::Painter,
public aura::WindowObserver {
public:
explicit WindowPainter(aura::Window* window)
: window_(window) {
window_->AddObserver(this);
}
virtual ~WindowPainter() {
if (window_)
window_->RemoveObserver(this);
}
// views::Painter overrides:
virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE {
// TODO(yusukes): Paint child windows of the |window_| correctly. Current
// code does not paint e.g. web content area in the window. crbug.com/141766
if (window_ && window_->delegate())
window_->delegate()->OnPaint(canvas);
}
private:
// aura::WindowObserver overrides:
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
DCHECK_EQ(window_, window);
window_ = NULL;
}
aura::Window* window_;
DISALLOW_COPY_AND_ASSIGN(WindowPainter);
};
} // namespace } // namespace
PhantomWindowController::PhantomWindowController(aura::Window* window) PhantomWindowController::PhantomWindowController(aura::Window* window)
: window_(window), : window_(window),
phantom_below_window_(NULL), phantom_below_window_(NULL),
phantom_widget_(NULL) { phantom_widget_(NULL),
style_(STYLE_SHADOW) {
} }
PhantomWindowController::~PhantomWindowController() { PhantomWindowController::~PhantomWindowController() {
Hide(); Hide();
} }
void PhantomWindowController::SetDestinationDisplay(
const gfx::Display& dst_display) {
dst_display_ = dst_display;
}
void PhantomWindowController::Show(const gfx::Rect& bounds) { void PhantomWindowController::Show(const gfx::Rect& bounds) {
if (bounds == bounds_) if (bounds == bounds_)
return; return;
...@@ -102,7 +146,7 @@ void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { ...@@ -102,7 +146,7 @@ void PhantomWindowController::SetBounds(const gfx::Rect& bounds) {
DCHECK(IsShowing()); DCHECK(IsShowing());
animation_.reset(); animation_.reset();
bounds_ = bounds; bounds_ = bounds;
phantom_widget_->SetBounds(bounds_); SetBoundsInternal(bounds);
} }
void PhantomWindowController::Hide() { void PhantomWindowController::Hide() {
...@@ -115,10 +159,27 @@ bool PhantomWindowController::IsShowing() const { ...@@ -115,10 +159,27 @@ bool PhantomWindowController::IsShowing() const {
return phantom_widget_ != NULL; return phantom_widget_ != NULL;
} }
void PhantomWindowController::set_style(Style style) {
// Cannot change |style_| after the widget is initialized.
DCHECK(!phantom_widget_);
style_ = style;
}
void PhantomWindowController::SetOpacity(float opacity) {
DCHECK(phantom_widget_);
ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer();
ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator());
layer->SetOpacity(opacity);
}
float PhantomWindowController::GetOpacity() const {
DCHECK(phantom_widget_);
return phantom_widget_->GetNativeWindow()->layer()->opacity();
}
void PhantomWindowController::AnimationProgressed( void PhantomWindowController::AnimationProgressed(
const ui::Animation* animation) { const ui::Animation* animation) {
phantom_widget_->SetBounds( SetBoundsInternal(animation->CurrentValueBetween(start_bounds_, bounds_));
animation->CurrentValueBetween(start_bounds_, bounds_));
} }
void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
...@@ -138,10 +199,18 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { ...@@ -138,10 +199,18 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); phantom_widget_->SetVisibilityChangedAnimationsEnabled(false);
phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); phantom_widget_->GetNativeWindow()->SetName("PhantomWindow");
views::View* content_view = new views::View; views::View* content_view = new views::View;
content_view->set_background( switch (style_) {
views::Background::CreateBackgroundPainter(true, new EdgePainter)); case STYLE_SHADOW:
content_view->set_background(
views::Background::CreateBackgroundPainter(true, new EdgePainter));
break;
case STYLE_WINDOW:
content_view->set_background(views::Background::CreateBackgroundPainter(
true, new WindowPainter(window_)));
break;
}
phantom_widget_->SetContentsView(content_view); phantom_widget_->SetContentsView(content_view);
phantom_widget_->SetBounds(bounds); SetBoundsInternal(bounds);
if (phantom_below_window_) if (phantom_below_window_)
phantom_widget_->StackBelow(phantom_below_window_); phantom_widget_->StackBelow(phantom_below_window_);
else else
...@@ -154,5 +223,15 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { ...@@ -154,5 +223,15 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
layer->SetOpacity(1); layer->SetOpacity(1);
} }
void PhantomWindowController::SetBoundsInternal(const gfx::Rect& bounds) {
aura::Window* window = phantom_widget_->GetNativeWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(window->GetRootWindow());
if (screen_position_client && dst_display_.id() != -1)
screen_position_client->SetBounds(window, bounds, dst_display_);
else
phantom_widget_->SetBounds(bounds);
}
} // namespace internal } // namespace internal
} // namespace ash } // namespace ash
...@@ -9,10 +9,12 @@ ...@@ -9,10 +9,12 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "ui/base/animation/animation_delegate.h" #include "ui/base/animation/animation_delegate.h"
#include "ui/gfx/display.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
namespace aura { namespace aura {
class Window; class Window;
class RootWindow;
} }
namespace ui { namespace ui {
...@@ -30,9 +32,17 @@ namespace internal { ...@@ -30,9 +32,17 @@ namespace internal {
// of a window. It's used used during dragging a window to show a snap location. // of a window. It's used used during dragging a window to show a snap location.
class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
public: public:
enum Style {
STYLE_SHADOW, // for window snapping.
STYLE_WINDOW, // for window dragging.
};
explicit PhantomWindowController(aura::Window* window); explicit PhantomWindowController(aura::Window* window);
virtual ~PhantomWindowController(); virtual ~PhantomWindowController();
// Sets the display where the phantom is placed.
void SetDestinationDisplay(const gfx::Display& dst_display);
// Bounds last passed to Show(). // Bounds last passed to Show().
const gfx::Rect& bounds() const { return bounds_; } const gfx::Rect& bounds() const { return bounds_; }
...@@ -56,6 +66,14 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -56,6 +66,14 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
phantom_below_window_ = phantom_below_window; phantom_below_window_ = phantom_below_window;
} }
// Sets/gets the style of the phantom window.
void set_style(Style style);
Style style() const { return style_; }
// Sets/gets the opacity of the phantom window.
void SetOpacity(float opacity);
float GetOpacity() const;
// ui::AnimationDelegate overrides: // ui::AnimationDelegate overrides:
virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
...@@ -63,9 +81,18 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -63,9 +81,18 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
// Creates and shows the |phantom_widget_| at |bounds|. // Creates and shows the |phantom_widget_| at |bounds|.
void CreatePhantomWidget(const gfx::Rect& bounds); void CreatePhantomWidget(const gfx::Rect& bounds);
// Sets bounds of the phantom window. The window is shown on |dst_display_|
// if its id() is valid. Otherwise, a display nearest to |bounds| is chosen.
void SetBoundsInternal(const gfx::Rect& bounds);
// Window the phantom is placed beneath. // Window the phantom is placed beneath.
aura::Window* window_; aura::Window* window_;
// The display where the phantom is placed. When dst_display_.id() is -1 (i.e.
// the default), a display nearest to the current |bounds_| is automatically
// used.
gfx::Display dst_display_;
// If set, the phantom window should get stacked below this window. // If set, the phantom window should get stacked below this window.
aura::Window* phantom_below_window_; aura::Window* phantom_below_window_;
...@@ -81,6 +108,9 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -81,6 +108,9 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
// Used to transition the bounds. // Used to transition the bounds.
scoped_ptr<ui::SlideAnimation> animation_; scoped_ptr<ui::SlideAnimation> animation_;
// The style of the phantom window.
Style style_;
DISALLOW_COPY_AND_ASSIGN(PhantomWindowController); DISALLOW_COPY_AND_ASSIGN(PhantomWindowController);
}; };
......
...@@ -34,6 +34,9 @@ namespace { ...@@ -34,6 +34,9 @@ namespace {
// Duration of the animation when snapping the window into place. // Duration of the animation when snapping the window into place.
const int kSnapDurationMS = 100; const int kSnapDurationMS = 100;
// The maximum opacity of the drag phantom window.
const float kMaxOpacity = 0.8f;
// Returns true if should snap to the edge. // Returns true if should snap to the edge.
bool ShouldSnapToEdge(int distance_from_edge, int grid_size) { bool ShouldSnapToEdge(int distance_from_edge, int grid_size) {
return distance_from_edge <= grid_size / 2 && return distance_from_edge <= grid_size / 2 &&
...@@ -121,7 +124,7 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) { ...@@ -121,7 +124,7 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) {
// Show a phantom window for dragging in another root window. // Show a phantom window for dragging in another root window.
if (HasSecondaryRootWindow()) if (HasSecondaryRootWindow())
UpdateDragPhantomWindow(bounds); UpdateDragPhantomWindow(bounds, in_original_root);
else else
drag_phantom_window_controller_.reset(); drag_phantom_window_controller_.reset();
...@@ -133,6 +136,7 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) { ...@@ -133,6 +136,7 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) {
} }
void WorkspaceWindowResizer::CompleteDrag(int event_flags) { void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
window()->layer()->SetOpacity(details_.initial_opacity);
drag_phantom_window_controller_.reset(); drag_phantom_window_controller_.reset();
snap_phantom_window_controller_.reset(); snap_phantom_window_controller_.reset();
if (!did_move_or_resize_ || details_.window_component != HTCAPTION) if (!did_move_or_resize_ || details_.window_component != HTCAPTION)
...@@ -182,6 +186,7 @@ void WorkspaceWindowResizer::CompleteDrag(int event_flags) { ...@@ -182,6 +186,7 @@ void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
} }
void WorkspaceWindowResizer::RevertDrag() { void WorkspaceWindowResizer::RevertDrag() {
window()->layer()->SetOpacity(details_.initial_opacity);
drag_phantom_window_controller_.reset(); drag_phantom_window_controller_.reset();
snap_phantom_window_controller_.reset(); snap_phantom_window_controller_.reset();
...@@ -439,7 +444,8 @@ int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { ...@@ -439,7 +444,8 @@ int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const {
return 0; return 0;
} }
void WorkspaceWindowResizer::UpdateDragPhantomWindow(const gfx::Rect& bounds) { void WorkspaceWindowResizer::UpdateDragPhantomWindow(const gfx::Rect& bounds,
bool in_original_root) {
if (!did_move_or_resize_ || details_.window_component != HTCAPTION || if (!did_move_or_resize_ || details_.window_component != HTCAPTION ||
!ShouldAllowMouseWarp()) { !ShouldAllowMouseWarp()) {
return; return;
...@@ -451,18 +457,36 @@ void WorkspaceWindowResizer::UpdateDragPhantomWindow(const gfx::Rect& bounds) { ...@@ -451,18 +457,36 @@ void WorkspaceWindowResizer::UpdateDragPhantomWindow(const gfx::Rect& bounds) {
const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen()); const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen());
const gfx::Rect bounds_in_screen = const gfx::Rect bounds_in_screen =
ScreenAsh::ConvertRectToScreen(window()->parent(), bounds); ScreenAsh::ConvertRectToScreen(window()->parent(), bounds);
const gfx::Rect phantom(root_bounds_in_screen.Intersect(bounds_in_screen)); const gfx::Rect bounds_in_another_root =
root_bounds_in_screen.Intersect(bounds_in_screen);
if (!phantom.IsEmpty()) {
const float fraction_in_another_window =
(bounds_in_another_root.width() * bounds_in_another_root.height()) /
static_cast<float>(bounds.width() * bounds.height());
const float phantom_opacity =
!in_original_root ? 1 : (kMaxOpacity * fraction_in_another_window);
const float window_opacity =
in_original_root ? 1 : (kMaxOpacity * (1 - fraction_in_another_window));
if (fraction_in_another_window > 0) {
if (!drag_phantom_window_controller_.get()) { if (!drag_phantom_window_controller_.get()) {
drag_phantom_window_controller_.reset( drag_phantom_window_controller_.reset(
new PhantomWindowController(window())); new PhantomWindowController(window()));
drag_phantom_window_controller_->Show(phantom); drag_phantom_window_controller_->set_style(
PhantomWindowController::STYLE_WINDOW);
// Always show the drag phantom on the |another_root| window.
drag_phantom_window_controller_->SetDestinationDisplay(
gfx::Screen::GetDisplayMatching(another_root->GetBoundsInScreen()));
drag_phantom_window_controller_->Show(bounds_in_screen);
} else { } else {
drag_phantom_window_controller_->SetBounds(phantom); // no animation // No animation.
drag_phantom_window_controller_->SetBounds(bounds_in_screen);
} }
drag_phantom_window_controller_->SetOpacity(phantom_opacity);
window()->layer()->SetOpacity(window_opacity);
} else { } else {
drag_phantom_window_controller_.reset(); drag_phantom_window_controller_.reset();
window()->layer()->SetOpacity(1.0f);
} }
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/wm/window_resizer.h" #include "ash/wm/window_resizer.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
namespace aura { namespace aura {
...@@ -62,6 +63,8 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { ...@@ -62,6 +63,8 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
const std::vector<aura::Window*>& attached_windows); const std::vector<aura::Window*>& attached_windows);
private: private:
FRIEND_TEST_ALL_PREFIXES(WorkspaceWindowResizerTest, PhantomStyle);
// Type of snapping. // Type of snapping.
enum SnapType { enum SnapType {
// Snap to the left/right edge of the screen. // Snap to the left/right edge of the screen.
...@@ -114,8 +117,9 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { ...@@ -114,8 +117,9 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
const gfx::Rect& bounds, const gfx::Rect& bounds,
int grid_size); int grid_size);
// Updates the bounds of the phantom window for window dragging. // Updates the bounds of the phantom window for window dragging. Set true on
void UpdateDragPhantomWindow(const gfx::Rect& bounds); // |in_original_root| if the pointer is still in |window()->GetRootWindow()|.
void UpdateDragPhantomWindow(const gfx::Rect& bounds, bool in_original_root);
// Restacks the windows z-order position so that one of the windows is at the // Restacks the windows z-order position so that one of the windows is at the
// top of the z-order, and the rest directly underneath it. // top of the z-order, and the rest directly underneath it.
...@@ -165,9 +169,7 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { ...@@ -165,9 +169,7 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
// is a grid and the caption is being dragged. // is a grid and the caption is being dragged.
scoped_ptr<PhantomWindowController> snap_phantom_window_controller_; scoped_ptr<PhantomWindowController> snap_phantom_window_controller_;
// For now, we show a phantom window on the other root window during dragging. // Shows a semi-transparent image of the window being dragged.
// TODO(yusukes): Show a semi-transparent image (screen shot) of the window
// instead.
scoped_ptr<PhantomWindowController> drag_phantom_window_controller_; scoped_ptr<PhantomWindowController> drag_phantom_window_controller_;
// Used to determine the target position of a snap. // Used to determine the target position of a snap.
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/wm/property_util.h" #include "ash/wm/property_util.h"
#include "ash/wm/workspace_controller.h" #include "ash/wm/workspace_controller.h"
#include "ash/wm/workspace/phantom_window_controller.h"
#include "base/string_number_conversions.h" #include "base/string_number_conversions.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
#include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_window_delegate.h"
...@@ -62,16 +63,19 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { ...@@ -62,16 +63,19 @@ class WorkspaceWindowResizerTest : public test::AshTestBase {
EXPECT_EQ(kRootHeight, root_bounds.height()); EXPECT_EQ(kRootHeight, root_bounds.height());
Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets()); Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
window_.reset(new aura::Window(&delegate_)); window_.reset(new aura::Window(&delegate_));
window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
window_->Init(ui::LAYER_NOT_DRAWN); window_->Init(ui::LAYER_NOT_DRAWN);
window_->SetParent(default_container); window_->SetParent(default_container);
window_->set_id(1); window_->set_id(1);
window2_.reset(new aura::Window(&delegate2_)); window2_.reset(new aura::Window(&delegate2_));
window2_->SetType(aura::client::WINDOW_TYPE_NORMAL);
window2_->Init(ui::LAYER_NOT_DRAWN); window2_->Init(ui::LAYER_NOT_DRAWN);
window2_->SetParent(default_container); window2_->SetParent(default_container);
window2_->set_id(2); window2_->set_id(2);
window3_.reset(new aura::Window(&delegate3_)); window3_.reset(new aura::Window(&delegate3_));
window3_->SetType(aura::client::WINDOW_TYPE_NORMAL);
window3_->Init(ui::LAYER_NOT_DRAWN); window3_->Init(ui::LAYER_NOT_DRAWN);
window3_->SetParent(default_container); window3_->SetParent(default_container);
window3_->set_id(3); window3_->set_id(3);
...@@ -133,6 +137,8 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { ...@@ -133,6 +137,8 @@ class WorkspaceWindowResizerTest : public test::AshTestBase {
DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest); DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
}; };
} // namespace
// Fails on win_aura since wm::GetRootWindowRelativeToWindow is not implemented // Fails on win_aura since wm::GetRootWindowRelativeToWindow is not implemented
// yet for the platform. // yet for the platform.
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -140,10 +146,12 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { ...@@ -140,10 +146,12 @@ class WorkspaceWindowResizerTest : public test::AshTestBase {
DISABLED_WindowDragWithMultiMonitors DISABLED_WindowDragWithMultiMonitors
#define MAYBE_WindowDragWithMultiMonitorsRightToLeft \ #define MAYBE_WindowDragWithMultiMonitorsRightToLeft \
DISABLED_WindowDragWithMultiMonitorsRightToLeft DISABLED_WindowDragWithMultiMonitorsRightToLeft
#define MAYBE_PhantomStyle DISABLED_PhantomStyle
#else #else
#define MAYBE_WindowDragWithMultiMonitors WindowDragWithMultiMonitors #define MAYBE_WindowDragWithMultiMonitors WindowDragWithMultiMonitors
#define MAYBE_WindowDragWithMultiMonitorsRightToLeft \ #define MAYBE_WindowDragWithMultiMonitorsRightToLeft \
WindowDragWithMultiMonitorsRightToLeft WindowDragWithMultiMonitorsRightToLeft
#define MAYBE_PhantomStyle PhantomStyle
#endif #endif
// Assertions around attached window resize dragging from the right with 2 // Assertions around attached window resize dragging from the right with 2
...@@ -569,6 +577,75 @@ TEST_F(WorkspaceWindowResizerTest, ...@@ -569,6 +577,75 @@ TEST_F(WorkspaceWindowResizerTest,
} }
} }
// Verifies the style of the drag phantom window is correct.
TEST_F(WorkspaceWindowResizerTest, MAYBE_PhantomStyle) {
UpdateDisplay("800x600,800x600");
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
ASSERT_EQ(2U, root_windows.size());
window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
gfx::Screen::GetPrimaryDisplay());
EXPECT_EQ(root_windows[0], window_->GetRootWindow());
EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
{
SetGridSize(0);
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
ASSERT_TRUE(resizer.get());
EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
EXPECT_FALSE(resizer->drag_phantom_window_controller_.get());
// The pointer is inside the primary root. Both phantoms should be NULL.
resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
EXPECT_FALSE(resizer->drag_phantom_window_controller_.get());
// The window spans both root windows.
resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0);
EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
PhantomWindowController* controller =
resizer->drag_phantom_window_controller_.get();
ASSERT_TRUE(controller);
EXPECT_EQ(PhantomWindowController::STYLE_WINDOW, controller->style());
// |window_| should be opaque since the pointer is still on the primary
// root window. The phantom should be semi-transparent.
EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
EXPECT_GT(1.0f, controller->GetOpacity());
// Enter the pointer to the secondary display.
resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
controller = resizer->drag_phantom_window_controller_.get();
ASSERT_TRUE(controller);
EXPECT_EQ(PhantomWindowController::STYLE_WINDOW, controller->style());
// |window_| should be transparent, and the phantom should be opaque.
EXPECT_GT(1.0f, window_->layer()->opacity());
EXPECT_FLOAT_EQ(1.0f, controller->GetOpacity());
resizer->CompleteDrag(0);
EXPECT_EQ(root_windows[1], window_->GetRootWindow());
EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
}
// Do the same test with RevertDrag().
window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
gfx::Screen::GetPrimaryDisplay());
EXPECT_EQ(root_windows[0], window_->GetRootWindow());
EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
{
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
ASSERT_TRUE(resizer.get());
EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
EXPECT_FALSE(resizer->drag_phantom_window_controller_.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
resizer->RevertDrag();
EXPECT_EQ(root_windows[0], window_->GetRootWindow());
EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
}
}
// Verifies windows are correctly restacked when reordering multiple windows. // Verifies windows are correctly restacked when reordering multiple windows.
TEST_F(WorkspaceWindowResizerTest, RestackAttached) { TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
window_->SetBounds(gfx::Rect( 0, 0, 200, 300)); window_->SetBounds(gfx::Rect( 0, 0, 200, 300));
...@@ -765,6 +842,5 @@ TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) { ...@@ -765,6 +842,5 @@ TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) {
EXPECT_EQ("106,124 320x160", window_->bounds().ToString()); EXPECT_EQ("106,124 320x160", window_->bounds().ToString());
} }
} // namespace
} // namespace test } // namespace test
} // namespace ash } // 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