| 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/root_window.h" | 5 #include "ui/aura/root_window.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 using std::vector; | 44 using std::vector; |
| 45 | 45 |
| 46 namespace aura { | 46 namespace aura { |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 const char kRootWindowForAcceleratedWidget[] = | 50 const char kRootWindowForAcceleratedWidget[] = |
| 51 "__AURA_ROOT_WINDOW_ACCELERATED_WIDGET__"; | 51 "__AURA_ROOT_WINDOW_ACCELERATED_WIDGET__"; |
| 52 | 52 |
| 53 const int kCompositorLockTimeoutMs = 67; | |
| 54 | |
| 55 // Returns true if |target| has a non-client (frame) component at |location|, | 53 // Returns true if |target| has a non-client (frame) component at |location|, |
| 56 // in window coordinates. | 54 // in window coordinates. |
| 57 bool IsNonClientLocation(Window* target, const gfx::Point& location) { | 55 bool IsNonClientLocation(Window* target, const gfx::Point& location) { |
| 58 if (!target->delegate()) | 56 if (!target->delegate()) |
| 59 return false; | 57 return false; |
| 60 int hit_test_code = target->delegate()->GetNonClientComponent(location); | 58 int hit_test_code = target->delegate()->GetNonClientComponent(location); |
| 61 return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE; | 59 return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE; |
| 62 } | 60 } |
| 63 | 61 |
| 64 typedef std::vector<EventFilter*> EventFilters; | 62 typedef std::vector<EventFilter*> EventFilters; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 89 RootWindowHost* CreateHost(RootWindow* root_window, | 87 RootWindowHost* CreateHost(RootWindow* root_window, |
| 90 const RootWindow::CreateParams& params) { | 88 const RootWindow::CreateParams& params) { |
| 91 RootWindowHost* host = params.host ? | 89 RootWindowHost* host = params.host ? |
| 92 params.host : RootWindowHost::Create(params.initial_bounds); | 90 params.host : RootWindowHost::Create(params.initial_bounds); |
| 93 host->SetDelegate(root_window); | 91 host->SetDelegate(root_window); |
| 94 return host; | 92 return host; |
| 95 } | 93 } |
| 96 | 94 |
| 97 } // namespace | 95 } // namespace |
| 98 | 96 |
| 99 CompositorLock::CompositorLock(RootWindow* root_window) | |
| 100 : root_window_(root_window) { | |
| 101 MessageLoop::current()->PostDelayedTask( | |
| 102 FROM_HERE, | |
| 103 base::Bind(&CompositorLock::CancelLock, AsWeakPtr()), | |
| 104 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); | |
| 105 } | |
| 106 | |
| 107 CompositorLock::~CompositorLock() { | |
| 108 CancelLock(); | |
| 109 } | |
| 110 | |
| 111 void CompositorLock::CancelLock() { | |
| 112 if (!root_window_) | |
| 113 return; | |
| 114 root_window_->UnlockCompositor(); | |
| 115 root_window_ = NULL; | |
| 116 } | |
| 117 | |
| 118 RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds) | 97 RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds) |
| 119 : initial_bounds(a_initial_bounds), | 98 : initial_bounds(a_initial_bounds), |
| 120 host(NULL) { | 99 host(NULL) { |
| 121 } | 100 } |
| 122 | 101 |
| 123 //////////////////////////////////////////////////////////////////////////////// | 102 //////////////////////////////////////////////////////////////////////////////// |
| 124 // RootWindow, public: | 103 // RootWindow, public: |
| 125 | 104 |
| 126 RootWindow::RootWindow(const CreateParams& params) | 105 RootWindow::RootWindow(const CreateParams& params) |
| 127 : Window(NULL), | 106 : Window(NULL), |
| 128 ALLOW_THIS_IN_INITIALIZER_LIST(host_(CreateHost(this, params))), | 107 ALLOW_THIS_IN_INITIALIZER_LIST(host_(CreateHost(this, params))), |
| 129 ALLOW_THIS_IN_INITIALIZER_LIST(schedule_paint_factory_(this)), | 108 ALLOW_THIS_IN_INITIALIZER_LIST(schedule_paint_factory_(this)), |
| 130 ALLOW_THIS_IN_INITIALIZER_LIST(event_factory_(this)), | 109 ALLOW_THIS_IN_INITIALIZER_LIST(event_factory_(this)), |
| 131 mouse_button_flags_(0), | 110 mouse_button_flags_(0), |
| 132 touch_ids_down_(0), | 111 touch_ids_down_(0), |
| 133 last_cursor_(ui::kCursorNull), | 112 last_cursor_(ui::kCursorNull), |
| 134 mouse_pressed_handler_(NULL), | 113 mouse_pressed_handler_(NULL), |
| 135 mouse_moved_handler_(NULL), | 114 mouse_moved_handler_(NULL), |
| 136 mouse_event_dispatch_target_(NULL), | 115 mouse_event_dispatch_target_(NULL), |
| 137 event_dispatch_target_(NULL), | 116 event_dispatch_target_(NULL), |
| 138 focus_manager_(NULL), | 117 focus_manager_(NULL), |
| 139 ALLOW_THIS_IN_INITIALIZER_LIST( | 118 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 140 gesture_recognizer_(ui::GestureRecognizer::Create(this))), | 119 gesture_recognizer_(ui::GestureRecognizer::Create(this))), |
| 141 synthesize_mouse_move_(false), | 120 synthesize_mouse_move_(false), |
| 142 waiting_on_compositing_end_(false), | 121 waiting_on_compositing_end_(false), |
| 143 draw_on_compositing_end_(false), | 122 draw_on_compositing_end_(false), |
| 144 defer_draw_scheduling_(false), | 123 defer_draw_scheduling_(false), |
| 145 mouse_move_hold_count_(0), | 124 mouse_move_hold_count_(0), |
| 146 ALLOW_THIS_IN_INITIALIZER_LIST(held_mouse_event_factory_(this)), | 125 ALLOW_THIS_IN_INITIALIZER_LIST(held_mouse_event_factory_(this)) { |
| 147 compositor_lock_(NULL), | |
| 148 draw_on_compositor_unlock_(false) { | |
| 149 SetName("RootWindow"); | 126 SetName("RootWindow"); |
| 150 | 127 |
| 151 compositor_.reset(new ui::Compositor(this, host_->GetAcceleratedWidget())); | 128 compositor_.reset(new ui::Compositor(this, host_->GetAcceleratedWidget())); |
| 152 DCHECK(compositor_.get()); | 129 DCHECK(compositor_.get()); |
| 153 compositor_->AddObserver(this); | 130 compositor_->AddObserver(this); |
| 154 | 131 |
| 155 prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(), | 132 prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(), |
| 156 kRootWindowForAcceleratedWidget, | 133 kRootWindowForAcceleratedWidget, |
| 157 this)); | 134 this)); |
| 158 } | 135 } |
| 159 | 136 |
| 160 RootWindow::~RootWindow() { | 137 RootWindow::~RootWindow() { |
| 161 if (compositor_lock_) { | |
| 162 // No need to schedule a draw, we're going away. | |
| 163 draw_on_compositor_unlock_ = false; | |
| 164 compositor_lock_->CancelLock(); | |
| 165 DCHECK(!compositor_lock_); | |
| 166 } | |
| 167 compositor_->RemoveObserver(this); | 138 compositor_->RemoveObserver(this); |
| 168 // Make sure to destroy the compositor before terminating so that state is | 139 // Make sure to destroy the compositor before terminating so that state is |
| 169 // cleared and we don't hit asserts. | 140 // cleared and we don't hit asserts. |
| 170 compositor_.reset(); | 141 compositor_.reset(); |
| 171 | 142 |
| 172 // Tear down in reverse. Frees any references held by the host. | 143 // Tear down in reverse. Frees any references held by the host. |
| 173 host_.reset(NULL); | 144 host_.reset(NULL); |
| 174 | 145 |
| 175 // An observer may have been added by an animation on the RootWindow. | 146 // An observer may have been added by an animation on the RootWindow. |
| 176 layer()->GetAnimator()->RemoveObserver(this); | 147 layer()->GetAnimator()->RemoveObserver(this); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 // being used in fullscreen mode, so root_window bounds = window bounds. | 249 // being used in fullscreen mode, so root_window bounds = window bounds. |
| 279 return host_->ConfineCursorToRootWindow(); | 250 return host_->ConfineCursorToRootWindow(); |
| 280 } | 251 } |
| 281 | 252 |
| 282 void RootWindow::Draw() { | 253 void RootWindow::Draw() { |
| 283 defer_draw_scheduling_ = false; | 254 defer_draw_scheduling_ = false; |
| 284 if (waiting_on_compositing_end_) { | 255 if (waiting_on_compositing_end_) { |
| 285 draw_on_compositing_end_ = true; | 256 draw_on_compositing_end_ = true; |
| 286 return; | 257 return; |
| 287 } | 258 } |
| 288 if (compositor_lock_) { | |
| 289 draw_on_compositor_unlock_ = true; | |
| 290 return; | |
| 291 } | |
| 292 waiting_on_compositing_end_ = true; | 259 waiting_on_compositing_end_ = true; |
| 293 | 260 |
| 294 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::Draw", | 261 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::Draw", |
| 295 compositor_->last_started_frame() + 1); | 262 compositor_->last_started_frame() + 1); |
| 296 | 263 |
| 297 compositor_->Draw(false); | 264 compositor_->Draw(false); |
| 298 } | 265 } |
| 299 | 266 |
| 300 void RootWindow::ScheduleFullDraw() { | 267 void RootWindow::ScheduleFullDraw() { |
| 301 compositor_->ScheduleFullDraw(); | 268 compositor_->ScheduleFullDraw(); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 } | 375 } |
| 409 | 376 |
| 410 void RootWindow::ToggleFullScreen() { | 377 void RootWindow::ToggleFullScreen() { |
| 411 host_->ToggleFullScreen(); | 378 host_->ToggleFullScreen(); |
| 412 } | 379 } |
| 413 | 380 |
| 414 void RootWindow::HoldMouseMoves() { | 381 void RootWindow::HoldMouseMoves() { |
| 415 if (!mouse_move_hold_count_) | 382 if (!mouse_move_hold_count_) |
| 416 held_mouse_event_factory_.InvalidateWeakPtrs(); | 383 held_mouse_event_factory_.InvalidateWeakPtrs(); |
| 417 ++mouse_move_hold_count_; | 384 ++mouse_move_hold_count_; |
| 385 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldMouseMoves", this); |
| 418 } | 386 } |
| 419 | 387 |
| 420 void RootWindow::ReleaseMouseMoves() { | 388 void RootWindow::ReleaseMouseMoves() { |
| 421 --mouse_move_hold_count_; | 389 --mouse_move_hold_count_; |
| 422 DCHECK_GE(mouse_move_hold_count_, 0); | 390 DCHECK_GE(mouse_move_hold_count_, 0); |
| 423 if (!mouse_move_hold_count_ && held_mouse_move_.get()) { | 391 if (!mouse_move_hold_count_ && held_mouse_move_.get()) { |
| 424 // We don't want to call DispatchHeldMouseMove directly, because this might | 392 // We don't want to call DispatchHeldMouseMove directly, because this might |
| 425 // be called from a deep stack while another event, in which case | 393 // be called from a deep stack while another event, in which case |
| 426 // dispatching another one may not be safe/expected. | 394 // dispatching another one may not be safe/expected. |
| 427 // Instead we post a task, that we may cancel if HoldMouseMoves is called | 395 // Instead we post a task, that we may cancel if HoldMouseMoves is called |
| 428 // again before it executes. | 396 // again before it executes. |
| 429 MessageLoop::current()->PostTask( | 397 MessageLoop::current()->PostTask( |
| 430 FROM_HERE, | 398 FROM_HERE, |
| 431 base::Bind(&RootWindow::DispatchHeldMouseMove, | 399 base::Bind(&RootWindow::DispatchHeldMouseMove, |
| 432 held_mouse_event_factory_.GetWeakPtr())); | 400 held_mouse_event_factory_.GetWeakPtr())); |
| 433 } | 401 } |
| 434 } | 402 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::HoldMouseMoves", this); |
| 435 | |
| 436 scoped_refptr<CompositorLock> RootWindow::GetCompositorLock() { | |
| 437 if (!compositor_lock_) | |
| 438 compositor_lock_ = new CompositorLock(this); | |
| 439 return compositor_lock_; | |
| 440 } | 403 } |
| 441 | 404 |
| 442 void RootWindow::SetFocusWhenShown(bool focused) { | 405 void RootWindow::SetFocusWhenShown(bool focused) { |
| 443 host_->SetFocusWhenShown(focused); | 406 host_->SetFocusWhenShown(focused); |
| 444 } | 407 } |
| 445 | 408 |
| 446 bool RootWindow::GrabSnapshot(const gfx::Rect& snapshot_bounds, | 409 bool RootWindow::GrabSnapshot(const gfx::Rect& snapshot_bounds, |
| 447 std::vector<unsigned char>* png_representation) { | 410 std::vector<unsigned char>* png_representation) { |
| 448 DCHECK(bounds().Contains(snapshot_bounds)); | 411 DCHECK(bounds().Contains(snapshot_bounds)); |
| 449 gfx::Rect snapshot_pixels = ui::ConvertRectToPixel(layer(), snapshot_bounds); | 412 gfx::Rect snapshot_pixels = ui::ConvertRectToPixel(layer(), snapshot_bounds); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 // RootWindow, ui::EventTarget implementation: | 445 // RootWindow, ui::EventTarget implementation: |
| 483 | 446 |
| 484 ui::EventTarget* RootWindow::GetParentTarget() { | 447 ui::EventTarget* RootWindow::GetParentTarget() { |
| 485 return Env::GetInstance(); | 448 return Env::GetInstance(); |
| 486 } | 449 } |
| 487 | 450 |
| 488 //////////////////////////////////////////////////////////////////////////////// | 451 //////////////////////////////////////////////////////////////////////////////// |
| 489 // RootWindow, ui::CompositorDelegate implementation: | 452 // RootWindow, ui::CompositorDelegate implementation: |
| 490 | 453 |
| 491 void RootWindow::ScheduleDraw() { | 454 void RootWindow::ScheduleDraw() { |
| 492 if (compositor_lock_) { | 455 if (!defer_draw_scheduling_) { |
| 493 draw_on_compositor_unlock_ = true; | |
| 494 } else if (!defer_draw_scheduling_) { | |
| 495 defer_draw_scheduling_ = true; | 456 defer_draw_scheduling_ = true; |
| 496 MessageLoop::current()->PostTask( | 457 MessageLoop::current()->PostTask( |
| 497 FROM_HERE, | 458 FROM_HERE, |
| 498 base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); | 459 base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); |
| 499 } | 460 } |
| 500 } | 461 } |
| 501 | 462 |
| 502 //////////////////////////////////////////////////////////////////////////////// | 463 //////////////////////////////////////////////////////////////////////////////// |
| 503 // RootWindow, ui::CompositorObserver implementation: | 464 // RootWindow, ui::CompositorObserver implementation: |
| 504 | 465 |
| 505 void RootWindow::OnCompositingDidCommit(ui::Compositor*) { | 466 void RootWindow::OnCompositingDidCommit(ui::Compositor*) { |
| 506 } | 467 } |
| 507 | 468 |
| 508 void RootWindow::OnCompositingWillStart(ui::Compositor*) { | |
| 509 } | |
| 510 | |
| 511 void RootWindow::OnCompositingStarted(ui::Compositor*) { | 469 void RootWindow::OnCompositingStarted(ui::Compositor*) { |
| 512 } | 470 } |
| 513 | 471 |
| 514 void RootWindow::OnCompositingEnded(ui::Compositor*) { | 472 void RootWindow::OnCompositingEnded(ui::Compositor*) { |
| 515 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::Draw", | 473 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::Draw", |
| 516 compositor_->last_ended_frame()); | 474 compositor_->last_ended_frame()); |
| 517 waiting_on_compositing_end_ = false; | 475 waiting_on_compositing_end_ = false; |
| 518 if (draw_on_compositing_end_) { | 476 if (draw_on_compositing_end_) { |
| 519 draw_on_compositing_end_ = false; | 477 draw_on_compositing_end_ = false; |
| 520 | 478 |
| 521 // Call ScheduleDraw() instead of Draw() in order to allow other | 479 // Call ScheduleDraw() instead of Draw() in order to allow other |
| 522 // ui::CompositorObservers to be notified before starting another | 480 // ui::CompositorObservers to be notified before starting another |
| 523 // draw cycle. | 481 // draw cycle. |
| 524 ScheduleDraw(); | 482 ScheduleDraw(); |
| 525 } | 483 } |
| 526 } | 484 } |
| 527 | 485 |
| 528 void RootWindow::OnCompositingAborted(ui::Compositor*) { | 486 void RootWindow::OnCompositingAborted(ui::Compositor*) { |
| 529 } | 487 } |
| 530 | 488 |
| 489 void RootWindow::OnCompositingLockStateChanged(ui::Compositor*) { |
| 490 } |
| 491 |
| 531 //////////////////////////////////////////////////////////////////////////////// | 492 //////////////////////////////////////////////////////////////////////////////// |
| 532 // RootWindow, ui::LayerDelegate implementation: | 493 // RootWindow, ui::LayerDelegate implementation: |
| 533 | 494 |
| 534 void RootWindow::OnDeviceScaleFactorChanged( | 495 void RootWindow::OnDeviceScaleFactorChanged( |
| 535 float device_scale_factor) { | 496 float device_scale_factor) { |
| 536 const bool cursor_is_in_bounds = | 497 const bool cursor_is_in_bounds = |
| 537 GetBoundsInScreen().Contains(Env::GetInstance()->last_mouse_location()); | 498 GetBoundsInScreen().Contains(Env::GetInstance()->last_mouse_location()); |
| 538 bool cursor_visible = false; | 499 bool cursor_visible = false; |
| 539 client::CursorClient* cursor_client = client::GetCursorClient(this); | 500 client::CursorClient* cursor_client = client::GetCursorClient(this); |
| 540 if (cursor_is_in_bounds && cursor_client) { | 501 if (cursor_is_in_bounds && cursor_client) { |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 // currently broken. See/ crbug.com/107931. | 1018 // currently broken. See/ crbug.com/107931. |
| 1058 ui::MouseEvent event(ui::ET_MOUSE_MOVED, | 1019 ui::MouseEvent event(ui::ET_MOUSE_MOVED, |
| 1059 orig_mouse_location, | 1020 orig_mouse_location, |
| 1060 orig_mouse_location, | 1021 orig_mouse_location, |
| 1061 ui::EF_IS_SYNTHESIZED); | 1022 ui::EF_IS_SYNTHESIZED); |
| 1062 event.set_system_location(Env::GetInstance()->last_mouse_location()); | 1023 event.set_system_location(Env::GetInstance()->last_mouse_location()); |
| 1063 OnHostMouseEvent(&event); | 1024 OnHostMouseEvent(&event); |
| 1064 #endif | 1025 #endif |
| 1065 } | 1026 } |
| 1066 | 1027 |
| 1067 void RootWindow::UnlockCompositor() { | |
| 1068 DCHECK(compositor_lock_); | |
| 1069 compositor_lock_ = NULL; | |
| 1070 if (draw_on_compositor_unlock_) { | |
| 1071 draw_on_compositor_unlock_ = false; | |
| 1072 ScheduleDraw(); | |
| 1073 } | |
| 1074 } | |
| 1075 | |
| 1076 } // namespace aura | 1028 } // namespace aura |
| OLD | NEW |