Commit 0e4a6217 authored by varkha's avatar varkha Committed by Commit bot

[ash-md] Properly scales windows with transient parents in overview

Previously to this CL the code was only considering the focused window
when calculating scale for the overview mode transform. It needs to
consider the bounding rectangle of the whole transient parent's tree.

BUG=632694

Review-Url: https://codereview.chromium.org/2197773002
Cr-Commit-Position: refs/heads/master@{#408763}
parent fbcc7784
......@@ -343,6 +343,52 @@ gfx::Rect ScopedTransformOverviewWindow::GetTargetBoundsInScreen() const {
return bounds;
}
gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds(
bool hide_header) const {
const bool material = ash::MaterialDesignController::IsOverviewMaterial();
const int top_inset = hide_header ? GetTopInset() : 0;
gfx::Rect bounds;
for (auto* window : GetTransientTreeIterator(window_)) {
// Ignore other window types when computing bounding box of window
// selector target item.
if (window != window_ &&
(!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL &&
window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) {
continue;
}
gfx::RectF window_bounds(window->GetTargetBounds());
gfx::Transform new_transform =
TransformAboutPivot(gfx::Point(window_bounds.x(), window_bounds.y()),
window->GetTargetTransform());
new_transform.TransformRect(&window_bounds);
// With Material Design the preview title is shown above the preview window.
// Hide the window header for apps or browser windows with no tabs (web
// apps) to avoid showing both the window header and the preview title.
if (material && top_inset > 0) {
gfx::RectF header_bounds(window_bounds);
header_bounds.set_height(top_inset);
new_transform.TransformRect(&header_bounds);
window_bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0);
}
bounds.Union(window->GetParent()->ConvertRectToScreen(
ToEnclosingRect(window_bounds)));
}
return bounds;
}
int ScopedTransformOverviewWindow::GetTopInset() const {
for (auto* window : GetTransientTreeIterator(window_)) {
// If there are regular windows in the transient ancestor tree, all those
// windows are shown in the same overview item and the header is not masked.
if (window != window_ && (window->GetType() == ui::wm::WINDOW_TYPE_NORMAL ||
window->GetType() == ui::wm::WINDOW_TYPE_PANEL)) {
return 0;
}
}
return window_->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET);
}
void ScopedTransformOverviewWindow::ShowWindowIfMinimized() {
if ((original_visibility_ == ORIGINALLY_MINIMIZED &&
window_->GetShowState() == ui::SHOW_STATE_MINIMIZED) ||
......@@ -439,10 +485,7 @@ void ScopedTransformOverviewWindow::SetTransform(
original_window_shape_.reset(new SkRegion(*window_shape));
}
gfx::Rect bounds(GetTargetBoundsInScreen().size());
const int inset =
(use_mask || use_shape)
? window()->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET)
: 0;
const int inset = (use_mask || use_shape) ? GetTopInset() : 0;
if (mask_) {
// Mask layer is used both to hide the window header and to use rounded
// corners. Its layout needs to be update when setting a transform.
......
......@@ -89,6 +89,18 @@ class ASH_EXPORT ScopedTransformOverviewWindow {
// Returns the original target bounds of all transformed windows.
gfx::Rect GetTargetBoundsInScreen() const;
// Calculates the bounds of a |window_| after being transformed to the
// selector's space. With Material Design those bounds are a union of all
// regular (normal and panel) windows in the |window_|'s transient hierarchy.
// The returned Rect is in virtual screen coordinates. When |hide_header| is
// true the returned bounds are adjusted to allow the original |window_|'s
// header to be hidden.
gfx::Rect GetTransformedBounds(bool hide_header) const;
// Returns TOP_VIEW_INSET property of |window_| unless there are transient
// ancestors in which case returns 0.
int GetTopInset() const;
// Restores and animates the managed window to it's non overview mode state.
void RestoreWindow();
......
......@@ -18,7 +18,6 @@
#include "ash/common/wm/overview/cleanup_animation_observer.h"
#include "ash/common/wm/overview/scoped_overview_animation_settings.h"
#include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h"
#include "ash/common/wm/overview/scoped_transform_overview_window.h"
#include "ash/common/wm/overview/window_selector.h"
#include "ash/common/wm/overview/window_selector_delegate.h"
#include "ash/common/wm/overview/window_selector_item.h"
......@@ -1014,7 +1013,7 @@ bool WindowGrid::FitWindowRectsInBounds(const gfx::Rect& bounds,
const gfx::Size item_size(0, height);
size_t i = 0;
for (auto* window : window_list_) {
const gfx::Rect target_bounds = window->GetWindow()->GetTargetBounds();
const gfx::Rect target_bounds = window->GetTargetBoundsInScreen();
const int width =
std::max(1, gfx::ToFlooredInt(target_bounds.width() *
window->GetItemScale(item_size)) +
......
......@@ -104,28 +104,6 @@ static const int kSelectorFadeInMilliseconds = 350;
// this fraction of size.
static const float kPreCloseScale = 0.02f;
// Calculates the |window| bounds after being transformed to the selector's
// space. The returned Rect is in virtual screen coordinates.
gfx::Rect GetTransformedBounds(WmWindow* window, bool hide_header) {
gfx::RectF bounds(
window->GetRootWindow()->ConvertRectToScreen(window->GetTargetBounds()));
gfx::Transform new_transform = TransformAboutPivot(
gfx::Point(bounds.x(), bounds.y()), window->GetTargetTransform());
new_transform.TransformRect(&bounds);
// With Material Design the preview title is shown above the preview window.
// Hide the window header for apps or browser windows with no tabs (web apps)
// to avoid showing both the window header and the preview title.
if (ash::MaterialDesignController::IsOverviewMaterial() && hide_header) {
gfx::RectF header_bounds(bounds);
header_bounds.set_height(
window->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET));
new_transform.TransformRect(&header_bounds);
bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0);
}
return ToEnclosingRect(bounds);
}
// Convenience method to fade in a Window with predefined animation settings.
// Note: The fade in animation will occur after a delay where the delay is how
// long the lay out animations take.
......@@ -460,15 +438,16 @@ void WindowSelectorItem::OnWindowTitleChanged(WmWindow* window) {
float WindowSelectorItem::GetItemScale(const gfx::Size& size) {
gfx::Size inset_size(size.width(), size.height() - 2 * kWindowMarginMD);
const int header_inset =
hide_header()
? GetWindow()->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET)
: 0;
return ScopedTransformOverviewWindow::GetItemScale(
GetWindow()->GetTargetBounds().size(), inset_size, header_inset,
transform_window_.GetTargetBoundsInScreen().size(), inset_size,
hide_header() ? transform_window_.GetTopInset() : 0,
close_button_->GetPreferredSize().height());
}
gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const {
return transform_window_.GetTargetBoundsInScreen();
}
void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
OverviewAnimationType animation_type) {
DCHECK(root_window_ == GetWindow()->GetRootWindow());
......@@ -482,10 +461,8 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
int top_view_inset = 0;
int title_height = 0;
if (ash::MaterialDesignController::IsOverviewMaterial()) {
if (hide_header()) {
top_view_inset =
GetWindow()->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET);
}
if (hide_header())
top_view_inset = transform_window_.GetTopInset();
title_height = close_button_->GetPreferredSize().height();
}
gfx::Rect selector_item_bounds =
......@@ -598,7 +575,7 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
void WindowSelectorItem::UpdateHeaderLayout(
OverviewAnimationType animation_type) {
gfx::Rect transformed_window_bounds = root_window_->ConvertRectFromScreen(
GetTransformedBounds(GetWindow(), hide_header()));
transform_window_.GetTransformedBounds(hide_header()));
if (ash::MaterialDesignController::IsOverviewMaterial()) {
gfx::Rect label_rect(close_button_->GetPreferredSize());
......
......@@ -84,6 +84,11 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
// returns the scale that allows the item to fully fit within |size|.
float GetItemScale(const gfx::Size& size);
// Returns the union of the original target bounds of all transformed windows
// managed by |this| item, i.e. all regular (normal or panel transient
// descendants of the window returned by GetWindow()).
gfx::Rect GetTargetBoundsInScreen() const;
// Sets the bounds of this window selector item to |target_bounds| in the
// |root_window_| root window. The bounds change will be animated as specified
// by |animation_type|.
......
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