diff options
Diffstat (limited to 'chromium/ash/wm/caption_buttons/alternate_frame_size_button_unittest.cc')
-rw-r--r-- | chromium/ash/wm/caption_buttons/alternate_frame_size_button_unittest.cc | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/chromium/ash/wm/caption_buttons/alternate_frame_size_button_unittest.cc b/chromium/ash/wm/caption_buttons/alternate_frame_size_button_unittest.cc new file mode 100644 index 00000000000..75c0f50604b --- /dev/null +++ b/chromium/ash/wm/caption_buttons/alternate_frame_size_button_unittest.cc @@ -0,0 +1,367 @@ +// Copyright 2013 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/caption_buttons/alternate_frame_size_button.h" + +#include "ash/ash_switches.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/wm/caption_buttons/frame_caption_button.h" +#include "ash/wm/caption_buttons/frame_caption_button_container_view.h" +#include "ash/wm/window_state.h" +#include "ash/wm/workspace/snap_sizer.h" +#include "base/command_line.h" +#include "ui/aura/test/event_generator.h" +#include "ui/aura/window.h" +#include "ui/events/gestures/gesture_configuration.h" +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +namespace ash { +namespace test { + +namespace { + +class TestWidgetDelegate : public views::WidgetDelegateView { + public: + TestWidgetDelegate() {} + virtual ~TestWidgetDelegate() {} + + // Overridden from views::WidgetDelegate: + virtual views::View* GetContentsView() OVERRIDE { + return this; + } + virtual bool CanResize() const OVERRIDE { + return true; + } + virtual bool CanMaximize() const OVERRIDE { + return true; + } + + ash::FrameCaptionButtonContainerView* caption_button_container() { + return caption_button_container_; + } + + private: + // Overridden from views::View: + virtual void Layout() OVERRIDE { + caption_button_container_->Layout(); + + // Right align the caption button container. + gfx::Size preferred_size = caption_button_container_->GetPreferredSize(); + caption_button_container_->SetBounds(width() - preferred_size.width(), 0, + preferred_size.width(), preferred_size.height()); + } + + virtual void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) OVERRIDE { + if (details.is_add && details.child == this) { + caption_button_container_ = new FrameCaptionButtonContainerView( + GetWidget(), FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); + AddChildView(caption_button_container_); + } + } + + // Not owned. + ash::FrameCaptionButtonContainerView* caption_button_container_; + + DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate); +}; + +} // namespace + +class AlternateFrameSizeButtonTest : public AshTestBase { + public: + AlternateFrameSizeButtonTest() {} + virtual ~AlternateFrameSizeButtonTest() {} + + // Returns the center point of |view| in screen coordinates. + gfx::Point CenterPointInScreen(views::View* view) { + return view->GetBoundsInScreen().CenterPoint(); + } + + // Returns true if the window is snapped to |edge|. + bool IsSnapped(internal::SnapSizer::Edge edge) const { + ash::wm::WindowShowType show_type = window_state()->window_show_type(); + if (edge == internal::SnapSizer::LEFT_EDGE) + return show_type == ash::wm::SHOW_TYPE_LEFT_SNAPPED; + else + return show_type == ash::wm::SHOW_TYPE_RIGHT_SNAPPED; + } + + // Returns true if all three buttons are in the normal state. + bool AllButtonsInNormalState() const { + return minimize_button_->state() == views::Button::STATE_NORMAL && + size_button_->state() == views::Button::STATE_NORMAL && + close_button_->state() == views::Button::STATE_NORMAL; + } + + // Creates a widget with |delegate|. The returned widget takes ownership of + // |delegate|. + views::Widget* CreateWidget(views::WidgetDelegate* delegate) { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.context = CurrentContext(); + params.delegate = delegate; + params.bounds = gfx::Rect(10, 10, 100, 100); + widget->Init(params); + widget->Show(); + return widget; + } + + // AshTestBase overrides: + virtual void SetUp() OVERRIDE { + AshTestBase::SetUp(); + + CommandLine* command_line = CommandLine::ForCurrentProcess(); + command_line->AppendSwitch( + switches::kAshEnableAlternateFrameCaptionButtonStyle); + CHECK(!command_line->HasSwitch(switches::kAshMultipleSnapWindowWidths)); + + TestWidgetDelegate* delegate = new TestWidgetDelegate(); + window_state_ = ash::wm::GetWindowState( + CreateWidget(delegate)->GetNativeWindow()); + + FrameCaptionButtonContainerView::TestApi test( + delegate->caption_button_container()); + + minimize_button_ = test.minimize_button(); + size_button_ = test.size_button(); + static_cast<AlternateFrameSizeButton*>( + size_button_)->set_delay_to_set_buttons_to_snap_mode(0); + close_button_ = test.close_button(); + } + + ash::wm::WindowState* window_state() { return window_state_; } + const ash::wm::WindowState* window_state() const { return window_state_; } + + FrameCaptionButton* minimize_button() { return minimize_button_; } + FrameCaptionButton* size_button() { return size_button_; } + FrameCaptionButton* close_button() { return close_button_; } + + private: + // Not owned. + ash::wm::WindowState* window_state_; + FrameCaptionButton* minimize_button_; + FrameCaptionButton* size_button_; + FrameCaptionButton* close_button_; + + DISALLOW_COPY_AND_ASSIGN(AlternateFrameSizeButtonTest); +}; + +// Tests that pressing the left mouse button or tapping down on the size button +// puts the button into the pressed state. +TEST_F(AlternateFrameSizeButtonTest, PressedState) { + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressLeftButton(); + EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state()); + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state()); + + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressTouchId(3); + EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state()); + generator.ReleaseTouchId(3); + RunAllPendingInMessageLoop(); + EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state()); +} + +// Tests that clicking on the size button toggles between the maximized and +// normal state. +TEST_F(AlternateFrameSizeButtonTest, ClickSizeButtonTogglesMaximize) { + EXPECT_FALSE(window_state()->IsMaximized()); + + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.ClickLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(window_state()->IsMaximized()); + + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.ClickLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_FALSE(window_state()->IsMaximized()); + + generator.GestureTapAt(CenterPointInScreen(size_button())); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(window_state()->IsMaximized()); + + generator.GestureTapAt(CenterPointInScreen(size_button())); + RunAllPendingInMessageLoop(); + EXPECT_FALSE(window_state()->IsMaximized()); +} + +// Test that clicking + dragging to a button adjacent to the size button snaps +// the window left or right. +TEST_F(AlternateFrameSizeButtonTest, ButtonDrag) { + EXPECT_TRUE(window_state()->IsNormalShowState()); + EXPECT_FALSE(window_state()->IsSnapped()); + + // 1) Test by dragging the mouse. + // Snap right. + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressLeftButton(); + generator.MoveMouseTo(CenterPointInScreen(close_button())); + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::RIGHT_EDGE)); + + // Snap left. + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressLeftButton(); + generator.MoveMouseTo(CenterPointInScreen(minimize_button())); + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); + + // 2) Test with scroll gestures. + // Snap right. + generator.GestureScrollSequence( + CenterPointInScreen(size_button()), + CenterPointInScreen(close_button()), + base::TimeDelta::FromMilliseconds(100), + 3); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::RIGHT_EDGE)); + + // Snap left. + generator.GestureScrollSequence( + CenterPointInScreen(size_button()), + CenterPointInScreen(minimize_button()), + base::TimeDelta::FromMilliseconds(100), + 3); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); + + // 3) Test with tap gestures. + const int touch_default_radius = + ui::GestureConfiguration::default_radius(); + ui::GestureConfiguration::set_default_radius(0); + // Snap right. + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(close_button())); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::RIGHT_EDGE)); + // Snap left. + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(minimize_button())); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); + ui::GestureConfiguration::set_default_radius(touch_default_radius); +} + +// Test that clicking, dragging, and overshooting the minimize button a bit +// horizontally still snaps the window left. +TEST_F(AlternateFrameSizeButtonTest, SnapLeftOvershootMinimize) { + EXPECT_TRUE(window_state()->IsNormalShowState()); + EXPECT_FALSE(window_state()->IsSnapped()); + + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + + generator.PressLeftButton(); + // Move to the minimize button. + generator.MoveMouseTo(CenterPointInScreen(minimize_button())); + // Overshoot the minimize button. + generator.MoveMouseBy(-minimize_button()->width(), 0); + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); +} + +// Test that right clicking the size button has no effect. +TEST_F(AlternateFrameSizeButtonTest, RightMouseButton) { + EXPECT_TRUE(window_state()->IsNormalShowState()); + EXPECT_FALSE(window_state()->IsSnapped()); + + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressRightButton(); + generator.ReleaseRightButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(window_state()->IsNormalShowState()); + EXPECT_FALSE(window_state()->IsSnapped()); +} + +// Test that upon releasing the mouse button after having pressed the size +// button +// - The state of all the caption buttons is reset. +// - The icon displayed by all of the caption buttons is reset. +TEST_F(AlternateFrameSizeButtonTest, ResetButtonsAfterClick) { + EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon()); + EXPECT_TRUE(AllButtonsInNormalState()); + + // Pressing the size button should result in the size button being pressed and + // the minimize and close button icons changing. + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressLeftButton(); + EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state()); + EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state()); + EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state()); + EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon()); + + // Dragging the mouse over the minimize button should press the minimize + // button and the minimize and close button icons should stay changed. + generator.MoveMouseTo(CenterPointInScreen(minimize_button())); + EXPECT_EQ(views::Button::STATE_PRESSED, minimize_button()->state()); + EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state()); + EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state()); + EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon()); + + // Release the mouse, snapping the window left. + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); + + // None of the buttons should stay pressed and the buttons should have their + // regular icons. + EXPECT_TRUE(AllButtonsInNormalState()); + EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon()); + + // Repeat test but release button where it does not affect the window's state + // because the code path is different. + generator.MoveMouseTo(CenterPointInScreen(size_button())); + generator.PressLeftButton(); + EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state()); + EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state()); + EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state()); + EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon()); + + const gfx::Rect& kWorkAreaBoundsInScreen = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left()); + + // None of the buttons should be pressed because we are really far away from + // any of the caption buttons. The minimize and close button icons should + // be changed because the mouse is pressed. + EXPECT_TRUE(AllButtonsInNormalState()); + EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon()); + + // Release the mouse. The window should stay snapped left. + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(IsSnapped(internal::SnapSizer::LEFT_EDGE)); + + // The buttons should stay unpressed and the buttons should now have their + // regular icons. + EXPECT_TRUE(AllButtonsInNormalState()); + EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon()); + EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon()); +} + +} // namespace test +} // namespace ash |