Commit 1245672e authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

applist: Slide backdrop in or out on swipe up or down.

The backdrop now moves with the window when swiping up or down to use
home launcher gestures. This also allows non resizable windows to be
swiped up or down now.

Test: manual
Bug: 880605
Change-Id: I020f21fc04f95da55cd2c897841ade0b105d66ed
Reviewed-on: https://chromium-review.googlesource.com/1205593
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#588899}
parent 3b0118d7
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/app_list_controller_impl.h"
#include "ash/app_list/model/app_list_view_state.h" #include "ash/app_list/model/app_list_view_state.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h" #include "ash/screen_util.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h" #include "ash/wm/mru_window_tracker.h"
...@@ -13,6 +14,9 @@ ...@@ -13,6 +14,9 @@
#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/window_transient_descendant_iterator.h" #include "ash/wm/window_transient_descendant_iterator.h"
#include "ash/wm/workspace/backdrop_controller.h"
#include "ash/wm/workspace/workspace_layout_manager.h"
#include "ash/wm/workspace_controller.h"
#include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics.h"
#include "base/numerics/ranges.h" #include "base/numerics/ranges.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
...@@ -70,8 +74,7 @@ bool CanProcessWindow(aura::Window* window, ...@@ -70,8 +74,7 @@ bool CanProcessWindow(aura::Window* window,
if (Shell::Get()->window_selector_controller()->IsSelecting()) if (Shell::Get()->window_selector_controller()->IsSelecting())
return false; return false;
wm::WindowState* state = wm::GetWindowState(window); return true;
return state->CanMaximize() && state->CanResize();
} }
// Find the transform that will convert |src| to |dst|. // Find the transform that will convert |src| to |dst|.
...@@ -82,34 +85,28 @@ gfx::Transform CalculateTransform(const gfx::RectF& src, ...@@ -82,34 +85,28 @@ gfx::Transform CalculateTransform(const gfx::RectF& src,
dst.y() - src.y()); dst.y() - src.y());
} }
// Get the target offscreen bounds of |window|. These bounds will be used to // Get the target offscreen workspace bounds.
// calculate the transform which will move |window| out and offscreen. The width gfx::RectF GetOffscreenWorkspaceBounds(const gfx::RectF& work_area) {
// will be a ratio of the work area, and the height will maintain the aspect gfx::RectF new_work_area;
// ratio. new_work_area.set_x(((1.f - kWidthRatio) / 2.f) * work_area.width() +
gfx::RectF GetOffscreenBounds(aura::Window* window) { work_area.x());
gfx::RectF bounds = gfx::RectF(window->GetTargetBounds()); new_work_area.set_width(kWidthRatio * work_area.width());
gfx::RectF work_area = new_work_area.set_height(kWidthRatio * work_area.height());
gfx::RectF(screen_util::GetDisplayWorkAreaBoundsInParent(window)); new_work_area.set_y(work_area.y() - work_area.height());
float aspect_ratio = bounds.width() / bounds.height(); return new_work_area;
work_area.set_x(((1.f - kWidthRatio) / 2.f) * work_area.width() +
work_area.x());
work_area.set_width(kWidthRatio * work_area.width());
work_area.set_height(work_area.width() / aspect_ratio);
work_area.set_y(work_area.y() - work_area.height());
return work_area;
} }
// Get the target bounds of a transient descendant of the window we are hiding. // Get the target bounds of a window. It should maintain the same ratios
// It should maintain the same ratios to the main window. // relative the work area.
gfx::RectF GetTransientDescendantBounds(aura::Window* transient_descendant, gfx::RectF GetOffscreenWindowBounds(aura::Window* window,
const gfx::RectF& src, const gfx::RectF& src_work_area,
const gfx::RectF& dst) { const gfx::RectF& dst_work_area) {
gfx::RectF bounds = gfx::RectF(transient_descendant->GetTargetBounds()); gfx::RectF bounds = gfx::RectF(window->GetTargetBounds());
float ratio = dst.width() / src.width(); float ratio = dst_work_area.width() / src_work_area.width();
gfx::RectF dst_bounds; gfx::RectF dst_bounds;
dst_bounds.set_x(bounds.x() * ratio + dst.x()); dst_bounds.set_x(bounds.x() * ratio + dst_work_area.x());
dst_bounds.set_y(bounds.y() * ratio + dst.y()); dst_bounds.set_y(bounds.y() * ratio + dst_work_area.y());
dst_bounds.set_width(bounds.width() * ratio); dst_bounds.set_width(bounds.width() * ratio);
dst_bounds.set_height(bounds.height() * ratio); dst_bounds.set_height(bounds.height() * ratio);
return dst_bounds; return dst_bounds;
...@@ -132,6 +129,18 @@ void UpdateSettings(ui::ScopedLayerAnimationSettings* settings) { ...@@ -132,6 +129,18 @@ void UpdateSettings(ui::ScopedLayerAnimationSettings* settings) {
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
} }
// Returns the window of the widget which contains the workspace backdrop. May
// be nullptr if the backdrop is not shown.
aura::Window* GetBackdropWindow(aura::Window* window) {
WorkspaceLayoutManager* layout_manager =
RootWindowController::ForWindow(window->GetRootWindow())
->workspace_controller()
->layout_manager();
return layout_manager
? layout_manager->backdrop_controller()->backdrop_window()
: nullptr;
}
// Helper class to perform window state changes without animations. Used to hide // Helper class to perform window state changes without animations. Used to hide
// and minimize windows without having their animation interfere with the ones // and minimize windows without having their animation interfere with the ones
// this class is in charge of. // this class is in charge of.
...@@ -194,14 +203,35 @@ bool HomeLauncherGestureHandler::OnPressEvent(Mode mode) { ...@@ -194,14 +203,35 @@ bool HomeLauncherGestureHandler::OnPressEvent(Mode mode) {
window_->layer()->SetOpacity(1.f); window_->layer()->SetOpacity(1.f);
} }
const gfx::RectF& current_bounds = gfx::RectF(window_->GetTargetBounds()); const gfx::RectF work_area =
const gfx::RectF& target_bounds = GetOffscreenBounds(window_); gfx::RectF(screen_util::GetDisplayWorkAreaBoundsInParent(window_));
const gfx::RectF target_work_area = GetOffscreenWorkspaceBounds(work_area);
// Calculate the values for the main window. // Calculate the values for the main window.
const gfx::RectF& current_bounds = gfx::RectF(window_->GetTargetBounds());
window_values_.initial_opacity = window_->layer()->opacity(); window_values_.initial_opacity = window_->layer()->opacity();
window_values_.initial_transform = window_->transform(); window_values_.initial_transform = window_->transform();
window_values_.target_opacity = 0.f; window_values_.target_opacity = 0.f;
window_values_.target_transform = window_values_.target_transform = CalculateTransform(
CalculateTransform(current_bounds, target_bounds); current_bounds,
GetOffscreenWindowBounds(window_, work_area, target_work_area));
aura::Window* backdrop_window = GetBackdropWindow(window_);
if (backdrop_window) {
// Store the values needed to transform the backdrop. The backdrop actually
// covers the area behind the shelf as well, so initially transform it to be
// sized to the work area. Without the transform tweak, there is an extra
// shelf sized black area under |window_|.
backdrop_values_ = base::make_optional(WindowValues());
backdrop_values_->initial_opacity = 1.f;
backdrop_values_->initial_transform = gfx::Transform(
1.f, 0.f, 0.f,
work_area.height() /
static_cast<float>(backdrop_window->bounds().height()),
0.f, 0.f);
backdrop_values_->target_opacity = 0.f;
backdrop_values_->target_transform = CalculateTransform(
gfx::RectF(backdrop_window->bounds()), target_work_area);
}
// Calculate the values for any transient descendants. // Calculate the values for any transient descendants.
transient_descendants_values_.clear(); transient_descendants_values_.clear();
...@@ -215,7 +245,7 @@ bool HomeLauncherGestureHandler::OnPressEvent(Mode mode) { ...@@ -215,7 +245,7 @@ bool HomeLauncherGestureHandler::OnPressEvent(Mode mode) {
values.target_opacity = 0.f; values.target_opacity = 0.f;
values.target_transform = CalculateTransform( values.target_transform = CalculateTransform(
gfx::RectF(window->GetTargetBounds()), gfx::RectF(window->GetTargetBounds()),
GetTransientDescendantBounds(window, current_bounds, target_bounds)); GetOffscreenWindowBounds(window, work_area, target_work_area));
window->AddObserver(this); window->AddObserver(this);
transient_descendants_values_[window] = values; transient_descendants_values_[window] = values;
} }
...@@ -314,6 +344,14 @@ void HomeLauncherGestureHandler::OnImplicitAnimationsCompleted() { ...@@ -314,6 +344,14 @@ void HomeLauncherGestureHandler::OnImplicitAnimationsCompleted() {
DCHECK(last_event_location_); DCHECK(last_event_location_);
DCHECK(window_); DCHECK(window_);
// Update the backdrop first as the backdrop controller listens for some state
// changes like minimizing below which may also alter the backdrop.
aura::Window* backdrop_window = GetBackdropWindow(window_);
if (backdrop_window) {
backdrop_window->SetTransform(gfx::Transform());
backdrop_window->layer()->SetOpacity(1.f);
}
if (GetHeightInWorkAreaAsRatio(last_event_location_->y(), window_) > 0.5) { if (GetHeightInWorkAreaAsRatio(last_event_location_->y(), window_) > 0.5) {
// Minimize the hidden windows so they can be used normally with alt+tab // Minimize the hidden windows so they can be used normally with alt+tab
// and overview. Minimize in reverse order to preserve mru ordering. // and overview. Minimize in reverse order to preserve mru ordering.
...@@ -367,6 +405,11 @@ void HomeLauncherGestureHandler::UpdateWindows(double progress, bool animate) { ...@@ -367,6 +405,11 @@ void HomeLauncherGestureHandler::UpdateWindows(double progress, bool animate) {
window->SetTransform(transform); window->SetTransform(transform);
}; };
aura::Window* backdrop_window = GetBackdropWindow(window_);
if (backdrop_window && backdrop_values_) {
update_windows_helper(progress, animate, backdrop_window,
*backdrop_values_);
}
for (const auto& descendant : transient_descendants_values_) { for (const auto& descendant : transient_descendants_values_) {
update_windows_helper(progress, animate, descendant.first, update_windows_helper(progress, animate, descendant.first,
descendant.second); descendant.second);
...@@ -391,6 +434,7 @@ void HomeLauncherGestureHandler::UpdateWindows(double progress, bool animate) { ...@@ -391,6 +434,7 @@ void HomeLauncherGestureHandler::UpdateWindows(double progress, bool animate) {
} }
void HomeLauncherGestureHandler::RemoveObserversAndStopTracking() { void HomeLauncherGestureHandler::RemoveObserversAndStopTracking() {
backdrop_values_ = base::nullopt;
last_event_location_ = base::nullopt; last_event_location_ = base::nullopt;
mode_ = Mode::kNone; mode_ = Mode::kNone;
......
...@@ -90,6 +90,10 @@ class ASH_EXPORT HomeLauncherGestureHandler : aura::WindowObserver, ...@@ -90,6 +90,10 @@ class ASH_EXPORT HomeLauncherGestureHandler : aura::WindowObserver,
// Original and target transform and opacity of |window_|. // Original and target transform and opacity of |window_|.
WindowValues window_values_; WindowValues window_values_;
// Original and target transform and opacity of the backdrop window. Empty if
// there is no backdrop on mouse pressed.
base::Optional<WindowValues> backdrop_values_;
// Tracks the transient descendants of |window_| and their initial and target // Tracks the transient descendants of |window_| and their initial and target
// opacities and transforms. // opacities and transforms.
std::map<aura::Window*, WindowValues> transient_descendants_values_; std::map<aura::Window*, WindowValues> transient_descendants_values_;
......
...@@ -64,6 +64,8 @@ class BackdropController : public ShellObserver, ...@@ -64,6 +64,8 @@ class BackdropController : public ShellObserver,
// the other windows in the container. // the other windows in the container.
void UpdateBackdrop(); void UpdateBackdrop();
aura::Window* backdrop_window() { return backdrop_window_; }
// ShellObserver: // ShellObserver:
void OnOverviewModeStarting() override; void OnOverviewModeStarting() override;
void OnOverviewModeEnded() override; void OnOverviewModeEnded() override;
......
...@@ -49,7 +49,11 @@ class ASH_EXPORT WorkspaceLayoutManager ...@@ -49,7 +49,11 @@ class ASH_EXPORT WorkspaceLayoutManager
// the WorkspaceLayoutManager. // the WorkspaceLayoutManager.
void SetBackdropDelegate(std::unique_ptr<BackdropDelegate> delegate); void SetBackdropDelegate(std::unique_ptr<BackdropDelegate> delegate);
// Overridden from aura::LayoutManager: BackdropController* backdrop_controller() {
return backdrop_controller_.get();
}
// aura::LayoutManager:
void OnWindowResized() override; void OnWindowResized() override;
void OnWindowAddedToLayout(aura::Window* child) override; void OnWindowAddedToLayout(aura::Window* child) override;
void OnWillRemoveWindowFromLayout(aura::Window* child) override; void OnWillRemoveWindowFromLayout(aura::Window* child) override;
...@@ -59,7 +63,7 @@ class ASH_EXPORT WorkspaceLayoutManager ...@@ -59,7 +63,7 @@ class ASH_EXPORT WorkspaceLayoutManager
void SetChildBounds(aura::Window* child, void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) override; const gfx::Rect& requested_bounds) override;
// Overriden from aura::WindowObserver: // aura::WindowObserver:
void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override; void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override;
void OnWindowPropertyChanged(aura::Window* window, void OnWindowPropertyChanged(aura::Window* window,
const void* key, const void* key,
...@@ -71,7 +75,7 @@ class ASH_EXPORT WorkspaceLayoutManager ...@@ -71,7 +75,7 @@ class ASH_EXPORT WorkspaceLayoutManager
const gfx::Rect& new_bounds, const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override; ui::PropertyChangeReason reason) override;
// wm::ActivationChangeObserver overrides: // wm::ActivationChangeObserver:
void OnWindowActivating(ActivationReason reason, void OnWindowActivating(ActivationReason reason,
aura::Window* gaining_active, aura::Window* gaining_active,
aura::Window* losing_active) override; aura::Window* losing_active) override;
...@@ -80,19 +84,19 @@ class ASH_EXPORT WorkspaceLayoutManager ...@@ -80,19 +84,19 @@ class ASH_EXPORT WorkspaceLayoutManager
aura::Window* gained_active, aura::Window* gained_active,
aura::Window* lost_active) override; aura::Window* lost_active) override;
// keyboard::KeyboardControllerObserver overrides: // keyboard::KeyboardControllerObserver:
void OnKeyboardWorkspaceDisplacingBoundsChanged( void OnKeyboardWorkspaceDisplacingBoundsChanged(
const gfx::Rect& new_bounds) override; const gfx::Rect& new_bounds) override;
// WindowStateObserver overrides: // WindowStateObserver:
void OnPostWindowStateTypeChange(wm::WindowState* window_state, void OnPostWindowStateTypeChange(wm::WindowState* window_state,
mojom::WindowStateType old_type) override; mojom::WindowStateType old_type) override;
// display::DisplayObserver overrides: // display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display, void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
// ShellObserver overrides: // ShellObserver:
void OnFullscreenStateChanged(bool is_fullscreen, void OnFullscreenStateChanged(bool is_fullscreen,
aura::Window* root_window) override; aura::Window* root_window) override;
void OnPinnedStateChanged(aura::Window* pinned_window) override; void OnPinnedStateChanged(aura::Window* pinned_window) override;
......
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