| 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 "ui/aura/window.h" | 5 #include "ui/aura/window.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "ui/events/event_target_iterator.h" | 33 #include "ui/events/event_target_iterator.h" |
| 34 #include "ui/gfx/canvas.h" | 34 #include "ui/gfx/canvas.h" |
| 35 #include "ui/gfx/path.h" | 35 #include "ui/gfx/path.h" |
| 36 #include "ui/gfx/scoped_canvas.h" | 36 #include "ui/gfx/scoped_canvas.h" |
| 37 #include "ui/gfx/screen.h" | 37 #include "ui/gfx/screen.h" |
| 38 | 38 |
| 39 namespace aura { | 39 namespace aura { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) { | |
| 44 switch (window_layer_type) { | |
| 45 case WINDOW_LAYER_NONE: | |
| 46 break; | |
| 47 case WINDOW_LAYER_NOT_DRAWN: | |
| 48 return ui::LAYER_NOT_DRAWN; | |
| 49 case WINDOW_LAYER_TEXTURED: | |
| 50 return ui::LAYER_TEXTURED; | |
| 51 case WINDOW_LAYER_SOLID_COLOR: | |
| 52 return ui::LAYER_SOLID_COLOR; | |
| 53 } | |
| 54 NOTREACHED(); | |
| 55 return ui::LAYER_NOT_DRAWN; | |
| 56 } | |
| 57 | |
| 58 // Used when searching for a Window to stack relative to. | 43 // Used when searching for a Window to stack relative to. |
| 59 template <class T> | 44 template <class T> |
| 60 T IteratorForDirectionBegin(aura::Window* window); | 45 T IteratorForDirectionBegin(aura::Window* window); |
| 61 | 46 |
| 62 template <> | 47 template <> |
| 63 Window::Windows::const_iterator IteratorForDirectionBegin( | 48 Window::Windows::const_iterator IteratorForDirectionBegin( |
| 64 aura::Window* window) { | 49 aura::Window* window) { |
| 65 return window->children().begin(); | 50 return window->children().begin(); |
| 66 } | 51 } |
| 67 | 52 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 user_data_(NULL), | 195 user_data_(NULL), |
| 211 ignore_events_(false), | 196 ignore_events_(false), |
| 212 // Don't notify newly added observers during notification. This causes | 197 // Don't notify newly added observers during notification. This causes |
| 213 // problems for code that adds an observer as part of an observer | 198 // problems for code that adds an observer as part of an observer |
| 214 // notification (such as the workspace code). | 199 // notification (such as the workspace code). |
| 215 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) { | 200 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) { |
| 216 set_target_handler(delegate_); | 201 set_target_handler(delegate_); |
| 217 } | 202 } |
| 218 | 203 |
| 219 Window::~Window() { | 204 Window::~Window() { |
| 220 // |layer()| can be NULL during tests, or if this Window is layerless. | 205 if (layer()->owner() == this) |
| 221 if (layer()) { | 206 layer()->CompleteAllAnimations(); |
| 222 if (layer()->owner() == this) | 207 layer()->SuppressPaint(); |
| 223 layer()->CompleteAllAnimations(); | |
| 224 layer()->SuppressPaint(); | |
| 225 } | |
| 226 | 208 |
| 227 // Let the delegate know we're in the processing of destroying. | 209 // Let the delegate know we're in the processing of destroying. |
| 228 if (delegate_) | 210 if (delegate_) |
| 229 delegate_->OnWindowDestroying(this); | 211 delegate_->OnWindowDestroying(this); |
| 230 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); | 212 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); |
| 231 | 213 |
| 232 // While we are being destroyed, our target handler may also be in the | 214 // While we are being destroyed, our target handler may also be in the |
| 233 // process of destruction or already destroyed, so do not forward any | 215 // process of destruction or already destroyed, so do not forward any |
| 234 // input events at the ui::EP_TARGET phase. | 216 // input events at the ui::EP_TARGET phase. |
| 235 set_target_handler(nullptr); | 217 set_target_handler(nullptr); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 253 |
| 272 // Clear properties. | 254 // Clear properties. |
| 273 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin(); | 255 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin(); |
| 274 iter != prop_map_.end(); | 256 iter != prop_map_.end(); |
| 275 ++iter) { | 257 ++iter) { |
| 276 if (iter->second.deallocator) | 258 if (iter->second.deallocator) |
| 277 (*iter->second.deallocator)(iter->second.value); | 259 (*iter->second.deallocator)(iter->second.value); |
| 278 } | 260 } |
| 279 prop_map_.clear(); | 261 prop_map_.clear(); |
| 280 | 262 |
| 281 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or | 263 // The layer will either be destroyed by |layer_owner_|'s dtor, or by whoever |
| 282 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or | 264 // acquired it. |
| 283 // we are layerless. | 265 layer()->set_delegate(NULL); |
| 284 if (layer()) | |
| 285 layer()->set_delegate(NULL); | |
| 286 DestroyLayer(); | 266 DestroyLayer(); |
| 287 } | 267 } |
| 288 | 268 |
| 289 void Window::Init(WindowLayerType window_layer_type) { | 269 void Window::Init(ui::LayerType layer_type) { |
| 290 if (window_layer_type != WINDOW_LAYER_NONE) { | 270 SetLayer(new ui::Layer(layer_type)); |
| 291 SetLayer(new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type))); | 271 layer()->SetVisible(false); |
| 292 layer()->SetVisible(false); | 272 layer()->set_delegate(this); |
| 293 layer()->set_delegate(this); | 273 UpdateLayerName(); |
| 294 UpdateLayerName(); | 274 layer()->SetFillsBoundsOpaquely(!transparent_); |
| 295 layer()->SetFillsBoundsOpaquely(!transparent_); | |
| 296 } | |
| 297 | |
| 298 Env::GetInstance()->NotifyWindowInitialized(this); | 275 Env::GetInstance()->NotifyWindowInitialized(this); |
| 299 } | 276 } |
| 300 | 277 |
| 301 void Window::SetType(ui::wm::WindowType type) { | 278 void Window::SetType(ui::wm::WindowType type) { |
| 302 // Cannot change type after the window is initialized. | 279 // Cannot change type after the window is initialized. |
| 303 DCHECK(!layer()); | 280 DCHECK(!layer()); |
| 304 type_ = type; | 281 type_ = type; |
| 305 } | 282 } |
| 306 | 283 |
| 307 void Window::SetName(const std::string& name) { | 284 void Window::SetName(const std::string& name) { |
| 308 name_ = name; | 285 name_ = name; |
| 309 | |
| 310 if (layer()) | 286 if (layer()) |
| 311 UpdateLayerName(); | 287 UpdateLayerName(); |
| 312 } | 288 } |
| 313 | 289 |
| 314 void Window::SetTitle(const base::string16& title) { | 290 void Window::SetTitle(const base::string16& title) { |
| 315 title_ = title; | 291 title_ = title; |
| 316 FOR_EACH_OBSERVER(WindowObserver, | 292 FOR_EACH_OBSERVER(WindowObserver, |
| 317 observers_, | 293 observers_, |
| 318 OnWindowTitleChanged(this)); | 294 OnWindowTitleChanged(this)); |
| 319 } | 295 } |
| 320 | 296 |
| 321 void Window::SetTransparent(bool transparent) { | 297 void Window::SetTransparent(bool transparent) { |
| 322 transparent_ = transparent; | 298 transparent_ = transparent; |
| 323 if (layer()) | 299 if (layer()) |
| 324 layer()->SetFillsBoundsOpaquely(!transparent_); | 300 layer()->SetFillsBoundsOpaquely(!transparent_); |
| 325 } | 301 } |
| 326 | 302 |
| 327 void Window::SetFillsBoundsCompletely(bool fills_bounds) { | 303 void Window::SetFillsBoundsCompletely(bool fills_bounds) { |
| 328 if (layer()) | 304 layer()->SetFillsBoundsCompletely(fills_bounds); |
| 329 layer()->SetFillsBoundsCompletely(fills_bounds); | |
| 330 } | 305 } |
| 331 | 306 |
| 332 Window* Window::GetRootWindow() { | 307 Window* Window::GetRootWindow() { |
| 333 return const_cast<Window*>( | 308 return const_cast<Window*>( |
| 334 static_cast<const Window*>(this)->GetRootWindow()); | 309 static_cast<const Window*>(this)->GetRootWindow()); |
| 335 } | 310 } |
| 336 | 311 |
| 337 const Window* Window::GetRootWindow() const { | 312 const Window* Window::GetRootWindow() const { |
| 338 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL; | 313 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL; |
| 339 } | 314 } |
| 340 | 315 |
| 341 WindowTreeHost* Window::GetHost() { | 316 WindowTreeHost* Window::GetHost() { |
| 342 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)-> | 317 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)-> |
| 343 GetHost()); | 318 GetHost()); |
| 344 } | 319 } |
| 345 | 320 |
| 346 const WindowTreeHost* Window::GetHost() const { | 321 const WindowTreeHost* Window::GetHost() const { |
| 347 const Window* root_window = GetRootWindow(); | 322 const Window* root_window = GetRootWindow(); |
| 348 return root_window ? root_window->host_ : NULL; | 323 return root_window ? root_window->host_ : NULL; |
| 349 } | 324 } |
| 350 | 325 |
| 351 void Window::Show() { | 326 void Window::Show() { |
| 352 if (layer()) { | 327 DCHECK_EQ(visible_, layer()->GetTargetVisibility()); |
| 353 DCHECK_EQ(visible_, layer()->GetTargetVisibility()); | 328 // It is not allowed that a window is visible but the layers alpha is fully |
| 354 // It is not allowed that a window is visible but the layers alpha is fully | 329 // transparent since the window would still be considered to be active but |
| 355 // transparent since the window would still be considered to be active but | 330 // could not be seen. |
| 356 // could not be seen. | 331 DCHECK_IMPLIES(visible_, layer()->GetTargetOpacity() > 0.0f); |
| 357 DCHECK(!(visible_ && layer()->GetTargetOpacity() == 0.0f)); | |
| 358 } | |
| 359 SetVisible(true); | 332 SetVisible(true); |
| 360 } | 333 } |
| 361 | 334 |
| 362 void Window::Hide() { | 335 void Window::Hide() { |
| 363 // RootWindow::OnVisibilityChanged will call ReleaseCapture. | 336 // RootWindow::OnVisibilityChanged will call ReleaseCapture. |
| 364 SetVisible(false); | 337 SetVisible(false); |
| 365 } | 338 } |
| 366 | 339 |
| 367 bool Window::IsVisible() const { | 340 bool Window::IsVisible() const { |
| 368 // Layer visibility can be inconsistent with window visibility, for example | 341 // Layer visibility can be inconsistent with window visibility, for example |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 parent_->GetAncestorWithLayer(&offset); | 456 parent_->GetAncestorWithLayer(&offset); |
| 484 if (!ancestor_with_layer) | 457 if (!ancestor_with_layer) |
| 485 return layer()->GetTargetBounds(); | 458 return layer()->GetTargetBounds(); |
| 486 | 459 |
| 487 gfx::Rect layer_target_bounds = layer()->GetTargetBounds(); | 460 gfx::Rect layer_target_bounds = layer()->GetTargetBounds(); |
| 488 layer_target_bounds -= offset; | 461 layer_target_bounds -= offset; |
| 489 return layer_target_bounds; | 462 return layer_target_bounds; |
| 490 } | 463 } |
| 491 | 464 |
| 492 void Window::SchedulePaintInRect(const gfx::Rect& rect) { | 465 void Window::SchedulePaintInRect(const gfx::Rect& rect) { |
| 493 if (!layer() && parent_) { | 466 layer()->SchedulePaint(rect); |
| 494 // Notification of paint scheduled happens for the window with a layer. | |
| 495 gfx::Rect parent_rect(bounds().size()); | |
| 496 parent_rect.Intersect(rect); | |
| 497 if (!parent_rect.IsEmpty()) { | |
| 498 parent_rect.Offset(bounds().origin().OffsetFromOrigin()); | |
| 499 parent_->SchedulePaintInRect(parent_rect); | |
| 500 } | |
| 501 } else if (layer()) { | |
| 502 layer()->SchedulePaint(rect); | |
| 503 } | |
| 504 } | 467 } |
| 505 | 468 |
| 506 void Window::StackChildAtTop(Window* child) { | 469 void Window::StackChildAtTop(Window* child) { |
| 507 if (children_.size() <= 1 || child == children_.back()) | 470 if (children_.size() <= 1 || child == children_.back()) |
| 508 return; // In the front already. | 471 return; // In the front already. |
| 509 StackChildAbove(child, children_.back()); | 472 StackChildAbove(child, children_.back()); |
| 510 } | 473 } |
| 511 | 474 |
| 512 void Window::StackChildAbove(Window* child, Window* target) { | 475 void Window::StackChildAbove(Window* child, Window* target) { |
| 513 StackChildRelativeTo(child, target, STACK_ABOVE); | 476 StackChildRelativeTo(child, target, STACK_ABOVE); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 | 744 |
| 782 bool Window::HasCapture() { | 745 bool Window::HasCapture() { |
| 783 Window* root_window = GetRootWindow(); | 746 Window* root_window = GetRootWindow(); |
| 784 if (!root_window) | 747 if (!root_window) |
| 785 return false; | 748 return false; |
| 786 client::CaptureClient* capture_client = client::GetCaptureClient(root_window); | 749 client::CaptureClient* capture_client = client::GetCaptureClient(root_window); |
| 787 return capture_client && capture_client->GetCaptureWindow() == this; | 750 return capture_client && capture_client->GetCaptureWindow() == this; |
| 788 } | 751 } |
| 789 | 752 |
| 790 void Window::SuppressPaint() { | 753 void Window::SuppressPaint() { |
| 791 if (layer()) | 754 layer()->SuppressPaint(); |
| 792 layer()->SuppressPaint(); | |
| 793 } | 755 } |
| 794 | 756 |
| 795 // {Set,Get,Clear}Property are implemented in window_property.h. | 757 // {Set,Get,Clear}Property are implemented in window_property.h. |
| 796 | 758 |
| 797 void Window::SetNativeWindowProperty(const char* key, void* value) { | 759 void Window::SetNativeWindowProperty(const char* key, void* value) { |
| 798 SetPropertyInternal( | 760 SetPropertyInternal( |
| 799 key, key, NULL, reinterpret_cast<int64>(value), 0); | 761 key, key, NULL, reinterpret_cast<int64>(value), 0); |
| 800 } | 762 } |
| 801 | 763 |
| 802 void* Window::GetNativeWindowProperty(const char* key) const { | 764 void* Window::GetNativeWindowProperty(const char* key) const { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 (!layer() && visible == visible_)) | 897 (!layer() && visible == visible_)) |
| 936 return; // No change. | 898 return; // No change. |
| 937 | 899 |
| 938 FOR_EACH_OBSERVER(WindowObserver, observers_, | 900 FOR_EACH_OBSERVER(WindowObserver, observers_, |
| 939 OnWindowVisibilityChanging(this, visible)); | 901 OnWindowVisibilityChanging(this, visible)); |
| 940 | 902 |
| 941 client::VisibilityClient* visibility_client = | 903 client::VisibilityClient* visibility_client = |
| 942 client::GetVisibilityClient(this); | 904 client::GetVisibilityClient(this); |
| 943 if (visibility_client) | 905 if (visibility_client) |
| 944 visibility_client->UpdateLayerVisibility(this, visible); | 906 visibility_client->UpdateLayerVisibility(this, visible); |
| 945 else if (layer()) | 907 else |
| 946 layer()->SetVisible(visible); | 908 layer()->SetVisible(visible); |
| 947 visible_ = visible; | 909 visible_ = visible; |
| 948 SchedulePaint(); | 910 SchedulePaint(); |
| 949 if (parent_ && parent_->layout_manager_) | 911 if (parent_ && parent_->layout_manager_) |
| 950 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); | 912 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); |
| 951 | 913 |
| 952 if (delegate_) | 914 if (delegate_) |
| 953 delegate_->OnWindowTargetVisibilityChanged(visible); | 915 delegate_->OnWindowTargetVisibilityChanged(visible); |
| 954 | 916 |
| 955 NotifyWindowVisibilityChanged(this, visible); | 917 NotifyWindowVisibilityChanged(this, visible); |
| 956 } | 918 } |
| 957 | 919 |
| 958 void Window::SchedulePaint() { | 920 void Window::SchedulePaint() { |
| 959 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); | 921 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); |
| 960 } | 922 } |
| 961 | 923 |
| 962 void Window::Paint(gfx::Canvas* canvas) { | 924 void Window::Paint(gfx::Canvas* canvas) { |
| 963 if (delegate_) | 925 if (delegate_) |
| 964 delegate_->OnPaint(canvas); | 926 delegate_->OnPaint(canvas); |
| 965 PaintLayerlessChildren(canvas); | |
| 966 } | |
| 967 | |
| 968 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) { | |
| 969 for (size_t i = 0, count = children_.size(); i < count; ++i) { | |
| 970 Window* child = children_[i]; | |
| 971 if (!child->layer() && child->visible_) { | |
| 972 gfx::ScopedCanvas scoped_canvas(canvas); | |
| 973 canvas->ClipRect(child->bounds()); | |
| 974 if (!canvas->IsClipEmpty()) { | |
| 975 canvas->Translate(child->bounds().OffsetFromOrigin()); | |
| 976 child->Paint(canvas); | |
| 977 } | |
| 978 } | |
| 979 } | |
| 980 } | 927 } |
| 981 | 928 |
| 982 Window* Window::GetWindowForPoint(const gfx::Point& local_point, | 929 Window* Window::GetWindowForPoint(const gfx::Point& local_point, |
| 983 bool return_tightest, | 930 bool return_tightest, |
| 984 bool for_event_handling) { | 931 bool for_event_handling) { |
| 985 if (!IsVisible()) | 932 if (!IsVisible()) |
| 986 return NULL; | 933 return NULL; |
| 987 | 934 |
| 988 if ((for_event_handling && !HitTest(local_point)) || | 935 if ((for_event_handling && !HitTest(local_point)) || |
| 989 (!for_event_handling && !ContainsPoint(local_point))) | 936 (!for_event_handling && !ContainsPoint(local_point))) |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 void Window::NotifyAncestorWindowTransformed(Window* source) { | 1284 void Window::NotifyAncestorWindowTransformed(Window* source) { |
| 1338 FOR_EACH_OBSERVER(WindowObserver, observers_, | 1285 FOR_EACH_OBSERVER(WindowObserver, observers_, |
| 1339 OnAncestorWindowTransformed(source, this)); | 1286 OnAncestorWindowTransformed(source, this)); |
| 1340 for (Window::Windows::const_iterator it = children_.begin(); | 1287 for (Window::Windows::const_iterator it = children_.begin(); |
| 1341 it != children_.end(); ++it) { | 1288 it != children_.end(); ++it) { |
| 1342 (*it)->NotifyAncestorWindowTransformed(source); | 1289 (*it)->NotifyAncestorWindowTransformed(source); |
| 1343 } | 1290 } |
| 1344 } | 1291 } |
| 1345 | 1292 |
| 1346 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) { | 1293 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) { |
| 1347 if (layer()) { | 1294 bounds_ = layer()->bounds(); |
| 1348 bounds_ = layer()->bounds(); | 1295 if (parent_ && !parent_->layer()) { |
| 1349 if (parent_ && !parent_->layer()) { | 1296 gfx::Vector2d offset; |
| 1350 gfx::Vector2d offset; | 1297 aura::Window* ancestor_with_layer = parent_->GetAncestorWithLayer(&offset); |
| 1351 aura::Window* ancestor_with_layer = | 1298 if (ancestor_with_layer) |
| 1352 parent_->GetAncestorWithLayer(&offset); | 1299 bounds_.Offset(-offset); |
| 1353 if (ancestor_with_layer) | |
| 1354 bounds_.Offset(-offset); | |
| 1355 } | |
| 1356 } | 1300 } |
| 1357 | 1301 |
| 1358 if (layout_manager_) | 1302 if (layout_manager_) |
| 1359 layout_manager_->OnWindowResized(); | 1303 layout_manager_->OnWindowResized(); |
| 1360 if (delegate_) | 1304 if (delegate_) |
| 1361 delegate_->OnBoundsChanged(old_bounds, bounds()); | 1305 delegate_->OnBoundsChanged(old_bounds, bounds()); |
| 1362 FOR_EACH_OBSERVER(WindowObserver, | 1306 FOR_EACH_OBSERVER(WindowObserver, |
| 1363 observers_, | 1307 observers_, |
| 1364 OnWindowBoundsChanged(this, old_bounds, bounds())); | 1308 OnWindowBoundsChanged(this, old_bounds, bounds())); |
| 1365 } | 1309 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 return window; | 1408 return window; |
| 1465 if (offset) | 1409 if (offset) |
| 1466 *offset += window->bounds().OffsetFromOrigin(); | 1410 *offset += window->bounds().OffsetFromOrigin(); |
| 1467 } | 1411 } |
| 1468 if (offset) | 1412 if (offset) |
| 1469 *offset = gfx::Vector2d(); | 1413 *offset = gfx::Vector2d(); |
| 1470 return NULL; | 1414 return NULL; |
| 1471 } | 1415 } |
| 1472 | 1416 |
| 1473 } // namespace aura | 1417 } // namespace aura |
| OLD | NEW |