| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 } | 378 } |
| 412 | 379 |
| 413 void RootWindow::ToggleFullScreen() { | 380 void RootWindow::ToggleFullScreen() { |
| 414 host_->ToggleFullScreen(); | 381 host_->ToggleFullScreen(); |
| 415 } | 382 } |
| 416 | 383 |
| 417 void RootWindow::HoldMouseMoves() { | 384 void RootWindow::HoldMouseMoves() { |
| 418 if (!mouse_move_hold_count_) | 385 if (!mouse_move_hold_count_) |
| 419 held_mouse_event_factory_.InvalidateWeakPtrs(); | 386 held_mouse_event_factory_.InvalidateWeakPtrs(); |
| 420 ++mouse_move_hold_count_; | 387 ++mouse_move_hold_count_; |
| 388 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldMouseMoves", this); |
| 421 } | 389 } |
| 422 | 390 |
| 423 void RootWindow::ReleaseMouseMoves() { | 391 void RootWindow::ReleaseMouseMoves() { |
| 424 --mouse_move_hold_count_; | 392 --mouse_move_hold_count_; |
| 425 DCHECK_GE(mouse_move_hold_count_, 0); | 393 DCHECK_GE(mouse_move_hold_count_, 0); |
| 426 if (!mouse_move_hold_count_ && held_mouse_move_.get()) { | 394 if (!mouse_move_hold_count_ && held_mouse_move_.get()) { |
| 427 // We don't want to call DispatchHeldMouseMove directly, because this might | 395 // We don't want to call DispatchHeldMouseMove directly, because this might |
| 428 // be called from a deep stack while another event, in which case | 396 // be called from a deep stack while another event, in which case |
| 429 // dispatching another one may not be safe/expected. | 397 // dispatching another one may not be safe/expected. |
| 430 // Instead we post a task, that we may cancel if HoldMouseMoves is called | 398 // Instead we post a task, that we may cancel if HoldMouseMoves is called |
| 431 // again before it executes. | 399 // again before it executes. |
| 432 MessageLoop::current()->PostTask( | 400 MessageLoop::current()->PostTask( |
| 433 FROM_HERE, | 401 FROM_HERE, |
| 434 base::Bind(&RootWindow::DispatchHeldMouseMove, | 402 base::Bind(&RootWindow::DispatchHeldMouseMove, |
| 435 held_mouse_event_factory_.GetWeakPtr())); | 403 held_mouse_event_factory_.GetWeakPtr())); |
| 436 } | 404 } |
| 437 } | 405 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::HoldMouseMoves", this); |
| 438 | |
| 439 scoped_refptr<CompositorLock> RootWindow::GetCompositorLock() { | |
| 440 if (!compositor_lock_) | |
| 441 compositor_lock_ = new CompositorLock(this); | |
| 442 return compositor_lock_; | |
| 443 } | 406 } |
| 444 | 407 |
| 445 void RootWindow::SetFocusWhenShown(bool focused) { | 408 void RootWindow::SetFocusWhenShown(bool focused) { |
| 446 host_->SetFocusWhenShown(focused); | 409 host_->SetFocusWhenShown(focused); |
| 447 } | 410 } |
| 448 | 411 |
| 449 bool RootWindow::GrabSnapshot(const gfx::Rect& snapshot_bounds, | 412 bool RootWindow::GrabSnapshot(const gfx::Rect& snapshot_bounds, |
| 450 std::vector<unsigned char>* png_representation) { | 413 std::vector<unsigned char>* png_representation) { |
| 451 DCHECK(bounds().Contains(snapshot_bounds)); | 414 DCHECK(bounds().Contains(snapshot_bounds)); |
| 452 gfx::Rect snapshot_pixels = ui::ConvertRectToPixel(layer(), snapshot_bounds); | 415 gfx::Rect snapshot_pixels = ui::ConvertRectToPixel(layer(), snapshot_bounds); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 // RootWindow, ui::EventTarget implementation: | 448 // RootWindow, ui::EventTarget implementation: |
| 486 | 449 |
| 487 ui::EventTarget* RootWindow::GetParentTarget() { | 450 ui::EventTarget* RootWindow::GetParentTarget() { |
| 488 return Env::GetInstance(); | 451 return Env::GetInstance(); |
| 489 } | 452 } |
| 490 | 453 |
| 491 //////////////////////////////////////////////////////////////////////////////// | 454 //////////////////////////////////////////////////////////////////////////////// |
| 492 // RootWindow, ui::CompositorDelegate implementation: | 455 // RootWindow, ui::CompositorDelegate implementation: |
| 493 | 456 |
| 494 void RootWindow::ScheduleDraw() { | 457 void RootWindow::ScheduleDraw() { |
| 495 if (compositor_lock_) { | 458 if (!defer_draw_scheduling_) { |
| 496 draw_on_compositor_unlock_ = true; | |
| 497 } else if (!defer_draw_scheduling_) { | |
| 498 defer_draw_scheduling_ = true; | 459 defer_draw_scheduling_ = true; |
| 499 MessageLoop::current()->PostTask( | 460 MessageLoop::current()->PostTask( |
| 500 FROM_HERE, | 461 FROM_HERE, |
| 501 base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); | 462 base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); |
| 502 } | 463 } |
| 503 } | 464 } |
| 504 | 465 |
| 505 //////////////////////////////////////////////////////////////////////////////// | 466 //////////////////////////////////////////////////////////////////////////////// |
| 506 // RootWindow, ui::CompositorObserver implementation: | 467 // RootWindow, ui::CompositorObserver implementation: |
| 507 | 468 |
| 508 void RootWindow::OnCompositingDidCommit(ui::Compositor*) { | 469 void RootWindow::OnCompositingDidCommit(ui::Compositor*) { |
| 509 } | 470 } |
| 510 | 471 |
| 511 void RootWindow::OnCompositingWillStart(ui::Compositor*) { | |
| 512 } | |
| 513 | |
| 514 void RootWindow::OnCompositingStarted(ui::Compositor*) { | 472 void RootWindow::OnCompositingStarted(ui::Compositor*) { |
| 515 } | 473 } |
| 516 | 474 |
| 517 void RootWindow::OnCompositingEnded(ui::Compositor*) { | 475 void RootWindow::OnCompositingEnded(ui::Compositor*) { |
| 518 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::Draw", | 476 TRACE_EVENT_ASYNC_END0("ui", "RootWindow::Draw", |
| 519 compositor_->last_ended_frame()); | 477 compositor_->last_ended_frame()); |
| 520 waiting_on_compositing_end_ = false; | 478 waiting_on_compositing_end_ = false; |
| 521 if (draw_on_compositing_end_) { | 479 if (draw_on_compositing_end_) { |
| 522 draw_on_compositing_end_ = false; | 480 draw_on_compositing_end_ = false; |
| 523 | 481 |
| 524 // Call ScheduleDraw() instead of Draw() in order to allow other | 482 // Call ScheduleDraw() instead of Draw() in order to allow other |
| 525 // ui::CompositorObservers to be notified before starting another | 483 // ui::CompositorObservers to be notified before starting another |
| 526 // draw cycle. | 484 // draw cycle. |
| 527 ScheduleDraw(); | 485 ScheduleDraw(); |
| 528 } | 486 } |
| 529 } | 487 } |
| 530 | 488 |
| 531 void RootWindow::OnCompositingAborted(ui::Compositor*) { | 489 void RootWindow::OnCompositingAborted(ui::Compositor*) { |
| 532 } | 490 } |
| 533 | 491 |
| 492 void RootWindow::OnCompositingLockStateChanged(ui::Compositor*) { |
| 493 } |
| 494 |
| 534 //////////////////////////////////////////////////////////////////////////////// | 495 //////////////////////////////////////////////////////////////////////////////// |
| 535 // RootWindow, ui::LayerDelegate implementation: | 496 // RootWindow, ui::LayerDelegate implementation: |
| 536 | 497 |
| 537 void RootWindow::OnDeviceScaleFactorChanged( | 498 void RootWindow::OnDeviceScaleFactorChanged( |
| 538 float device_scale_factor) { | 499 float device_scale_factor) { |
| 539 const bool cursor_is_in_bounds = | 500 const bool cursor_is_in_bounds = |
| 540 GetBoundsInScreen().Contains(Env::GetInstance()->last_mouse_location()); | 501 GetBoundsInScreen().Contains(Env::GetInstance()->last_mouse_location()); |
| 541 bool cursor_visible = false; | 502 bool cursor_visible = false; |
| 542 client::CursorClient* cursor_client = client::GetCursorClient(this); | 503 client::CursorClient* cursor_client = client::GetCursorClient(this); |
| 543 if (cursor_is_in_bounds && cursor_client) { | 504 if (cursor_is_in_bounds && cursor_client) { |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 // currently broken. See/ crbug.com/107931. | 1016 // currently broken. See/ crbug.com/107931. |
| 1056 ui::MouseEvent event(ui::ET_MOUSE_MOVED, | 1017 ui::MouseEvent event(ui::ET_MOUSE_MOVED, |
| 1057 orig_mouse_location, | 1018 orig_mouse_location, |
| 1058 orig_mouse_location, | 1019 orig_mouse_location, |
| 1059 ui::EF_IS_SYNTHESIZED); | 1020 ui::EF_IS_SYNTHESIZED); |
| 1060 event.set_system_location(Env::GetInstance()->last_mouse_location()); | 1021 event.set_system_location(Env::GetInstance()->last_mouse_location()); |
| 1061 OnHostMouseEvent(&event); | 1022 OnHostMouseEvent(&event); |
| 1062 #endif | 1023 #endif |
| 1063 } | 1024 } |
| 1064 | 1025 |
| 1065 void RootWindow::UnlockCompositor() { | |
| 1066 DCHECK(compositor_lock_); | |
| 1067 compositor_lock_ = NULL; | |
| 1068 if (draw_on_compositor_unlock_) { | |
| 1069 draw_on_compositor_unlock_ = false; | |
| 1070 ScheduleDraw(); | |
| 1071 } | |
| 1072 } | |
| 1073 | |
| 1074 } // namespace aura | 1026 } // namespace aura |
| OLD | NEW |