Chromium Code Reviews| Index: ash/common/wm/overview/scoped_transform_overview_window.cc |
| diff --git a/ash/common/wm/overview/scoped_transform_overview_window.cc b/ash/common/wm/overview/scoped_transform_overview_window.cc |
| index f7c928cb755fa8f38a30f3f607996e189a147fd2..48942ea3a1a29f0d3bbaa05eb3c6f550aa01eb34 100644 |
| --- a/ash/common/wm/overview/scoped_transform_overview_window.cc |
| +++ b/ash/common/wm/overview/scoped_transform_overview_window.cc |
| @@ -11,6 +11,9 @@ |
| #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
| #include "ash/common/wm/overview/window_selector_item.h" |
| #include "ash/common/wm/window_state.h" |
| +#include "ash/common/wm_lookup.h" |
| +#include "ash/common/wm_root_window_controller.h" |
| +#include "ash/common/wm_shell.h" |
| #include "ash/common/wm_window.h" |
| #include "ash/common/wm_window_property.h" |
| #include "base/macros.h" |
| @@ -20,6 +23,7 @@ |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/safe_integer_conversions.h" |
| #include "ui/gfx/transform_util.h" |
| +#include "ui/views/widget/widget.h" |
| using WmWindows = std::vector<ash::WmWindow*>; |
| @@ -30,9 +34,6 @@ namespace { |
| // When set to true by tests makes closing the widget synchronous. |
| bool immediate_close_for_tests = false; |
| -// The opacity level that windows will be set to when they are restored. |
| -const float kRestoreWindowOpacity = 1.0f; |
| - |
| // Delay closing window to allow it to shrink and fade out. |
| const int kCloseWindowDelayInMilliseconds = 150; |
| @@ -169,56 +170,36 @@ TransientDescendantIteratorRange GetTransientTreeIterator(WmWindow* window) { |
| ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) |
| : window_(window), |
| determined_original_window_shape_(false), |
| - original_visibility_( |
| - window->GetWindowState()->GetStateType() == |
| - wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED |
| - ? ORIGINALLY_DOCKED_MINIMIZED |
| - : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED |
| - ? ORIGINALLY_MINIMIZED |
| - : ORIGINALLY_VISIBLE)), |
| ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), |
| overview_started_(false), |
| original_transform_(window->GetTargetTransform()), |
| - original_opacity_(window->GetTargetOpacity()), |
| weak_ptr_factory_(this) {} |
| ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} |
| void ScopedTransformOverviewWindow::RestoreWindow() { |
| + ShowHeader(); |
| + if (minimized_) { |
| + // TODO(oshima): Use unminimize animation instead of hiding animation. |
| + minimized_->CloseNow(); |
| + minimized_.reset(); |
| + return; |
| + } |
| ScopedAnimationSettings animation_settings_list; |
| BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
| &animation_settings_list); |
| SetTransform(window()->GetRootWindow(), original_transform_); |
| - |
| std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
| CreateScopedOverviewAnimationSettings( |
| OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
| window_); |
| - gfx::Transform transform; |
| - if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
| - window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || |
| - (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
| - window_->GetWindowState()->GetStateType() != |
| - wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { |
| - // Setting opacity 0 and visible false ensures that the property change |
| - // to SHOW_STATE_MINIMIZED will not animate the window from its original |
| - // bounds to the minimized position. |
| - // Hiding the window needs to be done before the target opacity is 0, |
| - // otherwise the layer's visibility will not be updated |
| - // (See VisibilityController::UpdateLayerVisibility). |
| - window_->Hide(); |
| - window_->SetOpacity(0); |
| - window_->SetShowState(ui::SHOW_STATE_MINIMIZED); |
| - } |
| window_->GetWindowState()->set_ignored_by_shelf(ignored_by_shelf_); |
| - SetOpacity(original_opacity_); |
| - ShowHeader(); |
| } |
| void ScopedTransformOverviewWindow::BeginScopedAnimation( |
| OverviewAnimationType animation_type, |
| ScopedAnimationSettings* animation_settings) { |
| - for (auto* window : GetTransientTreeIterator(window_)) { |
| + for (auto* window : GetTransientTreeIterator(GetOverviewWindow())) { |
| animation_settings->push_back( |
| CreateScopedOverviewAnimationSettings(animation_type, window)); |
| } |
| @@ -229,15 +210,18 @@ bool ScopedTransformOverviewWindow::Contains(const WmWindow* target) const { |
| if (window->Contains(target)) |
| return true; |
| } |
| - return false; |
| + WmWindow* mirror = GetOverviewWindowForMinimizedState(); |
| + return mirror && mirror->Contains(target); |
| } |
| gfx::Rect ScopedTransformOverviewWindow::GetTargetBoundsInScreen() const { |
| gfx::Rect bounds; |
| - for (auto* window : GetTransientTreeIterator(window_)) { |
| + WmWindow* overview_window = GetOverviewWindow(); |
| + for (auto* window : GetTransientTreeIterator(overview_window)) { |
| // Ignore other window types when computing bounding box of window |
| // selector target item. |
| - if (window != window_ && window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| + if (window != overview_window && |
| + window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| window->GetType() != ui::wm::WINDOW_TYPE_PANEL) { |
| continue; |
| } |
| @@ -248,16 +232,15 @@ gfx::Rect ScopedTransformOverviewWindow::GetTargetBoundsInScreen() const { |
| } |
| gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds() const { |
| - if (window_->GetWindowState()->IsMinimized()) |
| - return window_->GetMinimizeAnimationTargetBoundsInScreen(); |
|
varkha
2016/11/15 20:17:22
nit: Is WmWindow::GetMinimizeAnimationTargetBounds
oshima
2016/11/16 14:58:27
Yes, we're going to fix this.
|
| - |
| const int top_inset = GetTopInset(); |
| gfx::Rect bounds; |
| - for (auto* window : GetTransientTreeIterator(window_)) { |
| + WmWindow* overview_window = GetOverviewWindow(); |
| + for (auto* window : GetTransientTreeIterator(overview_window)) { |
| // Ignore other window types when computing bounding box of window |
| // selector target item. |
| - if (window != window_ && (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| - window->GetType() != ui::wm::WINDOW_TYPE_PANEL)) { |
| + if (window != overview_window && |
| + (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| + window->GetType() != ui::wm::WINDOW_TYPE_PANEL)) { |
| continue; |
| } |
| gfx::RectF window_bounds(window->GetTargetBounds()); |
| @@ -294,6 +277,9 @@ SkColor ScopedTransformOverviewWindow::GetTopColor() const { |
| } |
| int ScopedTransformOverviewWindow::GetTopInset() const { |
| + // Mirror window doesn't have insets. |
| + if (minimized_) |
| + return 0; |
| 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. |
| @@ -305,24 +291,6 @@ int ScopedTransformOverviewWindow::GetTopInset() const { |
| return window_->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET); |
| } |
| -void ScopedTransformOverviewWindow::ShowWindowIfMinimized() { |
| - if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
| - window_->GetShowState() == ui::SHOW_STATE_MINIMIZED) || |
| - (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
| - window_->GetWindowState()->GetStateType() == |
| - wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { |
| - window_->Show(); |
| - } |
| -} |
| - |
| -void ScopedTransformOverviewWindow::ShowWindowOnExit() { |
| - if (original_visibility_ != ORIGINALLY_VISIBLE) { |
| - original_visibility_ = ORIGINALLY_VISIBLE; |
| - original_transform_ = gfx::Transform(); |
| - original_opacity_ = kRestoreWindowOpacity; |
| - } |
| -} |
| - |
| void ScopedTransformOverviewWindow::OnWindowDestroyed() { |
| window_ = nullptr; |
| } |
| @@ -380,8 +348,7 @@ void ScopedTransformOverviewWindow::SetTransform( |
| } |
| gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |
| - |
| - for (auto* window : GetTransientTreeIterator(window_)) { |
| + for (auto* window : GetTransientTreeIterator(GetOverviewWindow())) { |
| WmWindow* parent_window = window->GetParent(); |
| gfx::Point original_origin = |
| parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); |
| @@ -394,12 +361,15 @@ void ScopedTransformOverviewWindow::SetTransform( |
| } |
| void ScopedTransformOverviewWindow::SetOpacity(float opacity) { |
| - for (auto* window : GetTransientTreeIterator(window_)) { |
| + for (auto* window : GetTransientTreeIterator(GetOverviewWindow())) { |
| window->SetOpacity(opacity); |
| } |
| } |
| void ScopedTransformOverviewWindow::HideHeader() { |
| + // Mirrored Window does not have a header. |
| + if (minimized_) |
| + return; |
| gfx::Rect bounds(GetTargetBoundsInScreen().size()); |
| const int inset = GetTopInset(); |
| if (inset > 0) { |
| @@ -409,8 +379,9 @@ void ScopedTransformOverviewWindow::HideHeader() { |
| region->setRect(RectToSkIRect(bounds)); |
| if (original_window_shape_) |
| region->op(*original_window_shape_, SkRegion::kIntersect_Op); |
| - window()->GetLayer()->SetAlphaShape(std::move(region)); |
| - window()->SetMasksToBounds(true); |
| + WmWindow* window = GetOverviewWindow(); |
| + window->GetLayer()->SetAlphaShape(std::move(region)); |
| + window->SetMasksToBounds(true); |
| } |
| } |
| @@ -425,6 +396,17 @@ void ScopedTransformOverviewWindow::ShowHeader() { |
| window()->SetMasksToBounds(false); |
| } |
| +void ScopedTransformOverviewWindow::UpdateMirrorWindowForMinimizedState() { |
| + // TODO(oshima): Disable animation. |
| + if (window_->GetShowState() == ui::SHOW_STATE_MINIMIZED) { |
| + if (!minimized_.get()) |
|
varkha
2016/11/15 20:10:21
nit: Same as "if (!minimized)"?
oshima
2016/11/16 14:58:27
Done.
|
| + CreateMirrorWindowForMinimizedState(); |
| + } else { |
| + minimized_->CloseNow(); |
| + minimized_.reset(); |
| + } |
| +} |
| + |
| void ScopedTransformOverviewWindow::Close() { |
| if (immediate_close_for_tests) { |
| CloseWidget(); |
| @@ -440,7 +422,8 @@ void ScopedTransformOverviewWindow::PrepareForOverview() { |
| DCHECK(!overview_started_); |
| overview_started_ = true; |
| window_->GetWindowState()->set_ignored_by_shelf(true); |
| - ShowWindowIfMinimized(); |
| + if (window_->GetShowState() == ui::SHOW_STATE_MINIMIZED) |
| + CreateMirrorWindowForMinimizedState(); |
| } |
| void ScopedTransformOverviewWindow::CloseWidget() { |
| @@ -454,4 +437,63 @@ void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { |
| immediate_close_for_tests = true; |
| } |
| +WmWindow* ScopedTransformOverviewWindow::GetOverviewWindow() const { |
| + if (minimized_) |
| + return GetOverviewWindowForMinimizedState(); |
| + return window_; |
| +} |
| + |
| +void ScopedTransformOverviewWindow::OnGestureEvent(ui::GestureEvent* event) { |
| + if (event->type() == ui::ET_GESTURE_TAP) { |
| + window_->Show(); |
| + window_->Activate(); |
| + } |
| +} |
| + |
| +void ScopedTransformOverviewWindow::OnMouseEvent(ui::MouseEvent* event) { |
| + if (event->type() == ui::ET_MOUSE_PRESSED && event->IsOnlyLeftMouseButton()) { |
| + window_->Show(); |
| + window_->Activate(); |
| + } |
| +} |
| + |
| +WmWindow* ScopedTransformOverviewWindow::GetOverviewWindowForMinimizedState() |
| + const { |
| + return minimized_ ? WmLookup::Get()->GetWindowForWidget(minimized_.get()) |
| + : nullptr; |
| +} |
| + |
| +void ScopedTransformOverviewWindow::CreateMirrorWindowForMinimizedState() { |
| + DCHECK(!minimized_.get()); |
| + views::Widget::InitParams params; |
| + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + params.visible_on_all_workspaces = true; |
| + params.name = "OverviewModeMinimized"; |
| + params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO; |
| + params.accept_events = true; |
| + minimized_.reset(new views::Widget); |
| + window_->GetRootWindow() |
| + ->GetRootWindowController() |
| + ->ConfigureWidgetInitParamsForContainer( |
| + minimized_.get(), window_->GetParent()->GetShellWindowId(), ¶ms); |
| + minimized_->set_focus_on_creation(false); |
| + minimized_->Init(params); |
| + |
| + views::View* mirror_view = window_->CreateViewWithRecreatedLayers().release(); |
| + mirror_view->SetVisible(true); |
| + mirror_view->SetTargetHandler(this); |
| + minimized_->SetContentsView(mirror_view); |
| + gfx::Rect bounds(window_->GetBoundsInScreen()); |
| + gfx::Size preferred = mirror_view->GetPreferredSize(); |
| + // In unit tests, the content view can have empty size. |
| + LOG(ERROR) << "Preferred:" << preferred.ToString(); |
|
varkha
2016/11/15 20:10:21
nit: remove before landing.
oshima
2016/11/16 14:58:27
Done.
|
| + if (!preferred.IsEmpty()) { |
| + int inset = bounds.height() - preferred.height(); |
| + bounds.Inset(0, 0, 0, inset); |
| + } |
| + minimized_->SetBounds(bounds); |
| + minimized_->Show(); |
| +} |
| + |
| } // namespace ash |