window.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 3// found in the LICENSE file. 4 5#include "ui/aura/window.h" 6 7#include <algorithm> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/callback.h" 12#include "base/logging.h" 13#include "base/strings/string_number_conversions.h" 14#include "base/strings/string_util.h" 15#include "base/strings/stringprintf.h" 16#include "ui/aura/client/capture_client.h" 17#include "ui/aura/client/cursor_client.h" 18#include "ui/aura/client/event_client.h" 19#include "ui/aura/client/focus_client.h" 20#include "ui/aura/client/screen_position_client.h" 21#include "ui/aura/client/visibility_client.h" 22#include "ui/aura/client/window_stacking_client.h" 23#include "ui/aura/env.h" 24#include "ui/aura/layout_manager.h" 25#include "ui/aura/window_delegate.h" 26#include "ui/aura/window_event_dispatcher.h" 27#include "ui/aura/window_observer.h" 28#include "ui/aura/window_tracker.h" 29#include "ui/aura/window_tree_host.h" 30#include "ui/compositor/compositor.h" 31#include "ui/compositor/layer.h" 32#include "ui/events/event_target_iterator.h" 33#include "ui/gfx/animation/multi_animation.h" 34#include "ui/gfx/canvas.h" 35#include "ui/gfx/path.h" 36#include "ui/gfx/scoped_canvas.h" 37#include "ui/gfx/screen.h" 38 39namespace aura { 40 41namespace { 42 43ui::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. 59template <class T> 60T IteratorForDirectionBegin(aura::Window* window); 61 62template <> 63Window::Windows::const_iterator IteratorForDirectionBegin( 64 aura::Window* window) { 65 return window->children().begin(); 66} 67 68template <> 69Window::Windows::const_reverse_iterator IteratorForDirectionBegin( 70 aura::Window* window) { 71 return window->children().rbegin(); 72} 73 74template <class T> 75T IteratorForDirectionEnd(aura::Window* window); 76 77template <> 78Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) { 79 return window->children().end(); 80} 81 82template <> 83Window::Windows::const_reverse_iterator IteratorForDirectionEnd( 84 aura::Window* window) { 85 return window->children().rend(); 86} 87 88// Depth first search for the first Window with a layer to stack relative 89// to. Starts at target. Does not descend into |ignore|. 90template <class T> 91ui::Layer* FindStackingTargetLayerDown(aura::Window* target, 92 aura::Window* ignore) { 93 if (target == ignore) 94 return NULL; 95 96 if (target->layer()) 97 return target->layer(); 98 99 for (T i = IteratorForDirectionBegin<T>(target); 100 i != IteratorForDirectionEnd<T>(target); ++i) { 101 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore); 102 if (layer) 103 return layer; 104 } 105 return NULL; 106} 107 108// Depth first search through the siblings of |target||. This does not search 109// all the siblings, only those before/after |target| (depening upon the 110// template type) and ignoring |ignore|. Returns the Layer of the first Window 111// encountered with a Layer. 112template <class T> 113ui::Layer* FindStackingLayerInSiblings(aura::Window* target, 114 aura::Window* ignore) { 115 aura::Window* parent = target->parent(); 116 for (T i = std::find(IteratorForDirectionBegin<T>(parent), 117 IteratorForDirectionEnd<T>(parent), target); 118 i != IteratorForDirectionEnd<T>(parent); ++i) { 119 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore); 120 if (layer) 121 return layer; 122 } 123 return NULL; 124} 125 126// Returns the first Window that has a Layer. This does a depth first search 127// through the descendants of |target| first, then ascends up doing a depth 128// first search through siblings of all ancestors until a Layer is found or an 129// ancestor with a layer is found. This is intended to locate a layer to stack 130// other layers relative to. 131template <class T> 132ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) { 133 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore); 134 if (result) 135 return result; 136 while (target->parent()) { 137 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore); 138 if (result) 139 return result; 140 target = target->parent(); 141 if (target->layer()) 142 return NULL; 143 } 144 return NULL; 145} 146 147// Does a depth first search for all descendants of |child| that have layers. 148// This stops at any descendants that have layers (and adds them to |layers|). 149void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) { 150 if (child->layer()) { 151 layers->push_back(child->layer()); 152 return; 153 } 154 for (size_t i = 0; i < child->children().size(); ++i) 155 GetLayersToStack(child->children()[i], layers); 156} 157 158} // namespace 159 160class ScopedCursorHider { 161 public: 162 explicit ScopedCursorHider(Window* window) 163 : window_(window), 164 hid_cursor_(false) { 165 if (!window_->IsRootWindow()) 166 return; 167 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains( 168 Env::GetInstance()->last_mouse_location()); 169 client::CursorClient* cursor_client = client::GetCursorClient(window_); 170 if (cursor_is_in_bounds && cursor_client && 171 cursor_client->IsCursorVisible()) { 172 cursor_client->HideCursor(); 173 hid_cursor_ = true; 174 } 175 } 176 ~ScopedCursorHider() { 177 if (!window_->IsRootWindow()) 178 return; 179 180 // Update the device scale factor of the cursor client only when the last 181 // mouse location is on this root window. 182 if (hid_cursor_) { 183 client::CursorClient* cursor_client = client::GetCursorClient(window_); 184 if (cursor_client) { 185 const gfx::Display& display = 186 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow( 187 window_); 188 cursor_client->SetDisplay(display); 189 cursor_client->ShowCursor(); 190 } 191 } 192 } 193 194 private: 195 Window* window_; 196 bool hid_cursor_; 197 198 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider); 199}; 200 201Window::Window(WindowDelegate* delegate) 202 : host_(NULL), 203 type_(ui::wm::WINDOW_TYPE_UNKNOWN), 204 owned_by_parent_(true), 205 delegate_(delegate), 206 parent_(NULL), 207 visible_(false), 208 id_(-1), 209 transparent_(false), 210 user_data_(NULL), 211 ignore_events_(false), 212 // Don't notify newly added observers during notification. This causes 213 // problems for code that adds an observer as part of an observer 214 // notification (such as the workspace code). 215 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) { 216 set_target_handler(delegate_); 217} 218 219Window::~Window() { 220 // |layer()| can be NULL during tests, or if this Window is layerless. 221 if (layer()) 222 layer()->SuppressPaint(); 223 224 // Let the delegate know we're in the processing of destroying. 225 if (delegate_) 226 delegate_->OnWindowDestroying(this); 227 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); 228 229 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be 230 // necessary but unfortunately is right now due to ordering 231 // peculiarities. WED must be notified _after_ other observers 232 // are notified of pending teardown but before the hierarchy 233 // is actually torn down. 234 WindowTreeHost* host = GetHost(); 235 if (host) 236 host->dispatcher()->OnPostNotifiedWindowDestroying(this); 237 238 // The window should have already had its state cleaned up in 239 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes 240 // involving windows being destroyed without being hidden first. See 241 // crbug.com/342040. This should help us debug the issue. TODO(tdresser): 242 // remove this once we determine why we have windows that are destroyed 243 // without being hidden. 244 bool window_incorrectly_cleaned_up = CleanupGestureState(); 245 CHECK(!window_incorrectly_cleaned_up); 246 247 // Then destroy the children. 248 RemoveOrDestroyChildren(); 249 250 // The window needs to be removed from the parent before calling the 251 // WindowDestroyed callbacks of delegate and the observers. 252 if (parent_) 253 parent_->RemoveChild(this); 254 255 if (delegate_) 256 delegate_->OnWindowDestroyed(this); 257 ObserverListBase<WindowObserver>::Iterator iter(observers_); 258 WindowObserver* observer; 259 while ((observer = iter.GetNext())) { 260 RemoveObserver(observer); 261 observer->OnWindowDestroyed(this); 262 } 263 264 // Clear properties. 265 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin(); 266 iter != prop_map_.end(); 267 ++iter) { 268 if (iter->second.deallocator) 269 (*iter->second.deallocator)(iter->second.value); 270 } 271 prop_map_.clear(); 272 273 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or 274 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or 275 // we are layerless. 276 if (layer()) 277 layer()->set_delegate(NULL); 278 DestroyLayer(); 279} 280 281void Window::Init(WindowLayerType window_layer_type) { 282 if (window_layer_type != WINDOW_LAYER_NONE) { 283 SetLayer(new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type))); 284 layer()->SetVisible(false); 285 layer()->set_delegate(this); 286 UpdateLayerName(); 287 layer()->SetFillsBoundsOpaquely(!transparent_); 288 } 289 290 Env::GetInstance()->NotifyWindowInitialized(this); 291} 292 293void Window::SetType(ui::wm::WindowType type) { 294 // Cannot change type after the window is initialized. 295 DCHECK(!layer()); 296 type_ = type; 297} 298 299void Window::SetName(const std::string& name) { 300 name_ = name; 301 302 if (layer()) 303 UpdateLayerName(); 304} 305 306void Window::SetTransparent(bool transparent) { 307 transparent_ = transparent; 308 if (layer()) 309 layer()->SetFillsBoundsOpaquely(!transparent_); 310} 311 312void Window::SetFillsBoundsCompletely(bool fills_bounds) { 313 if (layer()) 314 layer()->SetFillsBoundsCompletely(fills_bounds); 315} 316 317Window* Window::GetRootWindow() { 318 return const_cast<Window*>( 319 static_cast<const Window*>(this)->GetRootWindow()); 320} 321 322const Window* Window::GetRootWindow() const { 323 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL; 324} 325 326WindowTreeHost* Window::GetHost() { 327 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)-> 328 GetHost()); 329} 330 331const WindowTreeHost* Window::GetHost() const { 332 const Window* root_window = GetRootWindow(); 333 return root_window ? root_window->host_ : NULL; 334} 335 336void Window::Show() { 337 if (layer()) { 338 DCHECK_EQ(visible_, layer()->GetTargetVisibility()); 339 // It is not allowed that a window is visible but the layers alpha is fully 340 // transparent since the window would still be considered to be active but 341 // could not be seen. 342 // TODO(skuhne): uncomment and fix issue 351553. 343 // DCHECK(!(visible_ && layer()->GetTargetOpacity() == 0.0f)); 344 } 345 SetVisible(true); 346} 347 348void Window::Hide() { 349 // RootWindow::OnVisibilityChanged will call ReleaseCapture. 350 SetVisible(false); 351} 352 353bool Window::IsVisible() const { 354 // Layer visibility can be inconsistent with window visibility, for example 355 // when a Window is hidden, we want this function to return false immediately 356 // after, even though the client may decide to animate the hide effect (and 357 // so the layer will be visible for some time after Hide() is called). 358 for (const Window* window = this; window; window = window->parent()) { 359 if (!window->visible_) 360 return false; 361 if (window->layer()) 362 return window->layer()->IsDrawn(); 363 } 364 return false; 365} 366 367gfx::Rect Window::GetBoundsInRootWindow() const { 368 // TODO(beng): There may be a better way to handle this, and the existing code 369 // is likely wrong anyway in a multi-display world, but this will 370 // do for now. 371 if (!GetRootWindow()) 372 return bounds(); 373 gfx::Point origin = bounds().origin(); 374 ConvertPointToTarget(parent_, GetRootWindow(), &origin); 375 return gfx::Rect(origin, bounds().size()); 376} 377 378gfx::Rect Window::GetBoundsInScreen() const { 379 gfx::Rect bounds(GetBoundsInRootWindow()); 380 const Window* root = GetRootWindow(); 381 if (root) { 382 aura::client::ScreenPositionClient* screen_position_client = 383 aura::client::GetScreenPositionClient(root); 384 if (screen_position_client) { 385 gfx::Point origin = bounds.origin(); 386 screen_position_client->ConvertPointToScreen(root, &origin); 387 bounds.set_origin(origin); 388 } 389 } 390 return bounds; 391} 392 393void Window::SetTransform(const gfx::Transform& transform) { 394 if (!layer()) { 395 // Transforms aren't supported on layerless windows. 396 NOTREACHED(); 397 return; 398 } 399 FOR_EACH_OBSERVER(WindowObserver, observers_, 400 OnWindowTransforming(this)); 401 layer()->SetTransform(transform); 402 FOR_EACH_OBSERVER(WindowObserver, observers_, 403 OnWindowTransformed(this)); 404} 405 406void Window::SetLayoutManager(LayoutManager* layout_manager) { 407 if (layout_manager == layout_manager_) 408 return; 409 layout_manager_.reset(layout_manager); 410 if (!layout_manager) 411 return; 412 // If we're changing to a new layout manager, ensure it is aware of all the 413 // existing child windows. 414 for (Windows::const_iterator it = children_.begin(); 415 it != children_.end(); 416 ++it) 417 layout_manager_->OnWindowAddedToLayout(*it); 418} 419 420scoped_ptr<ui::EventTargeter> 421Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) { 422 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass(); 423 targeter_ = targeter.Pass(); 424 return old_targeter.Pass(); 425} 426 427void Window::SetBounds(const gfx::Rect& new_bounds) { 428 if (parent_ && parent_->layout_manager()) 429 parent_->layout_manager()->SetChildBounds(this, new_bounds); 430 else 431 SetBoundsInternal(new_bounds); 432} 433 434void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen, 435 const gfx::Display& dst_display) { 436 Window* root = GetRootWindow(); 437 if (root) { 438 gfx::Point origin = new_bounds_in_screen.origin(); 439 aura::client::ScreenPositionClient* screen_position_client = 440 aura::client::GetScreenPositionClient(root); 441 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display); 442 return; 443 } 444 SetBounds(new_bounds_in_screen); 445} 446 447gfx::Rect Window::GetTargetBounds() const { 448 if (!layer()) 449 return bounds(); 450 451 if (!parent_ || parent_->layer()) 452 return layer()->GetTargetBounds(); 453 454 // We have a layer but our parent (who is valid) doesn't. This means the 455 // coordinates of the layer are relative to the first ancestor with a layer; 456 // convert to be relative to parent. 457 gfx::Vector2d offset; 458 const aura::Window* ancestor_with_layer = 459 parent_->GetAncestorWithLayer(&offset); 460 if (!ancestor_with_layer) 461 return layer()->GetTargetBounds(); 462 463 gfx::Rect layer_target_bounds = layer()->GetTargetBounds(); 464 layer_target_bounds -= offset; 465 return layer_target_bounds; 466} 467 468void Window::SchedulePaintInRect(const gfx::Rect& rect) { 469 if (!layer() && parent_) { 470 // Notification of paint scheduled happens for the window with a layer. 471 gfx::Rect parent_rect(bounds().size()); 472 parent_rect.Intersect(rect); 473 if (!parent_rect.IsEmpty()) { 474 parent_rect.Offset(bounds().origin().OffsetFromOrigin()); 475 parent_->SchedulePaintInRect(parent_rect); 476 } 477 } else if (layer() && layer()->SchedulePaint(rect)) { 478 FOR_EACH_OBSERVER( 479 WindowObserver, observers_, OnWindowPaintScheduled(this, rect)); 480 } 481} 482 483void Window::StackChildAtTop(Window* child) { 484 if (children_.size() <= 1 || child == children_.back()) 485 return; // In the front already. 486 StackChildAbove(child, children_.back()); 487} 488 489void Window::StackChildAbove(Window* child, Window* target) { 490 StackChildRelativeTo(child, target, STACK_ABOVE); 491} 492 493void Window::StackChildAtBottom(Window* child) { 494 if (children_.size() <= 1 || child == children_.front()) 495 return; // At the bottom already. 496 StackChildBelow(child, children_.front()); 497} 498 499void Window::StackChildBelow(Window* child, Window* target) { 500 StackChildRelativeTo(child, target, STACK_BELOW); 501} 502 503void Window::AddChild(Window* child) { 504 WindowObserver::HierarchyChangeParams params; 505 params.target = child; 506 params.new_parent = this; 507 params.old_parent = child->parent(); 508 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; 509 NotifyWindowHierarchyChange(params); 510 511 Window* old_root = child->GetRootWindow(); 512 513 DCHECK(std::find(children_.begin(), children_.end(), child) == 514 children_.end()); 515 if (child->parent()) 516 child->parent()->RemoveChildImpl(child, this); 517 518 gfx::Vector2d offset; 519 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset); 520 if (ancestor_with_layer) { 521 offset += child->bounds().OffsetFromOrigin(); 522 child->ReparentLayers(ancestor_with_layer->layer(), offset); 523 } 524 525 child->parent_ = this; 526 527 children_.push_back(child); 528 if (layout_manager_) 529 layout_manager_->OnWindowAddedToLayout(child); 530 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); 531 child->OnParentChanged(); 532 533 Window* root_window = GetRootWindow(); 534 if (root_window && old_root != root_window) { 535 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child); 536 child->NotifyAddedToRootWindow(); 537 } 538 539 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED; 540 NotifyWindowHierarchyChange(params); 541} 542 543void Window::RemoveChild(Window* child) { 544 WindowObserver::HierarchyChangeParams params; 545 params.target = child; 546 params.new_parent = NULL; 547 params.old_parent = this; 548 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; 549 NotifyWindowHierarchyChange(params); 550 551 RemoveChildImpl(child, NULL); 552 553 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED; 554 NotifyWindowHierarchyChange(params); 555} 556 557bool Window::Contains(const Window* other) const { 558 for (const Window* parent = other; parent; parent = parent->parent_) { 559 if (parent == this) 560 return true; 561 } 562 return false; 563} 564 565Window* Window::GetChildById(int id) { 566 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id)); 567} 568 569const Window* Window::GetChildById(int id) const { 570 Windows::const_iterator i; 571 for (i = children_.begin(); i != children_.end(); ++i) { 572 if ((*i)->id() == id) 573 return *i; 574 const Window* result = (*i)->GetChildById(id); 575 if (result) 576 return result; 577 } 578 return NULL; 579} 580 581// static 582void Window::ConvertPointToTarget(const Window* source, 583 const Window* target, 584 gfx::Point* point) { 585 if (!source) 586 return; 587 if (source->GetRootWindow() != target->GetRootWindow()) { 588 client::ScreenPositionClient* source_client = 589 client::GetScreenPositionClient(source->GetRootWindow()); 590 // |source_client| can be NULL in tests. 591 if (source_client) 592 source_client->ConvertPointToScreen(source, point); 593 594 client::ScreenPositionClient* target_client = 595 client::GetScreenPositionClient(target->GetRootWindow()); 596 // |target_client| can be NULL in tests. 597 if (target_client) 598 target_client->ConvertPointFromScreen(target, point); 599 } else if ((source != target) && (!source->layer() || !target->layer())) { 600 if (!source->layer()) { 601 gfx::Vector2d offset_to_layer; 602 source = source->GetAncestorWithLayer(&offset_to_layer); 603 *point += offset_to_layer; 604 } 605 if (!target->layer()) { 606 gfx::Vector2d offset_to_layer; 607 target = target->GetAncestorWithLayer(&offset_to_layer); 608 *point -= offset_to_layer; 609 } 610 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point); 611 } else { 612 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point); 613 } 614} 615 616// static 617void Window::ConvertRectToTarget(const Window* source, 618 const Window* target, 619 gfx::Rect* rect) { 620 DCHECK(rect); 621 gfx::Point origin = rect->origin(); 622 ConvertPointToTarget(source, target, &origin); 623 rect->set_origin(origin); 624} 625 626void Window::MoveCursorTo(const gfx::Point& point_in_window) { 627 Window* root_window = GetRootWindow(); 628 DCHECK(root_window); 629 gfx::Point point_in_root(point_in_window); 630 ConvertPointToTarget(this, root_window, &point_in_root); 631 root_window->GetHost()->MoveCursorTo(point_in_root); 632} 633 634gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const { 635 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor; 636} 637 638void Window::SetEventFilter(ui::EventHandler* event_filter) { 639 if (event_filter_) 640 RemovePreTargetHandler(event_filter_.get()); 641 event_filter_.reset(event_filter); 642 if (event_filter) 643 AddPreTargetHandler(event_filter); 644} 645 646void Window::AddObserver(WindowObserver* observer) { 647 observers_.AddObserver(observer); 648} 649 650void Window::RemoveObserver(WindowObserver* observer) { 651 observers_.RemoveObserver(observer); 652} 653 654bool Window::HasObserver(WindowObserver* observer) { 655 return observers_.HasObserver(observer); 656} 657 658bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const { 659 const Window* root_window = GetRootWindow(); 660 if (!root_window) 661 return false; 662 gfx::Point local_point(point_in_root); 663 ConvertPointToTarget(root_window, this, &local_point); 664 return gfx::Rect(GetTargetBounds().size()).Contains(local_point); 665} 666 667bool Window::ContainsPoint(const gfx::Point& local_point) const { 668 return gfx::Rect(bounds().size()).Contains(local_point); 669} 670 671Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) { 672 return GetWindowForPoint(local_point, true, true); 673} 674 675Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) { 676 return GetWindowForPoint(local_point, false, false); 677} 678 679Window* Window::GetToplevelWindow() { 680 Window* topmost_window_with_delegate = NULL; 681 for (aura::Window* window = this; window != NULL; window = window->parent()) { 682 if (window->delegate()) 683 topmost_window_with_delegate = window; 684 } 685 return topmost_window_with_delegate; 686} 687 688void Window::Focus() { 689 client::FocusClient* client = client::GetFocusClient(this); 690 DCHECK(client); 691 client->FocusWindow(this); 692} 693 694void Window::Blur() { 695 client::FocusClient* client = client::GetFocusClient(this); 696 DCHECK(client); 697 client->FocusWindow(NULL); 698} 699 700bool Window::HasFocus() const { 701 client::FocusClient* client = client::GetFocusClient(this); 702 return client && client->GetFocusedWindow() == this; 703} 704 705bool Window::CanFocus() const { 706 if (IsRootWindow()) 707 return IsVisible(); 708 709 // NOTE: as part of focusing the window the ActivationClient may make the 710 // window visible (by way of making a hidden ancestor visible). For this 711 // reason we can't check visibility here and assume the client is doing it. 712 if (!parent_ || (delegate_ && !delegate_->CanFocus())) 713 return false; 714 715 // The client may forbid certain windows from receiving focus at a given point 716 // in time. 717 client::EventClient* client = client::GetEventClient(GetRootWindow()); 718 if (client && !client->CanProcessEventsWithinSubtree(this)) 719 return false; 720 721 return parent_->CanFocus(); 722} 723 724bool Window::CanReceiveEvents() const { 725 if (IsRootWindow()) 726 return IsVisible(); 727 728 // The client may forbid certain windows from receiving events at a given 729 // point in time. 730 client::EventClient* client = client::GetEventClient(GetRootWindow()); 731 if (client && !client->CanProcessEventsWithinSubtree(this)) 732 return false; 733 734 return parent_ && IsVisible() && parent_->CanReceiveEvents(); 735} 736 737void Window::SetCapture() { 738 if (!IsVisible()) 739 return; 740 741 Window* root_window = GetRootWindow(); 742 if (!root_window) 743 return; 744 client::GetCaptureClient(root_window)->SetCapture(this); 745} 746 747void Window::ReleaseCapture() { 748 Window* root_window = GetRootWindow(); 749 if (!root_window) 750 return; 751 client::GetCaptureClient(root_window)->ReleaseCapture(this); 752} 753 754bool Window::HasCapture() { 755 Window* root_window = GetRootWindow(); 756 if (!root_window) 757 return false; 758 client::CaptureClient* capture_client = client::GetCaptureClient(root_window); 759 return capture_client && capture_client->GetCaptureWindow() == this; 760} 761 762void Window::SuppressPaint() { 763 if (layer()) 764 layer()->SuppressPaint(); 765} 766 767// {Set,Get,Clear}Property are implemented in window_property.h. 768 769void Window::SetNativeWindowProperty(const char* key, void* value) { 770 SetPropertyInternal( 771 key, key, NULL, reinterpret_cast<int64>(value), 0); 772} 773 774void* Window::GetNativeWindowProperty(const char* key) const { 775 return reinterpret_cast<void*>(GetPropertyInternal(key, 0)); 776} 777 778void Window::OnDeviceScaleFactorChanged(float device_scale_factor) { 779 ScopedCursorHider hider(this); 780 if (IsRootWindow()) 781 host_->OnDeviceScaleFactorChanged(device_scale_factor); 782 if (delegate_) 783 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 784} 785 786#if !defined(NDEBUG) 787std::string Window::GetDebugInfo() const { 788 return base::StringPrintf( 789 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f", 790 name().empty() ? "Unknown" : name().c_str(), id(), 791 bounds().x(), bounds().y(), bounds().width(), bounds().height(), 792 visible_ ? "WindowVisible" : "WindowHidden", 793 layer() ? 794 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") : 795 "NoLayer", 796 layer() ? layer()->opacity() : 1.0f); 797} 798 799void Window::PrintWindowHierarchy(int depth) const { 800 VLOG(0) << base::StringPrintf( 801 "%*s%s", depth * 2, "", GetDebugInfo().c_str()); 802 for (Windows::const_iterator it = children_.begin(); 803 it != children_.end(); ++it) { 804 Window* child = *it; 805 child->PrintWindowHierarchy(depth + 1); 806 } 807} 808#endif 809 810void Window::RemoveOrDestroyChildren() { 811 while (!children_.empty()) { 812 Window* child = children_[0]; 813 if (child->owned_by_parent_) { 814 delete child; 815 // Deleting the child so remove it from out children_ list. 816 DCHECK(std::find(children_.begin(), children_.end(), child) == 817 children_.end()); 818 } else { 819 // Even if we can't delete the child, we still need to remove it from the 820 // parent so that relevant bookkeeping (parent_ back-pointers etc) are 821 // updated. 822 RemoveChild(child); 823 } 824 } 825} 826 827/////////////////////////////////////////////////////////////////////////////// 828// Window, private: 829 830int64 Window::SetPropertyInternal(const void* key, 831 const char* name, 832 PropertyDeallocator deallocator, 833 int64 value, 834 int64 default_value) { 835 int64 old = GetPropertyInternal(key, default_value); 836 if (value == default_value) { 837 prop_map_.erase(key); 838 } else { 839 Value prop_value; 840 prop_value.name = name; 841 prop_value.value = value; 842 prop_value.deallocator = deallocator; 843 prop_map_[key] = prop_value; 844 } 845 FOR_EACH_OBSERVER(WindowObserver, observers_, 846 OnWindowPropertyChanged(this, key, old)); 847 return old; 848} 849 850int64 Window::GetPropertyInternal(const void* key, 851 int64 default_value) const { 852 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); 853 if (iter == prop_map_.end()) 854 return default_value; 855 return iter->second.value; 856} 857 858bool Window::HitTest(const gfx::Point& local_point) { 859 gfx::Rect local_bounds(bounds().size()); 860 if (!delegate_ || !delegate_->HasHitTestMask()) 861 return local_bounds.Contains(local_point); 862 863 gfx::Path mask; 864 delegate_->GetHitTestMask(&mask); 865 866 SkRegion clip_region; 867 clip_region.setRect(local_bounds.x(), local_bounds.y(), 868 local_bounds.width(), local_bounds.height()); 869 SkRegion mask_region; 870 return mask_region.setPath(mask, clip_region) && 871 mask_region.contains(local_point.x(), local_point.y()); 872} 873 874void Window::SetBoundsInternal(const gfx::Rect& new_bounds) { 875 gfx::Rect actual_new_bounds(new_bounds); 876 877 // Ensure we don't go smaller than our minimum bounds. 878 if (delegate_) { 879 const gfx::Size& min_size = delegate_->GetMinimumSize(); 880 actual_new_bounds.set_width( 881 std::max(min_size.width(), actual_new_bounds.width())); 882 actual_new_bounds.set_height( 883 std::max(min_size.height(), actual_new_bounds.height())); 884 } 885 886 gfx::Rect old_bounds = GetTargetBounds(); 887 888 // Always need to set the layer's bounds -- even if it is to the same thing. 889 // This may cause important side effects such as stopping animation. 890 if (!layer()) { 891 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() - 892 bounds_.OffsetFromOrigin(); 893 bounds_ = new_bounds; 894 OffsetLayerBounds(origin_delta); 895 } else { 896 if (parent_ && !parent_->layer()) { 897 gfx::Vector2d offset; 898 const aura::Window* ancestor_with_layer = 899 parent_->GetAncestorWithLayer(&offset); 900 if (ancestor_with_layer) 901 actual_new_bounds.Offset(offset); 902 } 903 layer()->SetBounds(actual_new_bounds); 904 } 905 906 // If we are currently not the layer's delegate, we will not get bounds 907 // changed notification from the layer (this typically happens after animating 908 // hidden). We must notify ourselves. 909 if (!layer() || layer()->delegate() != this) 910 OnWindowBoundsChanged(old_bounds); 911} 912 913void Window::SetVisible(bool visible) { 914 if ((layer() && visible == layer()->GetTargetVisibility()) || 915 (!layer() && visible == visible_)) 916 return; // No change. 917 918 FOR_EACH_OBSERVER(WindowObserver, observers_, 919 OnWindowVisibilityChanging(this, visible)); 920 921 client::VisibilityClient* visibility_client = 922 client::GetVisibilityClient(this); 923 if (visibility_client) 924 visibility_client->UpdateLayerVisibility(this, visible); 925 else if (layer()) 926 layer()->SetVisible(visible); 927 visible_ = visible; 928 SchedulePaint(); 929 if (parent_ && parent_->layout_manager_) 930 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); 931 932 if (delegate_) 933 delegate_->OnWindowTargetVisibilityChanged(visible); 934 935 NotifyWindowVisibilityChanged(this, visible); 936} 937 938void Window::SchedulePaint() { 939 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); 940} 941 942void Window::Paint(gfx::Canvas* canvas) { 943 if (delegate_) 944 delegate_->OnPaint(canvas); 945 PaintLayerlessChildren(canvas); 946} 947 948void Window::PaintLayerlessChildren(gfx::Canvas* canvas) { 949 for (size_t i = 0, count = children_.size(); i < count; ++i) { 950 Window* child = children_[i]; 951 if (!child->layer() && child->visible_) { 952 gfx::ScopedCanvas scoped_canvas(canvas); 953 canvas->ClipRect(child->bounds()); 954 if (!canvas->IsClipEmpty()) { 955 canvas->Translate(child->bounds().OffsetFromOrigin()); 956 child->Paint(canvas); 957 } 958 } 959 } 960} 961 962Window* Window::GetWindowForPoint(const gfx::Point& local_point, 963 bool return_tightest, 964 bool for_event_handling) { 965 if (!IsVisible()) 966 return NULL; 967 968 if ((for_event_handling && !HitTest(local_point)) || 969 (!for_event_handling && !ContainsPoint(local_point))) 970 return NULL; 971 972 // Check if I should claim this event and not pass it to my children because 973 // the location is inside my hit test override area. For details, see 974 // set_hit_test_bounds_override_inner(). 975 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) { 976 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size()); 977 inset_local_bounds.Inset(hit_test_bounds_override_inner_); 978 // We know we're inside the normal local bounds, so if we're outside the 979 // inset bounds we must be in the special hit test override area. 980 DCHECK(HitTest(local_point)); 981 if (!inset_local_bounds.Contains(local_point)) 982 return delegate_ ? this : NULL; 983 } 984 985 if (!return_tightest && delegate_) 986 return this; 987 988 for (Windows::const_reverse_iterator it = children_.rbegin(), 989 rend = children_.rend(); 990 it != rend; ++it) { 991 Window* child = *it; 992 993 if (for_event_handling) { 994 if (child->ignore_events_) 995 continue; 996 // The client may not allow events to be processed by certain subtrees. 997 client::EventClient* client = client::GetEventClient(GetRootWindow()); 998 if (client && !client->CanProcessEventsWithinSubtree(child)) 999 continue; 1000 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling( 1001 child, local_point)) 1002 continue; 1003 } 1004 1005 gfx::Point point_in_child_coords(local_point); 1006 ConvertPointToTarget(this, child, &point_in_child_coords); 1007 Window* match = child->GetWindowForPoint(point_in_child_coords, 1008 return_tightest, 1009 for_event_handling); 1010 if (match) 1011 return match; 1012 } 1013 1014 return delegate_ ? this : NULL; 1015} 1016 1017void Window::RemoveChildImpl(Window* child, Window* new_parent) { 1018 if (layout_manager_) 1019 layout_manager_->OnWillRemoveWindowFromLayout(child); 1020 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); 1021 Window* root_window = child->GetRootWindow(); 1022 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL; 1023 if (root_window && root_window != new_root_window) 1024 child->NotifyRemovingFromRootWindow(new_root_window); 1025 1026 gfx::Vector2d offset; 1027 GetAncestorWithLayer(&offset); 1028 child->UnparentLayers(!layer(), offset); 1029 child->parent_ = NULL; 1030 Windows::iterator i = std::find(children_.begin(), children_.end(), child); 1031 DCHECK(i != children_.end()); 1032 children_.erase(i); 1033 child->OnParentChanged(); 1034 if (layout_manager_) 1035 layout_manager_->OnWindowRemovedFromLayout(child); 1036} 1037 1038void Window::UnparentLayers(bool has_layerless_ancestor, 1039 const gfx::Vector2d& offset) { 1040 if (!layer()) { 1041 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin(); 1042 for (size_t i = 0; i < children_.size(); ++i) { 1043 children_[i]->UnparentLayers(true, new_offset); 1044 } 1045 } else { 1046 // Only remove the layer if we still own it. Someone else may have acquired 1047 // ownership of it via AcquireLayer() and may expect the hierarchy to go 1048 // unchanged as the Window is destroyed. 1049 if (OwnsLayer()) { 1050 if (layer()->parent()) 1051 layer()->parent()->Remove(layer()); 1052 if (has_layerless_ancestor) { 1053 const gfx::Rect real_bounds(bounds_); 1054 gfx::Rect layer_bounds(layer()->bounds()); 1055 layer_bounds.Offset(-offset); 1056 layer()->SetBounds(layer_bounds); 1057 bounds_ = real_bounds; 1058 } 1059 } 1060 } 1061} 1062 1063void Window::ReparentLayers(ui::Layer* parent_layer, 1064 const gfx::Vector2d& offset) { 1065 if (!layer()) { 1066 for (size_t i = 0; i < children_.size(); ++i) { 1067 children_[i]->ReparentLayers( 1068 parent_layer, 1069 offset + children_[i]->bounds().OffsetFromOrigin()); 1070 } 1071 } else { 1072 const gfx::Rect real_bounds(bounds()); 1073 parent_layer->Add(layer()); 1074 gfx::Rect layer_bounds(layer()->bounds().size()); 1075 layer_bounds += offset; 1076 layer()->SetBounds(layer_bounds); 1077 bounds_ = real_bounds; 1078 } 1079} 1080 1081void Window::OffsetLayerBounds(const gfx::Vector2d& offset) { 1082 if (!layer()) { 1083 for (size_t i = 0; i < children_.size(); ++i) 1084 children_[i]->OffsetLayerBounds(offset); 1085 } else { 1086 gfx::Rect layer_bounds(layer()->bounds()); 1087 layer_bounds += offset; 1088 layer()->SetBounds(layer_bounds); 1089 } 1090} 1091 1092void Window::OnParentChanged() { 1093 FOR_EACH_OBSERVER( 1094 WindowObserver, observers_, OnWindowParentChanged(this, parent_)); 1095} 1096 1097void Window::StackChildRelativeTo(Window* child, 1098 Window* target, 1099 StackDirection direction) { 1100 DCHECK_NE(child, target); 1101 DCHECK(child); 1102 DCHECK(target); 1103 DCHECK_EQ(this, child->parent()); 1104 DCHECK_EQ(this, target->parent()); 1105 1106 client::WindowStackingClient* stacking_client = 1107 client::GetWindowStackingClient(); 1108 if (stacking_client && 1109 !stacking_client->AdjustStacking(&child, &target, &direction)) 1110 return; 1111 1112 const size_t child_i = 1113 std::find(children_.begin(), children_.end(), child) - children_.begin(); 1114 const size_t target_i = 1115 std::find(children_.begin(), children_.end(), target) - children_.begin(); 1116 1117 // Don't move the child if it is already in the right place. 1118 if ((direction == STACK_ABOVE && child_i == target_i + 1) || 1119 (direction == STACK_BELOW && child_i + 1 == target_i)) 1120 return; 1121 1122 const size_t dest_i = 1123 direction == STACK_ABOVE ? 1124 (child_i < target_i ? target_i : target_i + 1) : 1125 (child_i < target_i ? target_i - 1 : target_i); 1126 children_.erase(children_.begin() + child_i); 1127 children_.insert(children_.begin() + dest_i, child); 1128 1129 StackChildLayerRelativeTo(child, target, direction); 1130 1131 child->OnStackingChanged(); 1132} 1133 1134void Window::StackChildLayerRelativeTo(Window* child, 1135 Window* target, 1136 StackDirection direction) { 1137 Window* ancestor_with_layer = GetAncestorWithLayer(NULL); 1138 ui::Layer* ancestor_layer = 1139 ancestor_with_layer ? ancestor_with_layer->layer() : NULL; 1140 if (!ancestor_layer) 1141 return; 1142 1143 if (child->layer() && target->layer()) { 1144 if (direction == STACK_ABOVE) 1145 ancestor_layer->StackAbove(child->layer(), target->layer()); 1146 else 1147 ancestor_layer->StackBelow(child->layer(), target->layer()); 1148 return; 1149 } 1150 typedef std::vector<ui::Layer*> Layers; 1151 Layers layers; 1152 GetLayersToStack(child, &layers); 1153 if (layers.empty()) 1154 return; 1155 1156 ui::Layer* target_layer; 1157 if (direction == STACK_ABOVE) { 1158 target_layer = 1159 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child); 1160 } else { 1161 target_layer = 1162 FindStackingTargetLayer<Windows::const_iterator>(target, child); 1163 } 1164 1165 if (!target_layer) { 1166 if (direction == STACK_ABOVE) { 1167 for (Layers::const_reverse_iterator i = layers.rbegin(), 1168 rend = layers.rend(); i != rend; ++i) { 1169 ancestor_layer->StackAtBottom(*i); 1170 } 1171 } else { 1172 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i) 1173 ancestor_layer->StackAtTop(*i); 1174 } 1175 return; 1176 } 1177 1178 if (direction == STACK_ABOVE) { 1179 for (Layers::const_reverse_iterator i = layers.rbegin(), 1180 rend = layers.rend(); i != rend; ++i) { 1181 ancestor_layer->StackAbove(*i, target_layer); 1182 } 1183 } else { 1184 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i) 1185 ancestor_layer->StackBelow(*i, target_layer); 1186 } 1187} 1188 1189void Window::OnStackingChanged() { 1190 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this)); 1191} 1192 1193void Window::NotifyRemovingFromRootWindow(Window* new_root) { 1194 FOR_EACH_OBSERVER(WindowObserver, observers_, 1195 OnWindowRemovingFromRootWindow(this, new_root)); 1196 for (Window::Windows::const_iterator it = children_.begin(); 1197 it != children_.end(); ++it) { 1198 (*it)->NotifyRemovingFromRootWindow(new_root); 1199 } 1200} 1201 1202void Window::NotifyAddedToRootWindow() { 1203 FOR_EACH_OBSERVER(WindowObserver, observers_, 1204 OnWindowAddedToRootWindow(this)); 1205 for (Window::Windows::const_iterator it = children_.begin(); 1206 it != children_.end(); ++it) { 1207 (*it)->NotifyAddedToRootWindow(); 1208 } 1209} 1210 1211void Window::NotifyWindowHierarchyChange( 1212 const WindowObserver::HierarchyChangeParams& params) { 1213 params.target->NotifyWindowHierarchyChangeDown(params); 1214 switch (params.phase) { 1215 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING: 1216 if (params.old_parent) 1217 params.old_parent->NotifyWindowHierarchyChangeUp(params); 1218 break; 1219 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED: 1220 if (params.new_parent) 1221 params.new_parent->NotifyWindowHierarchyChangeUp(params); 1222 break; 1223 default: 1224 NOTREACHED(); 1225 break; 1226 } 1227} 1228 1229void Window::NotifyWindowHierarchyChangeDown( 1230 const WindowObserver::HierarchyChangeParams& params) { 1231 NotifyWindowHierarchyChangeAtReceiver(params); 1232 for (Window::Windows::const_iterator it = children_.begin(); 1233 it != children_.end(); ++it) { 1234 (*it)->NotifyWindowHierarchyChangeDown(params); 1235 } 1236} 1237 1238void Window::NotifyWindowHierarchyChangeUp( 1239 const WindowObserver::HierarchyChangeParams& params) { 1240 for (Window* window = this; window; window = window->parent()) 1241 window->NotifyWindowHierarchyChangeAtReceiver(params); 1242} 1243 1244void Window::NotifyWindowHierarchyChangeAtReceiver( 1245 const WindowObserver::HierarchyChangeParams& params) { 1246 WindowObserver::HierarchyChangeParams local_params = params; 1247 local_params.receiver = this; 1248 1249 switch (params.phase) { 1250 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING: 1251 FOR_EACH_OBSERVER(WindowObserver, observers_, 1252 OnWindowHierarchyChanging(local_params)); 1253 break; 1254 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED: 1255 FOR_EACH_OBSERVER(WindowObserver, observers_, 1256 OnWindowHierarchyChanged(local_params)); 1257 break; 1258 default: 1259 NOTREACHED(); 1260 break; 1261 } 1262} 1263 1264void Window::NotifyWindowVisibilityChanged(aura::Window* target, 1265 bool visible) { 1266 if (!NotifyWindowVisibilityChangedDown(target, visible)) { 1267 return; // |this| has been deleted. 1268 } 1269 NotifyWindowVisibilityChangedUp(target, visible); 1270} 1271 1272bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target, 1273 bool visible) { 1274 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one 1275 // of the observers. We create an local observer for that. In that case we 1276 // exit without further access to any members. 1277 WindowTracker tracker; 1278 tracker.Add(this); 1279 FOR_EACH_OBSERVER(WindowObserver, observers_, 1280 OnWindowVisibilityChanged(target, visible)); 1281 return tracker.Contains(this); 1282} 1283 1284bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target, 1285 bool visible) { 1286 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible)) 1287 return false; // |this| was deleted. 1288 std::set<const Window*> child_already_processed; 1289 bool child_destroyed = false; 1290 do { 1291 child_destroyed = false; 1292 for (Window::Windows::const_iterator it = children_.begin(); 1293 it != children_.end(); ++it) { 1294 if (!child_already_processed.insert(*it).second) 1295 continue; 1296 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) { 1297 // |*it| was deleted, |it| is invalid and |children_| has changed. 1298 // We exit the current for-loop and enter a new one. 1299 child_destroyed = true; 1300 break; 1301 } 1302 } 1303 } while (child_destroyed); 1304 return true; 1305} 1306 1307void Window::NotifyWindowVisibilityChangedUp(aura::Window* target, 1308 bool visible) { 1309 for (Window* window = this; window; window = window->parent()) { 1310 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible); 1311 DCHECK(ret); 1312 } 1313} 1314 1315void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) { 1316 if (layer()) { 1317 bounds_ = layer()->bounds(); 1318 if (parent_ && !parent_->layer()) { 1319 gfx::Vector2d offset; 1320 aura::Window* ancestor_with_layer = 1321 parent_->GetAncestorWithLayer(&offset); 1322 if (ancestor_with_layer) 1323 bounds_.Offset(-offset); 1324 } 1325 } 1326 1327 if (layout_manager_) 1328 layout_manager_->OnWindowResized(); 1329 if (delegate_) 1330 delegate_->OnBoundsChanged(old_bounds, bounds()); 1331 FOR_EACH_OBSERVER(WindowObserver, 1332 observers_, 1333 OnWindowBoundsChanged(this, old_bounds, bounds())); 1334} 1335 1336bool Window::CleanupGestureState() { 1337 bool state_modified = false; 1338 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this); 1339 state_modified |= 1340 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this); 1341 for (Window::Windows::iterator iter = children_.begin(); 1342 iter != children_.end(); 1343 ++iter) { 1344 state_modified |= (*iter)->CleanupGestureState(); 1345 } 1346 return state_modified; 1347} 1348 1349void Window::OnPaintLayer(gfx::Canvas* canvas) { 1350 Paint(canvas); 1351} 1352 1353base::Closure Window::PrepareForLayerBoundsChange() { 1354 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this), 1355 bounds()); 1356} 1357 1358bool Window::CanAcceptEvent(const ui::Event& event) { 1359 // The client may forbid certain windows from receiving events at a given 1360 // point in time. 1361 client::EventClient* client = client::GetEventClient(GetRootWindow()); 1362 if (client && !client->CanProcessEventsWithinSubtree(this)) 1363 return false; 1364 1365 // We need to make sure that a touch cancel event and any gesture events it 1366 // creates can always reach the window. This ensures that we receive a valid 1367 // touch / gesture stream. 1368 if (event.IsEndingEvent()) 1369 return true; 1370 1371 if (!IsVisible()) 1372 return false; 1373 1374 // The top-most window can always process an event. 1375 if (!parent_) 1376 return true; 1377 1378 // For located events (i.e. mouse, touch etc.), an assumption is made that 1379 // windows that don't have a delegate cannot process the event (see more in 1380 // GetWindowForPoint()). This assumption is not made for key events. 1381 return event.IsKeyEvent() || delegate_; 1382} 1383 1384ui::EventTarget* Window::GetParentTarget() { 1385 if (IsRootWindow()) { 1386 return client::GetEventClient(this) ? 1387 client::GetEventClient(this)->GetToplevelEventTarget() : 1388 Env::GetInstance(); 1389 } 1390 return parent_; 1391} 1392 1393scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const { 1394 return scoped_ptr<ui::EventTargetIterator>( 1395 new ui::EventTargetIteratorImpl<Window>(children())); 1396} 1397 1398ui::EventTargeter* Window::GetEventTargeter() { 1399 return targeter_.get(); 1400} 1401 1402void Window::ConvertEventToTarget(ui::EventTarget* target, 1403 ui::LocatedEvent* event) { 1404 event->ConvertLocationToTarget(this, 1405 static_cast<Window*>(target)); 1406} 1407 1408void Window::UpdateLayerName() { 1409#if !defined(NDEBUG) 1410 DCHECK(layer()); 1411 1412 std::string layer_name(name_); 1413 if (layer_name.empty()) 1414 layer_name = "Unnamed Window"; 1415 1416 if (id_ != -1) 1417 layer_name += " " + base::IntToString(id_); 1418 1419 layer()->set_name(layer_name); 1420#endif 1421} 1422 1423bool Window::ContainsMouse() { 1424 bool contains_mouse = false; 1425 if (IsVisible()) { 1426 WindowTreeHost* host = GetHost(); 1427 contains_mouse = host && 1428 ContainsPointInRoot(host->dispatcher()->GetLastMouseLocationInRoot()); 1429 } 1430 return contains_mouse; 1431} 1432 1433const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const { 1434 for (const aura::Window* window = this; window; window = window->parent()) { 1435 if (window->layer()) 1436 return window; 1437 if (offset) 1438 *offset += window->bounds().OffsetFromOrigin(); 1439 } 1440 if (offset) 1441 *offset = gfx::Vector2d(); 1442 return NULL; 1443} 1444 1445} // namespace aura 1446