Chromium Code Reviews| 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* drag_window, | |
| 40 ui::LayerDelegate* delegate) | |
| 41 : drag_window_(drag_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 if (IsDelegateValid(drag_window_->layer())) | |
|
sky
2016/05/20 00:05:24
This is subtle and worth a comment.
oshima
2016/05/20 03:16:08
Done.
| |
| 50 original_delegate_->OnPaintLayer(context); | |
| 51 else | |
| 52 original_delegate_ = nullptr; | |
| 53 } | |
| 54 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | |
| 55 void OnDeviceScaleFactorChanged(float device_scale_factor) override { | |
| 56 // Don't tell the original delegate about device scale factor change | |
| 57 // on cloned layer because the original layer is still on the same display. | |
| 58 } | |
| 59 base::Closure PrepareForLayerBoundsChange() override { | |
| 60 return base::Closure(); | |
| 61 } | |
| 62 | |
| 63 bool IsDelegateValid(ui::Layer* layer) { | |
| 64 if (layer->delegate() == original_delegate_) | |
| 65 return true; | |
| 66 for (auto* child : layer->children()) { | |
| 67 if (IsDelegateValid(child)) | |
| 68 return true; | |
| 69 } | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 73 aura::Window* drag_window_; | |
| 74 ui::LayerDelegate* original_delegate_; | |
| 75 | |
| 76 DISALLOW_COPY_AND_ASSIGN(DragWindowLayerDelegate); | |
| 77 }; | |
| 78 | |
| 79 } // namespace | |
| 30 | 80 |
| 31 // This keeps tack of the drag window's state. It creates/destory/updates bounds | 81 // This keeps tack of the drag window's state. It creates/destory/updates bounds |
| 32 // and opacity based on the current bounds. | 82 // and opacity based on the current bounds. |
| 33 class DragWindowController::DragWindowDetails : public aura::WindowDelegate { | 83 class DragWindowController::DragWindowDetails |
| 84 : public aura::WindowDelegate, | |
| 85 public ::wm::LayerDelegateFactory { | |
| 34 public: | 86 public: |
| 35 DragWindowDetails(const display::Display& display, | 87 DragWindowDetails(const display::Display& display, |
| 36 aura::Window* original_window) | 88 aura::Window* original_window) |
| 37 : root_window_(Shell::GetInstance() | 89 : root_window_(Shell::GetInstance() |
| 38 ->window_tree_host_manager() | 90 ->window_tree_host_manager() |
| 39 ->GetRootWindowForDisplayId(display.id())) {} | 91 ->GetRootWindowForDisplayId(display.id())) {} |
| 40 | 92 |
| 41 ~DragWindowDetails() override { | 93 ~DragWindowDetails() override { |
| 42 delete drag_window_; | 94 delete drag_window_; |
| 43 DCHECK(!drag_window_); | 95 DCHECK(!drag_window_); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 71 GetDragWindowOpacity(bounds_in_screen, visible_bounds)); | 123 GetDragWindowOpacity(bounds_in_screen, visible_bounds)); |
| 72 } | 124 } |
| 73 } | 125 } |
| 74 | 126 |
| 75 private: | 127 private: |
| 76 friend class DragWindowController; | 128 friend class DragWindowController; |
| 77 | 129 |
| 78 void CreateDragWindow(aura::Window* original_window, | 130 void CreateDragWindow(aura::Window* original_window, |
| 79 const gfx::Rect& bounds_in_screen) { | 131 const gfx::Rect& bounds_in_screen) { |
| 80 DCHECK(!drag_window_); | 132 DCHECK(!drag_window_); |
| 133 original_window_ = original_window; | |
| 81 drag_window_ = new aura::Window(this); | 134 drag_window_ = new aura::Window(this); |
| 82 int parent_id = original_window->parent()->id(); | 135 int parent_id = original_window->parent()->id(); |
| 83 aura::Window* container = root_window_->GetChildById(parent_id); | 136 aura::Window* container = root_window_->GetChildById(parent_id); |
| 84 | 137 |
| 85 drag_window_->SetType(ui::wm::WINDOW_TYPE_POPUP); | 138 drag_window_->SetType(ui::wm::WINDOW_TYPE_POPUP); |
| 86 drag_window_->SetTransparent(true); | 139 drag_window_->SetTransparent(true); |
| 87 drag_window_->Init(ui::LAYER_TEXTURED); | 140 drag_window_->Init(ui::LAYER_TEXTURED); |
| 88 drag_window_->SetName("DragWindow"); | 141 drag_window_->SetName("DragWindow"); |
| 89 drag_window_->set_id(kShellWindowId_PhantomWindow); | 142 drag_window_->set_id(kShellWindowId_PhantomWindow); |
| 90 drag_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); | 143 drag_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 102 | 155 |
| 103 // Fade the window in. | 156 // Fade the window in. |
| 104 ui::Layer* drag_layer = drag_window_->layer(); | 157 ui::Layer* drag_layer = drag_window_->layer(); |
| 105 drag_layer->SetOpacity(0); | 158 drag_layer->SetOpacity(0); |
| 106 ui::ScopedLayerAnimationSettings scoped_setter(drag_layer->GetAnimator()); | 159 ui::ScopedLayerAnimationSettings scoped_setter(drag_layer->GetAnimator()); |
| 107 drag_layer->SetOpacity(1); | 160 drag_layer->SetOpacity(1); |
| 108 } | 161 } |
| 109 | 162 |
| 110 void RecreateWindowLayers(aura::Window* original_window) { | 163 void RecreateWindowLayers(aura::Window* original_window) { |
| 111 DCHECK(!layer_owner_.get()); | 164 DCHECK(!layer_owner_.get()); |
| 112 layer_owner_ = ::wm::RecreateLayers(original_window); | 165 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. | 166 // Place the layer at (0, 0) of the DragWindowController's window. |
| 118 gfx::Rect layer_bounds = layer_owner_->root()->bounds(); | 167 gfx::Rect layer_bounds = layer_owner_->root()->bounds(); |
| 119 layer_bounds.set_origin(gfx::Point(0, 0)); | 168 layer_bounds.set_origin(gfx::Point(0, 0)); |
| 120 layer_owner_->root()->SetBounds(layer_bounds); | 169 layer_owner_->root()->SetBounds(layer_bounds); |
| 121 layer_owner_->root()->SetVisible(false); | 170 layer_owner_->root()->SetVisible(false); |
| 122 // Detach it from the current container. | 171 // Detach it from the current container. |
| 123 layer_owner_->root()->parent()->Remove(layer_owner_->root()); | 172 layer_owner_->root()->parent()->Remove(layer_owner_->root()); |
| 124 } | 173 } |
| 125 | 174 |
| 126 void SetOpacity(const aura::Window* original_window, float opacity) { | 175 void SetOpacity(const aura::Window* original_window, float opacity) { |
| 127 ui::Layer* layer = drag_window_->layer(); | 176 ui::Layer* layer = drag_window_->layer(); |
| 128 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | 177 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
| 129 layer->SetOpacity(opacity); | 178 layer->SetOpacity(opacity); |
| 130 layer_owner_->root()->SetOpacity(1.0f); | 179 layer_owner_->root()->SetOpacity(1.0f); |
| 131 } | 180 } |
| 132 | 181 |
| 133 // aura::WindowDelegate: | 182 // aura::WindowDelegate: |
| 183 ui::LayerDelegate* CreateDelegate(ui::LayerDelegate* delegate) override { | |
| 184 if (!delegate) | |
| 185 return nullptr; | |
| 186 DragWindowLayerDelegate* new_delegate = | |
| 187 new DragWindowLayerDelegate(original_window_, delegate); | |
| 188 delegates_.push_back(base::WrapUnique(new_delegate)); | |
| 189 return new_delegate; | |
| 190 } | |
| 191 | |
| 192 // aura::WindowDelegate: | |
| 134 gfx::Size GetMinimumSize() const override { return gfx::Size(); } | 193 gfx::Size GetMinimumSize() const override { return gfx::Size(); } |
| 135 gfx::Size GetMaximumSize() const override { return gfx::Size(); } | 194 gfx::Size GetMaximumSize() const override { return gfx::Size(); } |
| 136 void OnBoundsChanged(const gfx::Rect& old_bounds, | 195 void OnBoundsChanged(const gfx::Rect& old_bounds, |
| 137 const gfx::Rect& new_bounds) override {} | 196 const gfx::Rect& new_bounds) override {} |
| 138 gfx::NativeCursor GetCursor(const gfx::Point& point) override { | 197 gfx::NativeCursor GetCursor(const gfx::Point& point) override { |
| 139 return gfx::kNullCursor; | 198 return gfx::kNullCursor; |
| 140 } | 199 } |
| 141 int GetNonClientComponent(const gfx::Point& point) const override { | 200 int GetNonClientComponent(const gfx::Point& point) const override { |
| 142 return HTNOWHERE; | 201 return HTNOWHERE; |
| 143 } | 202 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 156 void GetHitTestMask(gfx::Path* mask) const override {} | 215 void GetHitTestMask(gfx::Path* mask) const override {} |
| 157 void OnWindowDestroying(aura::Window* window) override { | 216 void OnWindowDestroying(aura::Window* window) override { |
| 158 DCHECK_EQ(drag_window_, window); | 217 DCHECK_EQ(drag_window_, window); |
| 159 drag_window_ = nullptr; | 218 drag_window_ = nullptr; |
| 160 } | 219 } |
| 161 | 220 |
| 162 aura::Window* root_window_; | 221 aura::Window* root_window_; |
| 163 | 222 |
| 164 aura::Window* drag_window_ = nullptr; // Owned by the container. | 223 aura::Window* drag_window_ = nullptr; // Owned by the container. |
| 165 | 224 |
| 225 aura::Window* original_window_ = nullptr; | |
| 226 | |
| 227 std::vector<std::unique_ptr<DragWindowLayerDelegate>> delegates_; | |
| 228 | |
| 166 // The copy of window_->layer() and its descendants. | 229 // The copy of window_->layer() and its descendants. |
| 167 std::unique_ptr<ui::LayerTreeOwner> layer_owner_; | 230 std::unique_ptr<ui::LayerTreeOwner> layer_owner_; |
| 168 | 231 |
| 169 DISALLOW_COPY_AND_ASSIGN(DragWindowDetails); | 232 DISALLOW_COPY_AND_ASSIGN(DragWindowDetails); |
| 170 }; | 233 }; |
| 171 | 234 |
| 172 // static | 235 // static |
| 173 float DragWindowController::GetDragWindowOpacity( | 236 float DragWindowController::GetDragWindowOpacity( |
| 174 const gfx::Rect& window_bounds, | 237 const gfx::Rect& window_bounds, |
| 175 const gfx::Rect& visible_bounds) { | 238 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_) { | 291 for (const std::unique_ptr<DragWindowDetails>& details : drag_windows_) { |
| 229 if (details->layer_owner_) { | 292 if (details->layer_owner_) { |
| 230 if (index == 0) | 293 if (index == 0) |
| 231 return details->layer_owner_.get(); | 294 return details->layer_owner_.get(); |
| 232 index--; | 295 index--; |
| 233 } | 296 } |
| 234 } | 297 } |
| 235 return nullptr; | 298 return nullptr; |
| 236 } | 299 } |
| 237 | 300 |
| 301 void DragWindowController::RequestLayerPaintForTest() { | |
| 302 ui::PaintContext context(nullptr, 1.0f, gfx::Rect()); | |
| 303 for (auto& details : drag_windows_) { | |
| 304 std::vector<ui::Layer*> layers; | |
| 305 layers.push_back(details->drag_window_->layer()); | |
| 306 while (layers.size()) { | |
| 307 ui::Layer* layer = layers.back(); | |
| 308 layers.pop_back(); | |
| 309 if (layer->delegate()) | |
| 310 layer->delegate()->OnPaintLayer(context); | |
| 311 for (auto* child : layer->children()) | |
| 312 layers.push_back(child); | |
| 313 } | |
| 314 } | |
| 315 } | |
| 316 | |
| 238 } // namespace ash | 317 } // namespace ash |
| OLD | NEW |