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 |