| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/drag_window_controller.h" | 5 #include "ash/wm/drag_window_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/display/window_tree_host_manager.h" | 9 #include "ash/display/window_tree_host_manager.h" |
| 10 #include "ash/screen_util.h" | 10 #include "ash/screen_util.h" |
| 11 #include "ash/shell.h" | 11 #include "ash/shell.h" |
| 12 #include "ash/shell_window_ids.h" | 12 #include "ash/shell_window_ids.h" |
| 13 #include "ash/wm/window_util.h" | 13 #include "ash/wm/window_util.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "ui/aura/client/aura_constants.h" | 15 #include "ui/aura/client/aura_constants.h" |
| 16 #include "ui/aura/client/screen_position_client.h" | 16 #include "ui/aura/client/screen_position_client.h" |
| 17 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 18 #include "ui/aura/window_delegate.h" | 18 #include "ui/aura/window_delegate.h" |
| 19 #include "ui/aura/window_event_dispatcher.h" | 19 #include "ui/aura/window_event_dispatcher.h" |
| 20 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
| 21 #include "ui/compositor/layer.h" | 21 #include "ui/compositor/layer.h" |
| 22 #include "ui/compositor/layer_tree_owner.h" | 22 #include "ui/compositor/layer_tree_owner.h" |
| 23 #include "ui/compositor/paint_context.h" |
| 23 #include "ui/compositor/scoped_layer_animation_settings.h" | 24 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 24 #include "ui/views/view.h" | 25 #include "ui/views/view.h" |
| 25 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
| 26 #include "ui/wm/core/shadow_types.h" | 27 #include "ui/wm/core/shadow_types.h" |
| 27 #include "ui/wm/core/window_util.h" | 28 #include "ui/wm/core/window_util.h" |
| 28 | 29 |
| 29 namespace ash { | 30 namespace ash { |
| 31 namespace { |
| 32 |
| 33 // A layer delegate to paint the content of the recreaetd layers |
| 34 // by delegating the paint request to the original delegate. |
| 35 // It checks if the orignal delegate is still valid by traversing |
| 36 // the original layers. |
| 37 class DragWindowLayerDelegate : public ui::LayerDelegate { |
| 38 public: |
| 39 DragWindowLayerDelegate(aura::Window* original_window, |
| 40 ui::LayerDelegate* delegate) |
| 41 : original_window_(original_window), original_delegate_(delegate) {} |
| 42 ~DragWindowLayerDelegate() override {} |
| 43 |
| 44 private: |
| 45 // ui:LayerDelegate: |
| 46 void OnPaintLayer(const ui::PaintContext& context) override { |
| 47 if (!original_delegate_) |
| 48 return; |
| 49 // |original_delegate_| may have already been deleted or |
| 50 // disconnected by this time. Check if |original_delegate_| is still |
| 51 // used by the original_window tree, or skip otherwise. |
| 52 if (IsDelegateValid(original_window_->layer())) |
| 53 original_delegate_->OnPaintLayer(context); |
| 54 else |
| 55 original_delegate_ = nullptr; |
| 56 } |
| 57 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
| 58 void OnDeviceScaleFactorChanged(float device_scale_factor) override { |
| 59 // Don't tell the original delegate about device scale factor change |
| 60 // on cloned layer because the original layer is still on the same display. |
| 61 } |
| 62 base::Closure PrepareForLayerBoundsChange() override { |
| 63 return base::Closure(); |
| 64 } |
| 65 |
| 66 bool IsDelegateValid(ui::Layer* layer) { |
| 67 if (layer->delegate() == original_delegate_) |
| 68 return true; |
| 69 for (auto* child : layer->children()) { |
| 70 if (IsDelegateValid(child)) |
| 71 return true; |
| 72 } |
| 73 return false; |
| 74 } |
| 75 |
| 76 aura::Window* original_window_; |
| 77 ui::LayerDelegate* original_delegate_; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(DragWindowLayerDelegate); |
| 80 }; |
| 81 |
| 82 } // namespace |
| 30 | 83 |
| 31 // This keeps tack of the drag window's state. It creates/destory/updates bounds | 84 // This keeps tack of the drag window's state. It creates/destory/updates bounds |
| 32 // and opacity based on the current bounds. | 85 // and opacity based on the current bounds. |
| 33 class DragWindowController::DragWindowDetails : public aura::WindowDelegate { | 86 class DragWindowController::DragWindowDetails |
| 87 : public aura::WindowDelegate, |
| 88 public ::wm::LayerDelegateFactory { |
| 34 public: | 89 public: |
| 35 DragWindowDetails(const display::Display& display, | 90 DragWindowDetails(const display::Display& display, |
| 36 aura::Window* original_window) | 91 aura::Window* original_window) |
| 37 : root_window_(Shell::GetInstance() | 92 : root_window_(Shell::GetInstance() |
| 38 ->window_tree_host_manager() | 93 ->window_tree_host_manager() |
| 39 ->GetRootWindowForDisplayId(display.id())) {} | 94 ->GetRootWindowForDisplayId(display.id())) {} |
| 40 | 95 |
| 41 ~DragWindowDetails() override { | 96 ~DragWindowDetails() override { |
| 42 delete drag_window_; | 97 delete drag_window_; |
| 43 DCHECK(!drag_window_); | 98 DCHECK(!drag_window_); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 71 GetDragWindowOpacity(bounds_in_screen, visible_bounds)); | 126 GetDragWindowOpacity(bounds_in_screen, visible_bounds)); |
| 72 } | 127 } |
| 73 } | 128 } |
| 74 | 129 |
| 75 private: | 130 private: |
| 76 friend class DragWindowController; | 131 friend class DragWindowController; |
| 77 | 132 |
| 78 void CreateDragWindow(aura::Window* original_window, | 133 void CreateDragWindow(aura::Window* original_window, |
| 79 const gfx::Rect& bounds_in_screen) { | 134 const gfx::Rect& bounds_in_screen) { |
| 80 DCHECK(!drag_window_); | 135 DCHECK(!drag_window_); |
| 136 original_window_ = original_window; |
| 81 drag_window_ = new aura::Window(this); | 137 drag_window_ = new aura::Window(this); |
| 82 int parent_id = original_window->parent()->id(); | 138 int parent_id = original_window->parent()->id(); |
| 83 aura::Window* container = root_window_->GetChildById(parent_id); | 139 aura::Window* container = root_window_->GetChildById(parent_id); |
| 84 | 140 |
| 85 drag_window_->SetType(ui::wm::WINDOW_TYPE_POPUP); | 141 drag_window_->SetType(ui::wm::WINDOW_TYPE_POPUP); |
| 86 drag_window_->SetTransparent(true); | 142 drag_window_->SetTransparent(true); |
| 87 drag_window_->Init(ui::LAYER_TEXTURED); | 143 drag_window_->Init(ui::LAYER_TEXTURED); |
| 88 drag_window_->SetName("DragWindow"); | 144 drag_window_->SetName("DragWindow"); |
| 89 drag_window_->set_id(kShellWindowId_PhantomWindow); | 145 drag_window_->set_id(kShellWindowId_PhantomWindow); |
| 90 drag_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); | 146 drag_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 102 | 158 |
| 103 // Fade the window in. | 159 // Fade the window in. |
| 104 ui::Layer* drag_layer = drag_window_->layer(); | 160 ui::Layer* drag_layer = drag_window_->layer(); |
| 105 drag_layer->SetOpacity(0); | 161 drag_layer->SetOpacity(0); |
| 106 ui::ScopedLayerAnimationSettings scoped_setter(drag_layer->GetAnimator()); | 162 ui::ScopedLayerAnimationSettings scoped_setter(drag_layer->GetAnimator()); |
| 107 drag_layer->SetOpacity(1); | 163 drag_layer->SetOpacity(1); |
| 108 } | 164 } |
| 109 | 165 |
| 110 void RecreateWindowLayers(aura::Window* original_window) { | 166 void RecreateWindowLayers(aura::Window* original_window) { |
| 111 DCHECK(!layer_owner_.get()); | 167 DCHECK(!layer_owner_.get()); |
| 112 layer_owner_ = ::wm::RecreateLayers(original_window); | 168 layer_owner_ = ::wm::RecreateLayers(original_window, this); |
| 113 // TODO(oshima): Recreated child layers may not have been painted | |
| 114 // yet, and may not be able to paint to because it does not have | |
| 115 // its original delegate. | |
| 116 layer_owner_->root()->set_delegate(original_window->layer()->delegate()); | |
| 117 // Place the layer at (0, 0) of the DragWindowController's window. | 169 // Place the layer at (0, 0) of the DragWindowController's window. |
| 118 gfx::Rect layer_bounds = layer_owner_->root()->bounds(); | 170 gfx::Rect layer_bounds = layer_owner_->root()->bounds(); |
| 119 layer_bounds.set_origin(gfx::Point(0, 0)); | 171 layer_bounds.set_origin(gfx::Point(0, 0)); |
| 120 layer_owner_->root()->SetBounds(layer_bounds); | 172 layer_owner_->root()->SetBounds(layer_bounds); |
| 121 layer_owner_->root()->SetVisible(false); | 173 layer_owner_->root()->SetVisible(false); |
| 122 // Detach it from the current container. | 174 // Detach it from the current container. |
| 123 layer_owner_->root()->parent()->Remove(layer_owner_->root()); | 175 layer_owner_->root()->parent()->Remove(layer_owner_->root()); |
| 124 } | 176 } |
| 125 | 177 |
| 126 void SetOpacity(const aura::Window* original_window, float opacity) { | 178 void SetOpacity(const aura::Window* original_window, float opacity) { |
| 127 ui::Layer* layer = drag_window_->layer(); | 179 ui::Layer* layer = drag_window_->layer(); |
| 128 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | 180 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
| 129 layer->SetOpacity(opacity); | 181 layer->SetOpacity(opacity); |
| 130 layer_owner_->root()->SetOpacity(1.0f); | 182 layer_owner_->root()->SetOpacity(1.0f); |
| 131 } | 183 } |
| 132 | 184 |
| 133 // aura::WindowDelegate: | 185 // aura::WindowDelegate: |
| 186 ui::LayerDelegate* CreateDelegate(ui::LayerDelegate* delegate) override { |
| 187 if (!delegate) |
| 188 return nullptr; |
| 189 DragWindowLayerDelegate* new_delegate = |
| 190 new DragWindowLayerDelegate(original_window_, delegate); |
| 191 delegates_.push_back(base::WrapUnique(new_delegate)); |
| 192 return new_delegate; |
| 193 } |
| 194 |
| 195 // aura::WindowDelegate: |
| 134 gfx::Size GetMinimumSize() const override { return gfx::Size(); } | 196 gfx::Size GetMinimumSize() const override { return gfx::Size(); } |
| 135 gfx::Size GetMaximumSize() const override { return gfx::Size(); } | 197 gfx::Size GetMaximumSize() const override { return gfx::Size(); } |
| 136 void OnBoundsChanged(const gfx::Rect& old_bounds, | 198 void OnBoundsChanged(const gfx::Rect& old_bounds, |
| 137 const gfx::Rect& new_bounds) override {} | 199 const gfx::Rect& new_bounds) override {} |
| 138 gfx::NativeCursor GetCursor(const gfx::Point& point) override { | 200 gfx::NativeCursor GetCursor(const gfx::Point& point) override { |
| 139 return gfx::kNullCursor; | 201 return gfx::kNullCursor; |
| 140 } | 202 } |
| 141 int GetNonClientComponent(const gfx::Point& point) const override { | 203 int GetNonClientComponent(const gfx::Point& point) const override { |
| 142 return HTNOWHERE; | 204 return HTNOWHERE; |
| 143 } | 205 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 156 void GetHitTestMask(gfx::Path* mask) const override {} | 218 void GetHitTestMask(gfx::Path* mask) const override {} |
| 157 void OnWindowDestroying(aura::Window* window) override { | 219 void OnWindowDestroying(aura::Window* window) override { |
| 158 DCHECK_EQ(drag_window_, window); | 220 DCHECK_EQ(drag_window_, window); |
| 159 drag_window_ = nullptr; | 221 drag_window_ = nullptr; |
| 160 } | 222 } |
| 161 | 223 |
| 162 aura::Window* root_window_; | 224 aura::Window* root_window_; |
| 163 | 225 |
| 164 aura::Window* drag_window_ = nullptr; // Owned by the container. | 226 aura::Window* drag_window_ = nullptr; // Owned by the container. |
| 165 | 227 |
| 228 aura::Window* original_window_ = nullptr; |
| 229 |
| 230 std::vector<std::unique_ptr<DragWindowLayerDelegate>> delegates_; |
| 231 |
| 166 // The copy of window_->layer() and its descendants. | 232 // The copy of window_->layer() and its descendants. |
| 167 std::unique_ptr<ui::LayerTreeOwner> layer_owner_; | 233 std::unique_ptr<ui::LayerTreeOwner> layer_owner_; |
| 168 | 234 |
| 169 DISALLOW_COPY_AND_ASSIGN(DragWindowDetails); | 235 DISALLOW_COPY_AND_ASSIGN(DragWindowDetails); |
| 170 }; | 236 }; |
| 171 | 237 |
| 172 // static | 238 // static |
| 173 float DragWindowController::GetDragWindowOpacity( | 239 float DragWindowController::GetDragWindowOpacity( |
| 174 const gfx::Rect& window_bounds, | 240 const gfx::Rect& window_bounds, |
| 175 const gfx::Rect& visible_bounds) { | 241 const gfx::Rect& visible_bounds) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 for (const std::unique_ptr<DragWindowDetails>& details : drag_windows_) { | 294 for (const std::unique_ptr<DragWindowDetails>& details : drag_windows_) { |
| 229 if (details->layer_owner_) { | 295 if (details->layer_owner_) { |
| 230 if (index == 0) | 296 if (index == 0) |
| 231 return details->layer_owner_.get(); | 297 return details->layer_owner_.get(); |
| 232 index--; | 298 index--; |
| 233 } | 299 } |
| 234 } | 300 } |
| 235 return nullptr; | 301 return nullptr; |
| 236 } | 302 } |
| 237 | 303 |
| 304 void DragWindowController::RequestLayerPaintForTest() { |
| 305 ui::PaintContext context(nullptr, 1.0f, gfx::Rect()); |
| 306 for (auto& details : drag_windows_) { |
| 307 std::vector<ui::Layer*> layers; |
| 308 layers.push_back(details->drag_window_->layer()); |
| 309 while (layers.size()) { |
| 310 ui::Layer* layer = layers.back(); |
| 311 layers.pop_back(); |
| 312 if (layer->delegate()) |
| 313 layer->delegate()->OnPaintLayer(context); |
| 314 for (auto* child : layer->children()) |
| 315 layers.push_back(child); |
| 316 } |
| 317 } |
| 318 } |
| 319 |
| 238 } // namespace ash | 320 } // namespace ash |
| OLD | NEW |