1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/wm/dock/docked_window_layout_manager.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf_constants.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shelf/shelf_types.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shelf/shelf_widget.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shell.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shell_window_ids.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ash/wm/window_animations.h" 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ash/wm/window_properties.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_resizer.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/wm/window_util.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/workspace_controller.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/auto_reset.h" 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/command_line.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "grit/ash_resources.h" 26bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "third_party/skia/include/core/SkColor.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h" 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h" 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/window.h" 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window_delegate.h" 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/canvas.h" 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h" 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gfx/rect.h" 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/background.h" 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h" 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace ash { 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Minimum, maximum width of the dock area and a width of the gap 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const int DockedWindowLayoutManager::kMaxDockWidth = 360; 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst int DockedWindowLayoutManager::kMinDockWidth = 200; 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst int DockedWindowLayoutManager::kMinDockGap = 2; 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int DockedWindowLayoutManager::kIdealWidth = 250; 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const int kMinimumHeight = 250; 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kSlideDurationMs = 120; 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int kFadeDurationMs = 60; 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int kMinimizeDurationMs = 720; 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DockedBackgroundWidget : public views::Widget, 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public BackgroundAnimatorDelegate { 60bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch public: 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit DockedBackgroundWidget(aura::Window* container) 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : alignment_(DOCKED_ALIGNMENT_NONE), 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_animator_(this, 0, kShelfBackgroundAlpha), 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) alpha_(0), 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opaque_background_(ui::LAYER_SOLID_COLOR), 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_type_(SHELF_BACKGROUND_DEFAULT), 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_change_type_(BACKGROUND_CHANGE_IMMEDIATE) { 68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch InitWidget(container); 69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sets widget bounds and sizes opaque background layer to fill the widget. 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SetBackgroundBounds(const gfx::Rect bounds, DockedAlignment alignment) { 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetBounds(bounds); 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) opaque_background_.SetBounds(gfx::Rect(bounds.size())); 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) alignment_ = alignment; 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sets the background type. Starts an animation to transition to 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |background_type| if the widget is visible. If the widget is not visible, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the animation is postponed till the widget becomes visible. 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetBackgroundType(ShelfBackgroundType background_type, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BackgroundAnimatorChangeType change_type) { 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_type_ = background_type; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_change_type_ = change_type; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsVisible()) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateBackground(); 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // views::Widget: 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnNativeWidgetVisibilityChanged(bool visible) OVERRIDE { 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::Widget::OnNativeWidgetVisibilityChanged(visible); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateBackground(); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::ImageSkia& shelf_background( 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) alignment_ == DOCKED_ALIGNMENT_LEFT ? 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background_left_ : shelf_background_right_); 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect rect = gfx::Rect(GetWindowBoundsInScreen().size()); 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkPaint paint; 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) paint.setAlpha(alpha_); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawImageInt(shelf_background, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background.width(), 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background.height(), 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ == DOCKED_ALIGNMENT_LEFT 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? rect.width() - shelf_background.width() 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : 0, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background.width(), 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.height(), 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) paint); 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) canvas->DrawImageInt( 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background, 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ == DOCKED_ALIGNMENT_LEFT ? 0 : shelf_background.width() - 1, 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background.height(), 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ == DOCKED_ALIGNMENT_LEFT ? 0 : shelf_background.width(), 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.width() - shelf_background.width(), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.height(), 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) false, 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) paint); 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // BackgroundAnimatorDelegate: 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void UpdateBackground(int alpha) OVERRIDE { 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) alpha_ = alpha; 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SchedulePaintInRect(gfx::Rect(GetWindowBoundsInScreen().size())); 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 135bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch private: 136bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void InitWidget(aura::Window* parent) { 137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch views::Widget::InitParams params; 138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.type = views::Widget::InitParams::TYPE_POPUP; 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 140bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.keep_on_top = false; 141bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 142bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.parent = parent; 143bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.accept_events = false; 144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch set_focus_on_creation(false); 145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Init(params); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetVisibilityChangedAnimationsEnabled(false); 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetNativeWindow()->SetProperty(kStayInSameRootWindowKey, true); 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) opaque_background_.SetColor(SK_ColorBLACK); 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) opaque_background_.SetOpacity(0.0f); 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetNativeWindow()->layer()->Add(&opaque_background_); 152bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Hide(); 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::ImageSkia shelf_background = 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background, SkBitmapOperations::ROTATION_90_CW); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_background, SkBitmapOperations::ROTATION_270_CW); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Transitions to |visible_background_type_| if the widget is visible and to 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SHELF_BACKGROUND_DEFAULT if it is not. 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateBackground() { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfBackgroundType background_type = IsVisible() ? 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_type_ : SHELF_BACKGROUND_DEFAULT; 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BackgroundAnimatorChangeType change_type = IsVisible() ? 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float target_opacity = 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (background_type == SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ui::ScopedLayerAnimationSettings> opaque_background_animation; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (change_type != BACKGROUND_CHANGE_IMMEDIATE) { 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings( 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opaque_background_.GetAnimator())); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opaque_background_animation->SetTransitionDuration( 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kTimeToSwitchBackgroundMs)); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opaque_background_.SetOpacity(target_opacity); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(varkha): use ui::Layer on both opaque_background and normal 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // background retire background_animator_ at all. It would be simpler. 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // See also ShelfWidget::SetPaintsBackground. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_animator_.SetPaintsBackground( 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_type != SHELF_BACKGROUND_DEFAULT, 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) change_type); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SchedulePaintInRect(gfx::Rect(GetWindowBoundsInScreen().size())); 189bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 190bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DockedAlignment alignment_; 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The animator for the background transitions. 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BackgroundAnimator background_animator_; 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The alpha to use for drawing image assets covering the docked background. 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int alpha_; 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Solid black background that can be made fully opaque. 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::Layer opaque_background_; 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Backgrounds created from shelf background by 90 or 270 degree rotation. 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::ImageSkia shelf_background_left_; 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::ImageSkia shelf_background_right_; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The background type to use when the widget is visible. When not visible, 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the widget uses SHELF_BACKGROUND_DEFAULT. 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfBackgroundType visible_background_type_; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Whether the widget should animate to |visible_background_type_|. 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BackgroundAnimatorChangeType visible_background_change_type_; 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 213bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); 214bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}; 215bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns true if a window is a popup or a transient child. 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsPopupOrTransient(const aura::Window* window) { 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (window->type() == ui::wm::WINDOW_TYPE_POPUP || 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::GetTransientParent(window)); 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Certain windows (minimized, hidden or popups) do not matter to docking. 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsUsedByLayout(const aura::Window* window) { 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return (window->IsVisible() && 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !wm::GetWindowState(window)->IsMinimized() && 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !IsPopupOrTransient(window)); 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void UndockWindow(aura::Window* window) { 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Rect previous_bounds = window->bounds(); 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) aura::Window* old_parent = window->parent(); 2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::client::ParentWindowWithContext(window, window, gfx::Rect()); 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (window->parent() != old_parent) 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wm::ReparentTransientChildrenOfChild(window, old_parent, window->parent()); 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Start maximize or fullscreen (affecting packaged apps) animation from 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // previous window bounds. 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window->layer()->SetBounds(previous_bounds); 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Returns width that is as close as possible to |target_width| while being 2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// consistent with docked min and max restrictions and respects the |window|'s 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// minimum and maximum size. 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int GetWindowWidthCloseTo(const aura::Window* window, int target_width) { 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!wm::GetWindowState(window)->CanResize()) { 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_LE(window->bounds().width(), 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DockedWindowLayoutManager::kMaxDockWidth); 2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return window->bounds().width(); 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int width = std::max(DockedWindowLayoutManager::kMinDockWidth, 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::min(target_width, 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DockedWindowLayoutManager::kMaxDockWidth)); 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (window->delegate()) { 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (window->delegate()->GetMinimumSize().width() != 0) 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) width = std::max(width, window->delegate()->GetMinimumSize().width()); 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (window->delegate()->GetMaximumSize().width() != 0) 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) width = std::min(width, window->delegate()->GetMaximumSize().width()); 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return width; 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Returns height that is as close as possible to |target_height| while 2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// respecting the |window|'s minimum and maximum size. 2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int GetWindowHeightCloseTo(const aura::Window* window, int target_height) { 2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!wm::GetWindowState(window)->CanResize()) 2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return window->bounds().height(); 2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int minimum_height = kMinimumHeight; 2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int maximum_height = 0; 2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const aura::WindowDelegate* delegate(window->delegate()); 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (delegate) { 2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (delegate->GetMinimumSize().height() != 0) { 2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) minimum_height = std::max(kMinimumHeight, 2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delegate->GetMinimumSize().height()); 2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (delegate->GetMaximumSize().height() != 0) 2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) maximum_height = delegate->GetMaximumSize().height(); 2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (minimum_height) 2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) target_height = std::max(target_height, minimum_height); 2828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (maximum_height) 2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) target_height = std::min(target_height, maximum_height); 2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return target_height; 2858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A functor used to sort the windows in order of their minimum height. 2888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct CompareMinimumHeight { 2898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool operator()(WindowWithHeight win1, WindowWithHeight win2) { 2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GetWindowHeightCloseTo(win1.window(), 0) < 2918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetWindowHeightCloseTo(win2.window(), 0); 2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A functor used to sort the windows in order of their center Y position. 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// |delta| is a pre-calculated distance from the bottom of one window to the top 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// of the next. Its value can be positive (gap) or negative (overlap). 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Half of |delta| is used as a transition point at which windows could ideally 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// swap positions. 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct CompareWindowPos { 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CompareWindowPos(aura::Window* dragged_window, 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* docked_container, 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float delta) 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : dragged_window_(dragged_window), 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) docked_container_(docked_container), 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delta_(delta / 2) {} 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool operator()(WindowWithHeight window_with_height1, 3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) WindowWithHeight window_with_height2) { 31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Use target coordinates since animations may be active when windows are 31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // reordered. 3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) aura::Window* win1(window_with_height1.window()); 3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) aura::Window* win2(window_with_height2.window()); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect win1_bounds = ScreenUtil::ConvertRectToScreen( 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) docked_container_, win1->GetTargetBounds()); 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect win2_bounds = ScreenUtil::ConvertRectToScreen( 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) docked_container_, win2->GetTargetBounds()); 3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) win1_bounds.set_height(window_with_height1.height_); 3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) win2_bounds.set_height(window_with_height2.height_); 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If one of the windows is the |dragged_window_| attempt to make an 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // earlier swap between the windows than just based on their centers. 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This is possible if the dragged window is at least as tall as the other 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // window. 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (win1 == dragged_window_) 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return compare_two_windows(win1_bounds, win2_bounds); 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (win2 == dragged_window_) 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return !compare_two_windows(win2_bounds, win1_bounds); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Otherwise just compare the centers. 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return win1_bounds.CenterPoint().y() < win2_bounds.CenterPoint().y(); 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Based on center point tries to deduce where the drag is coming from. 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // When dragging from below up the transition point is lower. 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // When dragging from above down the transition point is higher. 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool compare_bounds(const gfx::Rect dragged, const gfx::Rect other) { 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (dragged.CenterPoint().y() < other.CenterPoint().y()) 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return dragged.CenterPoint().y() < other.y() - delta_; 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return dragged.CenterPoint().y() < other.bottom() + delta_; 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Performs comparison both ways and selects stable result. 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool compare_two_windows(const gfx::Rect bounds1, const gfx::Rect bounds2) { 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Try comparing windows in both possible orders and see if the comparison 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // is stable. 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool result1 = compare_bounds(bounds1, bounds2); 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool result2 = compare_bounds(bounds2, bounds1); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (result1 != result2) 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return result1; 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Otherwise it is not possible to be sure that the windows will not bounce. 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // In this case just compare the centers. 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return bounds1.CenterPoint().y() < bounds2.CenterPoint().y(); 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::Window* dragged_window_; 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* docked_container_; 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) float delta_; 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 360bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace 3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A class that observes shelf for bounds changes. 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DockedWindowLayoutManager::ShelfWindowObserver : public WindowObserver { 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit ShelfWindowObserver( 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DockedWindowLayoutManager* docked_layout_manager) 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : docked_layout_manager_(docked_layout_manager) { 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(docked_layout_manager_->shelf()->shelf_widget()); 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) docked_layout_manager_->shelf()->shelf_widget()->GetNativeView() 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->AddObserver(this); 373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~ShelfWindowObserver() { 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (docked_layout_manager_->shelf() && 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) docked_layout_manager_->shelf()->shelf_widget()) 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) docked_layout_manager_->shelf()->shelf_widget()->GetNativeView() 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->RemoveObserver(this); 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // aura::WindowObserver: 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnWindowBoundsChanged(aura::Window* window, 384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Rect& old_bounds, 385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Rect& new_bounds) OVERRIDE { 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_bounds_in_screen_ = ScreenUtil::ConvertRectToScreen( 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window->parent(), new_bounds); 388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) docked_layout_manager_->OnShelfBoundsChanged(); 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Rect& shelf_bounds_in_screen() const { 392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return shelf_bounds_in_screen_; 393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DockedWindowLayoutManager* docked_layout_manager_; 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect shelf_bounds_in_screen_; 398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); 400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager public implementation: 4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)DockedWindowLayoutManager::DockedWindowLayoutManager( 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) aura::Window* dock_container, 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WorkspaceController* workspace_controller) 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : SnapToPixelLayoutManager(dock_container), 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dock_container_(dock_container), 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) in_layout_(false), 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dragged_window_(NULL), 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_window_docked_(false), 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_from_dock_(false), 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_(NULL), 4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) workspace_controller_(workspace_controller), 4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) in_fullscreen_(workspace_controller_->GetWindowState() == 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WORKSPACE_WINDOW_STATE_FULL_SCREEN), 417ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch docked_width_(0), 418bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch alignment_(DOCKED_ALIGNMENT_NONE), 419bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch last_active_window_(NULL), 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_action_time_(base::Time::Now()), 421bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch background_widget_(new DockedBackgroundWidget(dock_container_)) { 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(dock_container); 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AddObserver(this); 4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Shell::GetInstance()->AddShellObserver(this); 4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)DockedWindowLayoutManager::~DockedWindowLayoutManager() { 429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Shutdown(); 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid DockedWindowLayoutManager::Shutdown() { 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_ && shelf_->shelf_widget()) { 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfLayoutManager* shelf_layout_manager = ShelfLayoutManager::ForShelf( 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_->shelf_widget()->GetNativeWindow()); 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shelf_layout_manager->RemoveObserver(this); 437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shelf_observer_.reset(); 438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_ = NULL; 4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < dock_container_->children().size(); ++i) { 4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) aura::Window* child = dock_container_->children()[i]; 4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) child->RemoveObserver(this); 4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::GetWindowState(child)->RemoveObserver(this); 4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RemoveObserver(this); 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Shell::GetInstance()->RemoveShellObserver(this); 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid DockedWindowLayoutManager::AddObserver( 451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DockedWindowLayoutManagerObserver* observer) { 452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch observer_list_.AddObserver(observer); 453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid DockedWindowLayoutManager::RemoveObserver( 456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DockedWindowLayoutManagerObserver* observer) { 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch observer_list_.RemoveObserver(observer); 458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::StartDragging(aura::Window* window) { 4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!dragged_window_); 4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dragged_window_ = window; 4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(window)); 4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Start observing a window unless it is docked container's child in which 4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // case it is already observed. 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wm::WindowState* dragged_state = wm::GetWindowState(dragged_window_); 4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (dragged_window_->parent() != dock_container_) { 4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dragged_window_->AddObserver(this); 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dragged_state->AddObserver(this); 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!IsAnyWindowDocked() && 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dragged_state->drag_details() && 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !(dragged_state->drag_details()->bounds_change & 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowResizer::kBoundsChange_Resizes)) { 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If there are no other docked windows clear alignment when a docked window 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is moved (but not when it is resized or the window could get undocked 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // when resized away from the edge while docked). 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ = DOCKED_ALIGNMENT_NONE; 4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_from_dock_ = window->parent() == dock_container_; 4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!is_dragged_window_docked_); 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Resize all windows that are flush with the dock edge together if one of 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // them gets resized. 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (dragged_window_->bounds().width() == docked_width_ && 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (dragged_state->drag_details()->bounds_change & 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowResizer::kBoundsChange_Resizes) && 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (dragged_state->drag_details()->size_change_direction & 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowResizer::kBoundsChangeDirection_Horizontal)) { 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < dock_container_->children().size(); ++i) { 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* window1(dock_container_->children()[i]); 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsUsedByLayout(window1) && 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window1 != dragged_window_ && 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window1->bounds().width() == docked_width_) { 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wm::GetWindowState(window1)->set_bounds_changed_by_user(false); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DockedWindowLayoutManager::DockDraggedWindow(aura::Window* window) { 5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(window)); 5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnDraggedWindowDocked(window); 5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DockedWindowLayoutManager::UndockDraggedWindow() { 5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(dragged_window_)); 5088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnDraggedWindowUndocked(); 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Relayout(); 5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_from_dock_ = false; 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 513ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DockedWindowLayoutManager::FinishDragging(DockedAction action, 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DockedActionSource source) { 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(dragged_window_); 5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(dragged_window_)); 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (is_dragged_window_docked_) 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnDraggedWindowUndocked(); 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK (!is_dragged_window_docked_); 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Stop observing a window unless it is docked container's child in which 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // case it needs to keep being observed after the drag completes. 523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (dragged_window_->parent() != dock_container_) { 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dragged_window_->RemoveObserver(this); 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::GetWindowState(dragged_window_)->RemoveObserver(this); 526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (last_active_window_ == dragged_window_) 527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_active_window_ = NULL; 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If this is the first window that got docked by a move update alignment. 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (alignment_ == DOCKED_ALIGNMENT_NONE) 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ = GetEdgeNearestWindow(dragged_window_); 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // A window is no longer dragged and is a child. 53368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // When a window becomes a child at drag start this is 53468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the only opportunity we will have to enforce a window 53568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // count limit so do it here. 53668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MaybeMinimizeChildrenExcept(dragged_window_); 537d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dragged_window_ = NULL; 539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dragged_bounds_ = gfx::Rect(); 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Relayout(); 5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordUmaAction(action, source); 5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DockedWindowLayoutManager::SetShelf(Shelf* shelf) { 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!shelf_); 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_ = shelf; 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_->shelf_widget()) { 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfLayoutManager* shelf_layout_manager = ShelfLayoutManager::ForShelf( 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_->shelf_widget()->GetNativeWindow()); 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shelf_layout_manager->AddObserver(this); 552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shelf_observer_.reset(new ShelfWindowObserver(this)); 553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const aura::Window* window) const { 5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const gfx::Rect& bounds(window->GetBoundsInScreen()); 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 560d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Test overlap with an existing docked area first. 561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (docked_bounds_.Intersects(bounds) && 562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) alignment_ != DOCKED_ALIGNMENT_NONE) { 563d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // A window is being added to other docked windows (on the same side). 564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return alignment_; 565d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); 568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (bounds.x() <= container_bounds.x() && 569d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bounds.right() > container_bounds.x()) { 5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return DOCKED_ALIGNMENT_LEFT; 571d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else if (bounds.x() < container_bounds.right() && 572d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bounds.right() >= container_bounds.right()) { 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return DOCKED_ALIGNMENT_RIGHT; 5743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return DOCKED_ALIGNMENT_NONE; 5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochDockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { 579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Find a child that is not being dragged and is not a popup. 580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If such exists the current alignment is returned - even if some of the 581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // children are hidden or minimized (so they can be restored without losing 582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // the docked state). 583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (size_t i = 0; i < dock_container_->children().size(); ++i) { 584ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch aura::Window* window(dock_container_->children()[i]); 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (window != dragged_window_ && !IsPopupOrTransient(window)) 586ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return alignment_; 587ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 588ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // No docked windows remain other than possibly the window being dragged. 589ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Return |NONE| to indicate that windows may get docked on either side. 590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return DOCKED_ALIGNMENT_NONE; 591ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 592ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DockedWindowLayoutManager::CanDockWindow( 594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Window* window, 595010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DockedAlignment desired_alignment) { 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't allow interactive docking of windows with transient parents such as 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // modal browser dialogs. Prevent docking of panels attached to shelf during 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the drag. 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wm::WindowState* window_state = wm::GetWindowState(window); 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool should_attach_to_shelf = window_state->drag_details() && 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->drag_details()->should_attach_to_shelf; 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsPopupOrTransient(window) || should_attach_to_shelf) 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 60468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If a window is wide and cannot be resized down to maximum width allowed 60568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // then it cannot be docked. 6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(varkha). Prevent windows from changing size programmatically while 6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // they are docked. The size will take effect only once a window is undocked. 6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // See http://crbug.com/307792. 60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (window->bounds().width() > kMaxDockWidth && 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (!window_state->CanResize() || 61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (window->delegate() && 61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window->delegate()->GetMinimumSize().width() != 0 && 61368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { 61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 61568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If a window is tall and cannot be resized down to maximum height allowed 6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // then it cannot be docked. 6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect work_area = 6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) 6218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 622d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Cannot dock on the other size from an existing dock. 623d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const DockedAlignment alignment = CalculateAlignment(); 624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (desired_alignment != DOCKED_ALIGNMENT_NONE && 625010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) alignment != DOCKED_ALIGNMENT_NONE && 626010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) alignment != desired_alignment) { 627d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 628d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Do not allow docking on the same side as shelf. 630d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_) 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_alignment = shelf_->alignment(); 633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((desired_alignment == DOCKED_ALIGNMENT_LEFT && 634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shelf_alignment == SHELF_ALIGNMENT_LEFT) || 635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (desired_alignment == DOCKED_ALIGNMENT_RIGHT && 636010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shelf_alignment == SHELF_ALIGNMENT_RIGHT)) { 637d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 638d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 639d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 640d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 641d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DockedWindowLayoutManager::OnShelfBoundsChanged() { 643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Relayout(); 644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); 645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, aura::LayoutManager implementation: 6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnWindowResized() { 6508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MaybeMinimizeChildrenExcept(dragged_window_); 6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // When screen resizes update the insets even when dock width or alignment 6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // does not change. 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); 6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(child)) 659ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Dragged windows are already observed by StartDragging and do not change 6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // docked alignment during the drag. 6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (child == dragged_window_) 6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If this is the first window getting docked - update alignment. 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A window can be added without proper bounds when window is moved to another 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // display via API or due to display configuration change, so the alignment 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is set based on which edge is closer in the new display. 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (alignment_ == DOCKED_ALIGNMENT_NONE) 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment_ = GetEdgeNearestWindow(child); 67068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MaybeMinimizeChildrenExcept(child); 6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) child->AddObserver(this); 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::GetWindowState(child)->AddObserver(this); 6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { 6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(child)) 679ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 6803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Dragged windows are stopped being observed by FinishDragging and do not 6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // change alignment during the drag. They also cannot be set to be the 6823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |last_active_window_|. 6833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (child == dragged_window_) 6843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If this is the last window, set alignment and maximize the workspace. 6863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsAnyWindowDocked()) { 687ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch alignment_ = DOCKED_ALIGNMENT_NONE; 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateDockedWidth(0); 6893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 690bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (last_active_window_ == child) 691bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch last_active_window_ = NULL; 6923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) child->RemoveObserver(this); 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::GetWindowState(child)->RemoveObserver(this); 6947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 6951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 6977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( 6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* child, 7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool visible) { 7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(child)) 702ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (visible) 7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::GetWindowState(child)->Restore(); 7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::SetChildBounds( 7107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* child, 7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& requested_bounds) { 7125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The minimum constraints have to be applied first by the layout manager. 7135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect actual_new_bounds(requested_bounds); 7145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (child->delegate()) { 7155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Size& min_size = child->delegate()->GetMinimumSize(); 7165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actual_new_bounds.set_width( 7175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::max(min_size.width(), actual_new_bounds.width())); 7185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actual_new_bounds.set_height( 7195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::max(min_size.height(), actual_new_bounds.height())); 7205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SnapToPixelLayoutManager::SetChildBounds(child, actual_new_bounds); 722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (IsPopupOrTransient(child)) 723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Whenever one of our windows is moved or resized enforce layout. 725c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ShelfLayoutManager* shelf_layout = 726c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ShelfLayoutManager::ForShelf(dock_container_); 727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (shelf_layout) 728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shelf_layout->UpdateVisibilityState(); 7297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, ash::ShellObserver implementation: 7337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { 7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Relayout(); 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); 7378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MaybeMinimizeChildrenExcept(dragged_window_); 7384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DockedWindowLayoutManager::OnFullscreenStateChanged( 7411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_fullscreen, aura::Window* root_window) { 7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (dock_container_->GetRootWindow() != root_window) 7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Entering fullscreen mode (including immersive) hides docked windows. 7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) in_fullscreen_ = workspace_controller_->GetWindowState() == 7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WORKSPACE_WINDOW_STATE_FULL_SCREEN; 7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // prevent Relayout from getting called multiple times during this 7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Use a copy of children array because a call to MinimizeDockedWindow or 7518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // RestoreDockedWindow can change order. 7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) aura::Window::Windows children(dock_container_->children()); 7538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (aura::Window::Windows::const_iterator iter = children.begin(); 7548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) iter != children.end(); ++iter) { 7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) aura::Window* window(*iter); 7564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(window)) 7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::WindowState* window_state = wm::GetWindowState(window); 7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (in_fullscreen_) { 7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (window->IsVisible()) 7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MinimizeDockedWindow(window_state); 7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!window_state->IsMinimized()) 7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RestoreDockedWindow(window_state); 7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Relayout(); 7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnShelfAlignmentChanged( 7731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) { 7747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (dock_container_->GetRootWindow() != root_window) 7757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 7767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!shelf_ || !shelf_->shelf_widget()) 7787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 7797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (alignment_ == DOCKED_ALIGNMENT_NONE) 7817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 7827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Do not allow shelf and dock on the same side. Switch side that 7847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // the dock is attached to and move all dock windows to that new side. 7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfAlignment shelf_alignment = shelf_->shelf_widget()->GetAlignment(); 7867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (alignment_ == DOCKED_ALIGNMENT_LEFT && 7877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shelf_alignment == SHELF_ALIGNMENT_LEFT) { 788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch alignment_ = DOCKED_ALIGNMENT_RIGHT; 7897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else if (alignment_ == DOCKED_ALIGNMENT_RIGHT && 7907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shelf_alignment == SHELF_ALIGNMENT_RIGHT) { 791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch alignment_ = DOCKED_ALIGNMENT_LEFT; 7927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Relayout(); 7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); 7957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, ShelfLayoutManagerObserver implementation: 799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DockedWindowLayoutManager::OnBackgroundUpdated( 800a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfBackgroundType background_type, 801a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BackgroundAnimatorChangeType change_type) { 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_widget_->SetBackgroundType(background_type, change_type); 803a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 805a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, WindowStateObserver implementation: 8077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DockedWindowLayoutManager::OnPreWindowStateTypeChange( 8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::WindowState* window_state, 810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WindowStateType old_type) { 8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) aura::Window* window = window_state->window(); 8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(window)) 8137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 8147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The window property will still be set, but no actual change will occur 8154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // until OnFullscreenStateChange is called when exiting fullscreen. 8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (in_fullscreen_) 8177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 8184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (window_state->IsMinimized()) { 8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MinimizeDockedWindow(window_state); 820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (window_state->IsMaximizedOrFullscreen() || 821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window_state->IsSnapped()) { 822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (window != dragged_window_) { 823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UndockWindow(window); 824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RecordUmaAction(DOCKED_ACTION_MAXIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN); 825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { 8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RestoreDockedWindow(window_state); 8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 8307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, WindowObserver implementation: 8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 834bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid DockedWindowLayoutManager::OnWindowBoundsChanged( 835bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch aura::Window* window, 836bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const gfx::Rect& old_bounds, 837bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const gfx::Rect& new_bounds) { 8383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Only relayout if the dragged window would get docked. 8393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (window == dragged_window_ && is_dragged_window_docked_) 840bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch Relayout(); 841bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 842bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 84368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DockedWindowLayoutManager::OnWindowVisibilityChanging( 84468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* window, bool visible) { 8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsPopupOrTransient(window)) 8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT; 84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (visible) { 849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; 850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::SetWindowVisibilityAnimationDuration( 85168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window, base::TimeDelta::FromMilliseconds(kFadeDurationMs)); 852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (wm::GetWindowState(window)->IsMinimized()) { 853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_type = WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE; 85468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::SetWindowVisibilityAnimationType(window, animation_type); 85668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 85768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 858bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) { 8593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (dragged_window_ == window) { 860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FinishDragging(DOCKED_ACTION_NONE, DOCKED_ACTION_SOURCE_UNKNOWN); 8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!dragged_window_); 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!is_dragged_window_docked_); 8633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (window == last_active_window_) 8653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_active_window_ = NULL; 866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordUmaAction(DOCKED_ACTION_CLOSE, DOCKED_ACTION_SOURCE_UNKNOWN); 867bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 868bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 869bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 8707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager, aura::client::ActivationChangeObserver 872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// implementation: 8737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 8747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnWindowActivated(aura::Window* gained_active, 8757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* lost_active) { 8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (gained_active && IsPopupOrTransient(gained_active)) 8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Ignore if the window that is not managed by this was activated. 8797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* ancestor = NULL; 8807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (aura::Window* parent = gained_active; 8817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) parent; parent = parent->parent()) { 8827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (parent->parent() == dock_container_) { 8837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ancestor = parent; 8847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 8857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 8867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 8877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (ancestor) 8887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UpdateStacking(ancestor); 8897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 8907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 8917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DockedWindowLayoutManager private implementation: 8937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 89468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( 89568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* child) { 8968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Minimize any windows that don't fit without overlap. 8978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect work_area = 8988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); 8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int available_room = work_area.height(); 9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool gap_needed = !!child; 9018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (child) 9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) available_room -= GetWindowHeightCloseTo(child, 0); 9038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Use a copy of children array because a call to Minimize can change order. 90468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window::Windows children(dock_container_->children()); 90568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); 90668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) while (iter != children.rend()) { 90768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* window(*iter++); 90868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (window == child || !IsUsedByLayout(window)) 90968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) continue; 9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int room_needed = GetWindowHeightCloseTo(window, 0) + 9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (gap_needed ? kMinDockGap : 0); 9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gap_needed = true; 913a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (available_room > room_needed) { 9148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) available_room -= room_needed; 915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 916a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Slow down minimizing animations. Lock duration so that it is not 917a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // overridden by other ScopedLayerAnimationSettings down the stack. 918a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 919a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) settings.SetTransitionDuration( 920a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); 921a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) settings.LockTransitionDuration(); 92268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) wm::GetWindowState(window)->Minimize(); 923a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 92468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 92568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 92668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DockedWindowLayoutManager::MinimizeDockedWindow( 9284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::WindowState* window_state) { 9294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(window_state->window())); 9304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_state->window()->Hide(); 93168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (window_state->IsActive()) 93268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_state->Deactivate(); 933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordUmaAction(DOCKED_ACTION_MINIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN); 9347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 9357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DockedWindowLayoutManager::RestoreDockedWindow( 9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wm::WindowState* window_state) { 9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) aura::Window* window = window_state->window(); 9394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!IsPopupOrTransient(window)); 940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Always place restored window at the bottom shuffling the other windows up. 94168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(varkha): add a separate container for docked windows to keep track 94268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // of ordering. 94368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( 94468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dock_container_); 94568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Rect work_area = display.work_area(); 9468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Evict the window if it can no longer be docked because of its height. 948010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { 9498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UndockWindow(window); 950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordUmaAction(DOCKED_ACTION_EVICT, DOCKED_ACTION_SOURCE_UNKNOWN); 9518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 9528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 95368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds(window->bounds()); 954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds.set_y(work_area.bottom()); 95568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window->SetBounds(bounds); 9567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) window->Show(); 95768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MaybeMinimizeChildrenExcept(window); 958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordUmaAction(DOCKED_ACTION_RESTORE, DOCKED_ACTION_SOURCE_UNKNOWN); 959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DockedWindowLayoutManager::RecordUmaAction(DockedAction action, 962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DockedActionSource source) { 963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action == DOCKED_ACTION_NONE) 964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Action", action, DOCKED_ACTION_COUNT); 966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Ash.Dock.ActionSource", source, 967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DOCKED_ACTION_SOURCE_COUNT); 968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time time_now = base::Time::Now(); 969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta time_between_use = time_now - last_action_time_; 970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", 971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) time_between_use.InSeconds(), 972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1, 973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromHours(10).InSeconds(), 974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100); 975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_action_time_ = time_now; 976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int docked_all_count = 0; 977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int docked_visible_count = 0; 978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int docked_panels_count = 0; 979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int large_windows_count = 0; 980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < dock_container_->children().size(); ++i) { 981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const aura::Window* window(dock_container_->children()[i]); 982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsPopupOrTransient(window)) 983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) docked_all_count++; 985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!IsUsedByLayout(window)) 986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) docked_visible_count++; 9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (window->type() == ui::wm::WINDOW_TYPE_PANEL) 989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) docked_panels_count++; 990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const wm::WindowState* window_state = wm::GetWindowState(window); 991f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state->HasRestoreBounds()) { 992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); 993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (restore_bounds.width() > kMaxDockWidth) 994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) large_windows_count++; 995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsAll", docked_all_count); 998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsLarge", large_windows_count); 999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsPanels", docked_panels_count); 1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsVisible", docked_visible_count); 1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DockedWindowLayoutManager::UpdateDockedWidth(int width) { 1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (docked_width_ == width) 1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) docked_width_ = width; 1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); 10087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 10097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 10108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DockedWindowLayoutManager::OnDraggedWindowDocked(aura::Window* window) { 10113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!is_dragged_window_docked_); 10123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_window_docked_ = true; 10133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DockedWindowLayoutManager::OnDraggedWindowUndocked() { 10163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK (is_dragged_window_docked_); 10173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) is_dragged_window_docked_ = false; 10183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool DockedWindowLayoutManager::IsAnyWindowDocked() { 10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; 1022ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1023ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 10245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( 10255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const aura::Window* window) const { 10265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& bounds(window->GetBoundsInScreen()); 10275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); 10285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (abs(bounds.x() - container_bounds.x()) < 10295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) abs(bounds.right() - container_bounds.right())) ? 10305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DOCKED_ALIGNMENT_LEFT : DOCKED_ALIGNMENT_RIGHT; 10315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 10325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::Relayout() { 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (in_layout_) 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) 10377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 10387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 10397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 10403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); 10417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* active_window = NULL; 10428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::vector<WindowWithHeight> visible_windows; 10437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (size_t i = 0; i < dock_container_->children().size(); ++i) { 10447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::Window* window(dock_container_->children()[i]); 10457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 10463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsUsedByLayout(window) || window == dragged_window_) 10477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) continue; 10487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 10497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If the shelf is currently hidden (full-screen mode), hide window until 10507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // full-screen mode is exited. 10514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (in_fullscreen_) { 10527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The call to Hide does not set the minimize property, so the window will 10537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // be restored when the shelf becomes visible again. 10547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) window->Hide(); 10557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) continue; 10567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 10577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (window->HasFocus() || 10587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) window->Contains( 10597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) aura::client::GetFocusClient(window)->GetFocusedWindow())) { 10607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!active_window); 10617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) active_window = window; 10627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 10638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) visible_windows.push_back(WindowWithHeight(window)); 1064bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Consider docked dragged_window_ when fanning out other child windows. 10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (is_dragged_window_docked_) { 10678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) visible_windows.push_back(WindowWithHeight(dragged_window_)); 10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!active_window); 10693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) active_window = dragged_window_; 10703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1071bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 10728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Position docked windows as well as the window being dragged. 1073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect work_area = 10748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); 1075a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (shelf_observer_) 1076a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) work_area.Subtract(shelf_observer_->shelf_bounds_in_screen()); 10778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int available_room = CalculateWindowHeightsAndRemainingRoom(work_area, 10788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &visible_windows); 10798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FanOutChildren(work_area, 10808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CalculateIdealWidth(visible_windows), 10818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) available_room, 10828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &visible_windows); 10838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // After the first Relayout allow the windows to change their order easier 10858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // since we know they are docked. 10868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) is_dragged_from_dock_ = true; 10878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateStacking(active_window); 10888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 10898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( 10918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect work_area, 10928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::vector<WindowWithHeight>* visible_windows) { 10935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int available_room = work_area.height(); 10948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int remaining_windows = visible_windows->size(); 10955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int gap_height = remaining_windows > 1 ? kMinDockGap : 0; 10968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Sort windows by their minimum heights and calculate target heights. 10988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::sort(visible_windows->begin(), visible_windows->end(), 10998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CompareMinimumHeight()); 11008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Distribute the free space among the docked windows. Since the windows are 11018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // sorted (tall windows first) we can now assume that any window which 11028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // required more space than the current window will have already been 11038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // accounted for previously in this loop, so we can safely give that window 11048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // its proportional share of the remaining space. 11058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (std::vector<WindowWithHeight>::reverse_iterator iter = 11068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) visible_windows->rbegin(); 11078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) iter != visible_windows->rend(); ++iter) { 11088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) iter->height_ = GetWindowHeightCloseTo( 11095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->window(), 11105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (available_room + gap_height) / remaining_windows - gap_height); 11115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) available_room -= (iter->height_ + gap_height); 11128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) remaining_windows--; 11138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 11145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return available_room + gap_height; 11158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 11168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 11178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int DockedWindowLayoutManager::CalculateIdealWidth( 11188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::vector<WindowWithHeight>& visible_windows) { 1119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int smallest_max_width = kMaxDockWidth; 1120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int largest_min_width = kMinDockWidth; 1121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ideal width of the docked area is as close to kIdealWidth as possible 1122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // while still respecting the minimum and maximum width restrictions on the 1123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // individual docked windows as well as the width that was possibly set by a 1124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // user (which needs to be preserved when dragging and rearranging windows). 11258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (std::vector<WindowWithHeight>::const_iterator iter = 11268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) visible_windows.begin(); 11278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) iter != visible_windows.end(); ++iter) { 11288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const aura::Window* window = iter->window(); 1129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int min_window_width = window->bounds().width(); 1130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int max_window_width = min_window_width; 1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!wm::GetWindowState(window)->bounds_changed_by_user()) { 1132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); 1133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); 113468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) largest_min_width = std::max(largest_min_width, min_window_width); 1136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) smallest_max_width = std::min(smallest_max_width, max_window_width); 1137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int ideal_width = std::max(largest_min_width, 1139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::min(smallest_max_width, kIdealWidth)); 1140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Restrict docked area width regardless of window restrictions. 1141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ideal_width = std::max(std::min(ideal_width, kMaxDockWidth), kMinDockWidth); 1142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ideal_width; 11438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 11448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 11458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DockedWindowLayoutManager::FanOutChildren( 11468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect& work_area, 11478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int ideal_docked_width, 11488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int available_room, 11498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::vector<WindowWithHeight>* visible_windows) { 11508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); 11518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 11528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Calculate initial vertical offset and the gap or overlap between windows. 11538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const int num_windows = visible_windows->size(); 11545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const float delta = static_cast<float>(available_room) / 1155bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ((available_room > 0 || num_windows <= 1) ? 1156bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch num_windows + 1 : num_windows - 1); 11575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float y_pos = work_area.y() + ((delta > 0) ? delta : 0); 1158bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 115968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Docked area is shown only if there is at least one non-dragged visible 116068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // docked window. 1161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int new_width = ideal_docked_width; 11628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (visible_windows->empty() || 11638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) (visible_windows->size() == 1 && 11648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) (*visible_windows)[0].window() == dragged_window_)) { 1165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_width = 0; 116668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateDockedWidth(new_width); 11683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Sort windows by their center positions and fan out overlapping 11693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // windows. 11708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::sort(visible_windows->begin(), visible_windows->end(), 11713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : NULL, 1172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dock_container_, 1173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delta)); 11748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); 1175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) iter != visible_windows->end(); ++iter) { 11768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) aura::Window* window = iter->window(); 11775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect bounds = ScreenUtil::ConvertRectToScreen( 1178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dock_container_, window->GetTargetBounds()); 1179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // A window is extended or shrunk to be as close as possible to the ideal 1180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // docked area width. Windows that were resized by a user are kept at their 1181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // existing size. 118268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This also enforces the min / max restrictions on the docked area width. 118368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds.set_width(GetWindowWidthCloseTo( 118468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window, 1185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) wm::GetWindowState(window)->bounds_changed_by_user() ? 1186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bounds.width() : ideal_docked_width)); 118768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_LE(bounds.width(), ideal_docked_width); 1188bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DockedAlignment alignment = alignment_; 11905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_) 11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) alignment = GetEdgeNearestWindow(window); 1192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1193bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Fan out windows evenly distributing the overlap or remaining free space. 11948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bounds.set_height(iter->height_); 1195bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bounds.set_y(std::max(work_area.y(), 1196bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::min(work_area.bottom() - bounds.height(), 1197bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch static_cast<int>(y_pos + 0.5)))); 11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) y_pos += bounds.height() + delta + kMinDockGap; 1199bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1200bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // All docked windows other than the one currently dragged remain stuck 120168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // to the screen edge (flush with the edge or centered in the dock area). 1202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch (alignment) { 1203bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case DOCKED_ALIGNMENT_LEFT: 120468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds.set_x(dock_bounds.x() + 120568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (ideal_docked_width - bounds.width()) / 2); 1206bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 1207bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case DOCKED_ALIGNMENT_RIGHT: 120868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds.set_x(dock_bounds.right() - 120968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (ideal_docked_width + bounds.width()) / 2); 1210bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 1211bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case DOCKED_ALIGNMENT_NONE: 1212bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 12137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (window == dragged_window_) { 12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dragged_bounds_ = bounds; 12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 12173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If the following asserts it is probably because not all the children 1219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // have been removed when dock was closed. 12203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_NE(alignment_, DOCKED_ALIGNMENT_NONE); 12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds = ScreenUtil::ConvertRectFromScreen(dock_container_, bounds); 122268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (bounds != window->GetTargetBounds()) { 122368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::Layer* layer = window->layer(); 122468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); 122568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) slide_settings.SetPreemptionStrategy( 122668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 122768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) slide_settings.SetTransitionDuration( 122868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kSlideDurationMs)); 122968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SetChildBoundsDirect(window, bounds); 123068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 12327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 12337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 12344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DockedWindowLayoutManager::UpdateDockBounds( 12354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DockedWindowLayoutManagerObserver::Reason reason) { 1236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0); 12374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Rect work_area = 12384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); 1239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect bounds = gfx::Rect( 12403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0 ? 1241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dock_container_->bounds().right() - dock_inset: 1242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dock_container_->bounds().x(), 1243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dock_container_->bounds().y(), 1244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dock_inset, 12454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) work_area.height()); 1246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch docked_bounds_ = bounds + 1247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dock_container_->GetBoundsInScreen().OffsetFromOrigin(); 1248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FOR_EACH_OBSERVER( 1249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DockedWindowLayoutManagerObserver, 1250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch observer_list_, 12514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnDockBoundsChanging(bounds, reason)); 1252bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Show or hide background for docked area. 1253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect background_bounds(docked_bounds_); 1254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (shelf_observer_) 1255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) background_bounds.Subtract(shelf_observer_->shelf_bounds_in_screen()); 1256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) background_widget_->SetBackgroundBounds(background_bounds, alignment_); 1257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (docked_width_ > 0) 1258bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch background_widget_->Show(); 1259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else 1260bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch background_widget_->Hide(); 1261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 12637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::UpdateStacking(aura::Window* active_window) { 1264bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!active_window) { 1265bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!last_active_window_) 1266bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 1267bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch active_window = last_active_window_; 1268bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1269bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 12703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Windows are stacked like a deck of cards: 1271bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // ,------. 1272bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // |,------.| 1273bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // |,------.| 1274bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // | active | 1275bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // | window | 1276bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // |`------'| 1277bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // |`------'| 1278bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // `------' 12793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Use the middle of each window to figure out how to stack the window. 1280bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // This allows us to update the stacking when a window is being dragged around 1281bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // by the titlebar. 1282bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::map<int, aura::Window*> window_ordering; 1283bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (aura::Window::Windows::const_iterator it = 1284bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch dock_container_->children().begin(); 1285bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch it != dock_container_->children().end(); ++it) { 12863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsUsedByLayout(*it) || 12873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ((*it) == dragged_window_ && !is_dragged_window_docked_)) { 1288bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch continue; 12893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1290bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch gfx::Rect bounds = (*it)->bounds(); 1291bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch window_ordering.insert(std::make_pair(bounds.y() + bounds.height() / 2, 1292bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch *it)); 1293bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1294bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int active_center_y = active_window->bounds().CenterPoint().y(); 1295bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 12963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::Window* previous_window = NULL; 1297bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (std::map<int, aura::Window*>::const_iterator it = 1298bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch window_ordering.begin(); 1299bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch it != window_ordering.end() && it->first < active_center_y; ++it) { 1300bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (previous_window) 1301bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch dock_container_->StackChildAbove(it->second, previous_window); 1302bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch previous_window = it->second; 1303bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1304bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (std::map<int, aura::Window*>::const_reverse_iterator it = 1305bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch window_ordering.rbegin(); 1306bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch it != window_ordering.rend() && it->first > active_center_y; ++it) { 1307bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (previous_window) 1308bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch dock_container_->StackChildAbove(it->second, previous_window); 1309bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch previous_window = it->second; 1310bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1311bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 13123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (previous_window && active_window->parent() == dock_container_) 13133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dock_container_->StackChildAbove(active_window, previous_window); 13143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (active_window != dragged_window_) 13153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_active_window_ = active_window; 13167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 13177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 13187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 13197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// keyboard::KeyboardControllerObserver implementation: 13207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 13217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DockedWindowLayoutManager::OnKeyboardBoundsChanging( 13227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& keyboard_bounds) { 13237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // This bounds change will have caused a change to the Shelf which does not 13247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // propagate automatically to this class, so manually recalculate bounds. 13254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Relayout(); 13264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); 13277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 13287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 13297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace ash 1330