Commit 68214399 authored by Eliot Courtney's avatar Eliot Courtney Committed by Commit Bot

Snap picture-in-picture window to the edges of the work area.

the closest edge.

Bug: 883098
Bug: 841886
Bug: b/115291749
Test: Drag PIP window to the middle of the screen - it animates back to
Test: Added unittests
Change-Id: Ibf19f50c4e4298ea126c1a1986f014076e4592f1
Reviewed-on: https://chromium-review.googlesource.com/c/1221010
Commit-Queue: Eliot Courtney <edcourtney@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600262}
parent 905467f6
...@@ -1190,6 +1190,8 @@ component("ash") { ...@@ -1190,6 +1190,8 @@ component("ash") {
"wm/overview/window_selector_delegate.h", "wm/overview/window_selector_delegate.h",
"wm/overview/window_selector_item.cc", "wm/overview/window_selector_item.cc",
"wm/overview/window_selector_item.h", "wm/overview/window_selector_item.h",
"wm/pip/pip_positioner.cc",
"wm/pip/pip_positioner.h",
"wm/pip/pip_window_resizer.cc", "wm/pip/pip_window_resizer.cc",
"wm/pip/pip_window_resizer.h", "wm/pip/pip_window_resizer.h",
"wm/property_util.cc", "wm/property_util.cc",
...@@ -1967,6 +1969,7 @@ test("ash_unittests") { ...@@ -1967,6 +1969,7 @@ test("ash_unittests") {
"wm/overview/cleanup_animation_observer_unittest.cc", "wm/overview/cleanup_animation_observer_unittest.cc",
"wm/overview/window_selector_controller_unittest.cc", "wm/overview/window_selector_controller_unittest.cc",
"wm/overview/window_selector_unittest.cc", "wm/overview/window_selector_unittest.cc",
"wm/pip/pip_positioner_unittest.cc",
"wm/pip/pip_window_resizer_unittest.cc", "wm/pip/pip_window_resizer_unittest.cc",
"wm/resize_shadow_and_cursor_unittest.cc", "wm/resize_shadow_and_cursor_unittest.cc",
"wm/root_window_layout_manager_unittest.cc", "wm/root_window_layout_manager_unittest.cc",
......
// Copyright 2018 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/pip/pip_positioner.h"
#include <algorithm>
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"
#include "ui/keyboard/keyboard_controller.h"
namespace ash {
namespace {
const int kPipWorkAreaInsetsDp = 8;
enum { GRAVITY_LEFT, GRAVITY_RIGHT, GRAVITY_TOP, GRAVITY_BOTTOM };
// Returns the result of adjusting |bounds| according to |gravity| inside
// |region|.
gfx::Rect GetAdjustedBoundsByGravity(const gfx::Rect& bounds,
const gfx::Rect& region,
int gravity) {
switch (gravity) {
case GRAVITY_LEFT:
return gfx::Rect(region.x(), bounds.y(), bounds.width(), bounds.height());
case GRAVITY_RIGHT:
return gfx::Rect(region.right() - bounds.width(), bounds.y(),
bounds.width(), bounds.height());
case GRAVITY_TOP:
return gfx::Rect(bounds.x(), region.y(), bounds.width(), bounds.height());
case GRAVITY_BOTTOM:
return gfx::Rect(bounds.x(), region.bottom() - bounds.height(),
bounds.width(), bounds.height());
default:
NOTREACHED();
}
return bounds;
}
} // namespace
gfx::Rect PipPositioner::GetMovementArea(const display::Display& display) {
gfx::Rect work_area = display.work_area();
auto* keyboard_controller = keyboard::KeyboardController::Get();
// Include keyboard if it's not floating.
if (keyboard_controller->IsEnabled() &&
keyboard_controller->GetActiveContainerType() !=
keyboard::ContainerType::FLOATING) {
gfx::Rect keyboard_bounds = keyboard_controller->visual_bounds_in_screen();
work_area.Subtract(keyboard_bounds);
}
work_area.Inset(kPipWorkAreaInsetsDp, kPipWorkAreaInsetsDp);
return work_area;
}
gfx::Rect PipPositioner::GetBoundsForDrag(const display::Display& display,
const gfx::Rect& bounds) {
gfx::Rect drag_bounds = bounds;
drag_bounds.AdjustToFit(GetMovementArea(display));
return drag_bounds;
}
gfx::Rect PipPositioner::GetRestingPosition(const display::Display& display,
const gfx::Rect& bounds) {
gfx::Rect resting_bounds = bounds;
gfx::Rect area = GetMovementArea(display);
resting_bounds.AdjustToFit(area);
gfx::Point pip_center = resting_bounds.CenterPoint();
gfx::Point area_center = area.CenterPoint();
gfx::Vector2d direction = pip_center - area_center;
int gravity = 0;
if (std::abs(direction.x()) > std::abs(direction.y())) {
gravity = direction.x() < 0 ? GRAVITY_LEFT : GRAVITY_RIGHT;
} else {
gravity = direction.y() < 0 ? GRAVITY_TOP : GRAVITY_BOTTOM;
}
return GetAdjustedBoundsByGravity(resting_bounds, area, gravity);
}
} // namespace ash
// Copyright 2018 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.
#ifndef ASH_WM_PIP_PIP_POSITIONER_H_
#define ASH_WM_PIP_PIP_POSITIONER_H_
#include "ash/ash_export.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/rect.h"
namespace ash {
class PipPositionerTest;
class ASH_EXPORT PipPositioner {
public:
PipPositioner() = delete;
~PipPositioner() = delete;
// Returns the area that the PIP window can be positioned inside for a given
// display |display|.
static gfx::Rect GetMovementArea(const display::Display& display);
// Returns the position the PIP window should come to rest at. For example,
// this will be at a screen edge, not in the middle of the screen.
// TODO(edcourtney): This should consider drag velocity for fling as well.
static gfx::Rect GetRestingPosition(const display::Display& display,
const gfx::Rect& bounds);
// Adjusts bounds during a drag of a PIP window. For example, this will
// ensure that the PIP window cannot leave the PIP movement area.
// |bounds| is in screen coordinates.
static gfx::Rect GetBoundsForDrag(const display::Display& display,
const gfx::Rect& bounds);
private:
friend class PipPositionerTest;
DISALLOW_COPY_AND_ASSIGN(PipPositioner);
};
} // namespace ash
#endif // ASH_WM_PIP_PIP_POSITIONER_H_
// Copyright 2018 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/pip/pip_positioner.h"
#include <memory>
#include <string>
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "ash/wm/wm_event.h"
#include "base/command_line.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_switches.h"
#include "ui/keyboard/keyboard_util.h"
namespace ash {
namespace {
// WindowState based on a given initial state.
class FakeWindowState : public wm::WindowState::State {
public:
explicit FakeWindowState(mojom::WindowStateType initial_state_type)
: state_type_(initial_state_type) {}
~FakeWindowState() override = default;
// WindowState::State overrides:
void OnWMEvent(wm::WindowState* window_state,
const wm::WMEvent* event) override {}
mojom::WindowStateType GetType() const override { return state_type_; }
void AttachState(wm::WindowState* window_state,
wm::WindowState::State* previous_state) override {}
void DetachState(wm::WindowState* window_state) override {}
private:
mojom::WindowStateType state_type_;
DISALLOW_COPY_AND_ASSIGN(FakeWindowState);
};
} // namespace
class PipPositionerTest : public AshTestBase {
public:
PipPositionerTest() = default;
~PipPositionerTest() override = default;
void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
keyboard::switches::kEnableVirtualKeyboard);
AshTestBase::SetUp();
keyboard::SetTouchKeyboardEnabled(true);
Shell::Get()->EnableKeyboard();
UpdateWorkArea("400x400");
window_ = CreateTestWindowInShellWithBounds(gfx::Rect(200, 200, 100, 100));
wm::WindowState* window_state = wm::GetWindowState(window_);
test_state_ = new FakeWindowState(mojom::WindowStateType::PIP);
window_state->SetStateObject(
std::unique_ptr<wm::WindowState::State>(test_state_));
}
void TearDown() override {
keyboard::SetTouchKeyboardEnabled(false);
AshTestBase::TearDown();
}
void UpdateWorkArea(const std::string& bounds) {
UpdateDisplay(bounds);
aura::Window* root = Shell::GetPrimaryRootWindow();
Shell::Get()->SetDisplayWorkAreaInsets(root, gfx::Insets());
}
protected:
aura::Window* window() { return window_; }
wm::WindowState* window_state() { return wm::GetWindowState(window_); }
FakeWindowState* test_state() { return test_state_; }
private:
aura::Window* window_;
FakeWindowState* test_state_;
DISALLOW_COPY_AND_ASSIGN(PipPositionerTest);
};
TEST_F(PipPositionerTest, PipMovementAreaIsInset) {
gfx::Rect area = PipPositioner::GetMovementArea(window_state()->GetDisplay());
EXPECT_EQ("8,8 384x384", area.ToString());
}
TEST_F(PipPositionerTest, PipMovementAreaIncludesKeyboardIfKeyboardIsShown) {
auto* keyboard_controller = keyboard::KeyboardController::Get();
keyboard_controller->ShowKeyboard(true /* lock */);
keyboard_controller->NotifyKeyboardWindowLoaded();
aura::Window* keyboard_window = keyboard_controller->GetKeyboardWindow();
keyboard_window->SetBounds(gfx::Rect(0, 300, 400, 100));
gfx::Rect area = PipPositioner::GetMovementArea(window_state()->GetDisplay());
EXPECT_EQ(gfx::Rect(8, 8, 384, 284), area);
}
TEST_F(PipPositionerTest, PipRestingPositionSnapsToClosestEdge) {
auto display = window_state()->GetDisplay();
// Snap near top edge to top.
EXPECT_EQ("100,8 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(100, 50, 100, 100))
.ToString());
// Snap near bottom edge to bottom.
EXPECT_EQ("100,292 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(100, 250, 100, 100))
.ToString());
// Snap near left edge to left.
EXPECT_EQ("8,100 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(50, 100, 100, 100))
.ToString());
// Snap near right edge to right.
EXPECT_EQ("292,100 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(250, 100, 100, 100))
.ToString());
}
TEST_F(PipPositionerTest, PipRestingPositionSnapsInsideDisplay) {
auto display = window_state()->GetDisplay();
// Snap near top edge outside movement area to top.
EXPECT_EQ("100,8 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(100, -50, 100, 100))
.ToString());
// Snap near bottom edge outside movement area to bottom.
EXPECT_EQ("100,292 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(100, 450, 100, 100))
.ToString());
// Snap near left edge outside movement area to left.
EXPECT_EQ("8,100 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(-50, 100, 100, 100))
.ToString());
// Snap near right edge outside movement area to right.
EXPECT_EQ("292,100 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(450, 100, 100, 100))
.ToString());
}
TEST_F(PipPositionerTest, PipAdjustPositionForDragClampsToMovementArea) {
auto display = window_state()->GetDisplay();
// Adjust near top edge outside movement area.
EXPECT_EQ("100,8 100x100", PipPositioner::GetBoundsForDrag(
display, gfx::Rect(100, -50, 100, 100))
.ToString());
// Adjust near bottom edge outside movement area.
EXPECT_EQ("100,292 100x100", PipPositioner::GetBoundsForDrag(
display, gfx::Rect(100, 450, 100, 100))
.ToString());
// Adjust near left edge outside movement area.
EXPECT_EQ("8,100 100x100", PipPositioner::GetBoundsForDrag(
display, gfx::Rect(-50, 100, 100, 100))
.ToString());
// Adjust near right edge outside movement area.
EXPECT_EQ("292,100 100x100", PipPositioner::GetBoundsForDrag(
display, gfx::Rect(450, 100, 100, 100))
.ToString());
}
TEST_F(PipPositionerTest, PipRestingPositionWorksIfKeyboardIsDisabled) {
Shell::Get()->DisableKeyboard();
auto display = window_state()->GetDisplay();
// Snap near top edge to top.
EXPECT_EQ("100,8 100x100", PipPositioner::GetRestingPosition(
display, gfx::Rect(100, 50, 100, 100))
.ToString());
}
} // namespace ash
...@@ -4,13 +4,21 @@ ...@@ -4,13 +4,21 @@
#include "ash/wm/pip/pip_window_resizer.h" #include "ash/wm/pip/pip_window_resizer.h"
#include "ash/wm/pip/pip_positioner.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/coordinate_conversion.h"
namespace ash { namespace ash {
namespace {
// TODO(edcourtney): Consider varying the animation duration based on how far
// the pip window has to move.
const int kPipSnapToEdgeAnimationDurationMs = 50;
} // namespace
PipWindowResizer::PipWindowResizer(wm::WindowState* window_state) PipWindowResizer::PipWindowResizer(wm::WindowState* window_state)
: WindowResizer(window_state) { : WindowResizer(window_state) {
window_state->OnDragStarted(details().window_component); window_state->OnDragStarted(details().window_component);
...@@ -24,10 +32,11 @@ void PipWindowResizer::Drag(const gfx::Point& location_in_parent, ...@@ -24,10 +32,11 @@ void PipWindowResizer::Drag(const gfx::Point& location_in_parent,
::wm::ConvertPointToScreen(GetTarget()->parent(), &last_location_in_screen_); ::wm::ConvertPointToScreen(GetTarget()->parent(), &last_location_in_screen_);
gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent); gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent);
display::Display display = display::Display display = window_state()->GetDisplay();
display::Screen::GetScreen()->GetDisplayNearestWindow(GetTarget());
gfx::Rect work_area = display.work_area(); ::wm::ConvertRectToScreen(GetTarget()->parent(), &bounds);
bounds.AdjustToFit(work_area); bounds = PipPositioner::GetBoundsForDrag(display, bounds);
::wm::ConvertRectFromScreen(GetTarget()->parent(), &bounds);
if (bounds != GetTarget()->bounds()) { if (bounds != GetTarget()->bounds()) {
moved_or_resized_ = true; moved_or_resized_ = true;
...@@ -40,6 +49,22 @@ void PipWindowResizer::CompleteDrag() { ...@@ -40,6 +49,22 @@ void PipWindowResizer::CompleteDrag() {
window_state()->DeleteDragDetails(); window_state()->DeleteDragDetails();
window_state()->ClearRestoreBounds(); window_state()->ClearRestoreBounds();
window_state()->set_bounds_changed_by_user(moved_or_resized_); window_state()->set_bounds_changed_by_user(moved_or_resized_);
// Animate the PIP window to its resting position.
gfx::Rect bounds = PipPositioner::GetRestingPosition(
window_state()->GetDisplay(), GetTarget()->GetBoundsInScreen());
base::TimeDelta duration =
base::TimeDelta::FromMilliseconds(kPipSnapToEdgeAnimationDurationMs);
wm::SetBoundsEvent event(wm::WM_EVENT_SET_BOUNDS, bounds, /*animate=*/true,
duration);
window_state()->OnWMEvent(&event);
// If the pip work area changes (e.g. message center, virtual keyboard),
// we want to restore to the last explicitly set position.
// TODO(edcourtney): This may not be the best place for this. Consider
// doing this a different way or saving these bounds at a later point when
// the work area changes.
window_state()->SaveCurrentBoundsForRestore();
} }
void PipWindowResizer::RevertDrag() { void PipWindowResizer::RevertDrag() {
......
...@@ -9,11 +9,17 @@ ...@@ -9,11 +9,17 @@
#include "ash/shelf/shelf.h" #include "ash/shelf/shelf.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/wm_event.h" #include "ash/wm/wm_event.h"
#include "base/command_line.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/insets.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_switches.h"
#include "ui/keyboard/keyboard_util.h"
namespace ash { namespace ash {
namespace wm { namespace wm {
...@@ -60,19 +66,30 @@ class PipWindowResizerTest : public AshTestBase { ...@@ -60,19 +66,30 @@ class PipWindowResizerTest : public AshTestBase {
~PipWindowResizerTest() override = default; ~PipWindowResizerTest() override = default;
void SetUp() override { void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
keyboard::switches::kEnableVirtualKeyboard);
AshTestBase::SetUp(); AshTestBase::SetUp();
keyboard::SetTouchKeyboardEnabled(true);
Shell::Get()->EnableKeyboard();
window_ = CreateTestWindowInShellWithBounds(gfx::Rect(200, 200, 100, 100)); window_.reset(
wm::WindowState* window_state = wm::GetWindowState(window_); CreateTestWindowInShellWithBounds(gfx::Rect(200, 200, 100, 100)));
wm::WindowState* window_state = wm::GetWindowState(window_.get());
test_state_ = new FakeWindowState(mojom::WindowStateType::PIP); test_state_ = new FakeWindowState(mojom::WindowStateType::PIP);
window_state->SetStateObject( window_state->SetStateObject(
std::unique_ptr<wm::WindowState::State>(test_state_)); std::unique_ptr<wm::WindowState::State>(test_state_));
window_->SetProperty(aura::client::kAlwaysOnTopKey, true);
} }
void TearDown() override { AshTestBase::TearDown(); } void TearDown() override {
window_.reset();
keyboard::SetTouchKeyboardEnabled(false);
AshTestBase::TearDown();
}
protected: protected:
aura::Window* window() { return window_; } aura::Window* window() { return window_.get(); }
FakeWindowState* test_state() { return test_state_; } FakeWindowState* test_state() { return test_state_; }
PipWindowResizer* CreateResizerForTest(int window_component) { PipWindowResizer* CreateResizerForTest(int window_component) {
...@@ -98,7 +115,7 @@ class PipWindowResizerTest : public AshTestBase { ...@@ -98,7 +115,7 @@ class PipWindowResizerTest : public AshTestBase {
} }
private: private:
aura::Window* window_; std::unique_ptr<aura::Window> window_;
FakeWindowState* test_state_; FakeWindowState* test_state_;
DISALLOW_COPY_AND_ASSIGN(PipWindowResizerTest); DISALLOW_COPY_AND_ASSIGN(PipWindowResizerTest);
...@@ -129,19 +146,41 @@ TEST_F(PipWindowResizerTest, PipWindowDragIsRestrictedToWorkArea) { ...@@ -129,19 +146,41 @@ TEST_F(PipWindowResizerTest, PipWindowDragIsRestrictedToWorkArea) {
// Drag to the right. // Drag to the right.
resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0); resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
EXPECT_EQ("300,200 100x100", test_state()->last_bounds().ToString()); EXPECT_EQ("292,200 100x100", test_state()->last_bounds().ToString());
// Drag down. // Drag down.
resizer->Drag(CalculateDragPoint(*resizer, 0, 800), 0); resizer->Drag(CalculateDragPoint(*resizer, 0, 800), 0);
EXPECT_EQ("200,300 100x100", test_state()->last_bounds().ToString()); EXPECT_EQ("200,292 100x100", test_state()->last_bounds().ToString());
// Drag to the left. // Drag to the left.
resizer->Drag(CalculateDragPoint(*resizer, -800, 0), 0); resizer->Drag(CalculateDragPoint(*resizer, -800, 0), 0);
EXPECT_EQ("0,200 100x100", test_state()->last_bounds().ToString()); EXPECT_EQ("8,200 100x100", test_state()->last_bounds().ToString());
// Drag up. // Drag up.
resizer->Drag(CalculateDragPoint(*resizer, 0, -800), 0); resizer->Drag(CalculateDragPoint(*resizer, 0, -800), 0);
EXPECT_EQ("200,0 100x100", test_state()->last_bounds().ToString()); EXPECT_EQ("200,8 100x100", test_state()->last_bounds().ToString());
}
TEST_F(PipWindowResizerTest, PipWindowCanBeDraggedInTabletMode) {
Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
UpdateWorkArea("400x800");
std::unique_ptr<PipWindowResizer> resizer(CreateResizerForTest(HTCAPTION));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
EXPECT_EQ("200,210 100x100", test_state()->last_bounds().ToString());
}
TEST_F(PipWindowResizerTest, PipWindowCanBeResizedInTabletMode) {
Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
UpdateWorkArea("400x800");
std::unique_ptr<PipWindowResizer> resizer(CreateResizerForTest(HTBOTTOM));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
EXPECT_EQ("200,200 100x110", test_state()->last_bounds().ToString());
} }
} // namespace wm } // namespace wm
......
...@@ -484,6 +484,10 @@ void WindowState::OnRevertDrag(const gfx::Point& location) { ...@@ -484,6 +484,10 @@ void WindowState::OnRevertDrag(const gfx::Point& location) {
delegate_->OnDragFinished(/*canceled=*/true, location); delegate_->OnDragFinished(/*canceled=*/true, location);
} }
display::Display WindowState::GetDisplay() {
return display::Screen::GetScreen()->GetDisplayNearestWindow(window());
}
void WindowState::CreateDragDetails(const gfx::Point& point_in_parent, void WindowState::CreateDragDetails(const gfx::Point& point_in_parent,
int window_component, int window_component,
::wm::WindowMoveSource source) { ::wm::WindowMoveSource source) {
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/ui_base_types.h" #include "ui/base/ui_base_types.h"
#include "ui/compositor/layer_owner.h" #include "ui/compositor/layer_owner.h"
#include "ui/display/display.h"
#include "ui/gfx/animation/tween.h" #include "ui/gfx/animation/tween.h"
namespace gfx { namespace gfx {
...@@ -338,6 +339,9 @@ class ASH_EXPORT WindowState : public aura::WindowObserver { ...@@ -338,6 +339,9 @@ class ASH_EXPORT WindowState : public aura::WindowObserver {
const DragDetails* drag_details() const { return drag_details_.get(); } const DragDetails* drag_details() const { return drag_details_.get(); }
DragDetails* drag_details() { return drag_details_.get(); } DragDetails* drag_details() { return drag_details_.get(); }
// Returns the Display that this WindowState is on.
display::Display GetDisplay();
class TestApi { class TestApi {
public: public:
static State* GetStateImpl(WindowState* window_state) { static State* GetStateImpl(WindowState* window_state) {
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/window_factory.h" #include "ash/window_factory.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
...@@ -1882,50 +1881,4 @@ TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) { ...@@ -1882,50 +1881,4 @@ TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
touch_resize_window_->bounds().ToString()); touch_resize_window_->bounds().ToString());
} }
TEST_F(WorkspaceWindowResizerTest, PipCanBeResized) {
aura::Window* root_window = Shell::GetPrimaryRootWindow();
aura::Window* container =
Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer);
std::unique_ptr<aura::Window> window(
aura::test::CreateTestWindowWithId(0, container));
window->SetBounds(gfx::Rect(20, 30, 50, 60));
window->Show();
auto* fake_state = new FakeWindowState(mojom::WindowStateType::PIP);
wm::WindowState* window_state = wm::GetWindowState(window.get());
window_state->SetStateObject(
std::unique_ptr<wm::WindowState::State>(fake_state));
std::unique_ptr<WindowResizer> resizer(
CreateResizerForTest(window.get(), gfx::Point(), HTRIGHT));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
resizer->CompleteDrag();
EXPECT_EQ("20,30 100x60", fake_state->last_bounds().ToString());
}
TEST_F(WorkspaceWindowResizerTest, PipCanBeResizedInTabletMode) {
Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
aura::Window* root_window = Shell::GetPrimaryRootWindow();
aura::Window* container =
Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer);
std::unique_ptr<aura::Window> window(
aura::test::CreateTestWindowWithId(0, container));
window->SetBounds(gfx::Rect(20, 30, 50, 60));
window->Show();
auto* fake_state = new FakeWindowState(mojom::WindowStateType::PIP);
wm::WindowState* window_state = wm::GetWindowState(window.get());
window_state->SetStateObject(
std::unique_ptr<wm::WindowState::State>(fake_state));
std::unique_ptr<WindowResizer> resizer(
CreateResizerForTest(window.get(), gfx::Point(), HTRIGHT));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
resizer->CompleteDrag();
EXPECT_EQ("20,30 100x60", fake_state->last_bounds().ToString());
}
} // namespace ash } // namespace ash
...@@ -1903,9 +1903,9 @@ TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) { ...@@ -1903,9 +1903,9 @@ TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) {
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer( std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer(
window, gfx::Point(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE)); window, gfx::Point(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE));
resizer->Drag(gfx::Point(10, 0), 0); resizer->Drag(gfx::Point(10, 10), 0);
EXPECT_EQ(gfx::Rect(10, 0, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(10, 0, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->bounds());
resizer->CompleteDrag(); resizer->CompleteDrag();
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
-AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/0 -AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/0
-AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/1 -AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/1
-LockActionHandlerLayoutManagerTest.KeyboardBounds -LockActionHandlerLayoutManagerTest.KeyboardBounds
-PipPositionerTest.*
-PipWindowResizerTest.*
-ShellTest.KeyboardCreation -ShellTest.KeyboardCreation
-SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboard -SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboard
-SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered -SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered
......
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