| 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 "ash/wm/toplevel_window_event_handler.h" | 5 #include "ash/wm/toplevel_window_event_handler.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/wm/default_window_resizer.h" | 8 #include "ash/wm/default_window_resizer.h" |
| 9 #include "ash/wm/property_util.h" | 9 #include "ash/wm/property_util.h" |
| 10 #include "ash/wm/resize_shadow_controller.h" | 10 #include "ash/wm/resize_shadow_controller.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 // ToplevelWindowEventHandler -------------------------------------------------- | 96 // ToplevelWindowEventHandler -------------------------------------------------- |
| 97 | 97 |
| 98 ToplevelWindowEventHandler::ToplevelWindowEventHandler(aura::Window* owner) | 98 ToplevelWindowEventHandler::ToplevelWindowEventHandler(aura::Window* owner) |
| 99 : in_move_loop_(false), | 99 : in_move_loop_(false), |
| 100 move_cancelled_(false) { | 100 move_cancelled_(false) { |
| 101 aura::client::SetWindowMoveClient(owner, this); | 101 aura::client::SetWindowMoveClient(owner, this); |
| 102 Shell::GetInstance()->display_controller()->AddObserver(this); | 102 Shell::GetInstance()->display_controller()->AddObserver(this); |
| 103 owner->AddPreTargetHandler(this); |
| 104 owner->AddPostTargetHandler(this); |
| 103 } | 105 } |
| 104 | 106 |
| 105 ToplevelWindowEventHandler::~ToplevelWindowEventHandler() { | 107 ToplevelWindowEventHandler::~ToplevelWindowEventHandler() { |
| 106 Shell::GetInstance()->display_controller()->RemoveObserver(this); | 108 Shell::GetInstance()->display_controller()->RemoveObserver(this); |
| 107 } | 109 } |
| 108 | 110 |
| 109 ui::EventResult ToplevelWindowEventHandler::OnKeyEvent(ui::KeyEvent* event) { | 111 ui::EventResult ToplevelWindowEventHandler::OnKeyEvent(ui::KeyEvent* event) { |
| 110 if (window_resizer_.get() && event->type() == ui::ET_KEY_PRESSED && | 112 if (window_resizer_.get() && event->type() == ui::ET_KEY_PRESSED && |
| 111 event->key_code() == ui::VKEY_ESCAPE) { | 113 event->key_code() == ui::VKEY_ESCAPE) { |
| 112 CompleteDrag(DRAG_REVERT, event->flags()); | 114 CompleteDrag(DRAG_REVERT, event->flags()); |
| 113 } | 115 } |
| 114 return ui::ER_UNHANDLED; | 116 return ui::ER_UNHANDLED; |
| 115 } | 117 } |
| 116 | 118 |
| 117 ui::EventResult ToplevelWindowEventHandler::OnMouseEvent( | 119 ui::EventResult ToplevelWindowEventHandler::OnMouseEvent( |
| 118 ui::MouseEvent* event) { | 120 ui::MouseEvent* event) { |
| 119 if ((event->flags() & | 121 if ((event->flags() & |
| 120 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) | 122 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) |
| 121 return ui::ER_UNHANDLED; | 123 return ui::ER_UNHANDLED; |
| 122 | 124 |
| 123 aura::Window* target = static_cast<aura::Window*>(event->target()); | 125 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 124 switch (event->type()) { | 126 switch (event->type()) { |
| 125 case ui::ET_MOUSE_PRESSED: { | 127 case ui::ET_MOUSE_PRESSED: |
| 126 // We also update the current window component here because for the | 128 return HandleMousePressed(target, event); |
| 127 // mouse-drag-release-press case, where the mouse is released and | |
| 128 // pressed without mouse move event. | |
| 129 int component = | |
| 130 target->delegate()->GetNonClientComponent(event->location()); | |
| 131 if ((event->flags() & | |
| 132 (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) == 0 && | |
| 133 WindowResizer::GetBoundsChangeForWindowComponent(component)) { | |
| 134 gfx::Point location_in_parent( | |
| 135 ConvertPointToParent(target, event->location())); | |
| 136 CreateScopedWindowResizer(target, location_in_parent, component); | |
| 137 } else { | |
| 138 window_resizer_.reset(); | |
| 139 } | |
| 140 return WindowResizer::GetBoundsChangeForWindowComponent(component) != 0 ? | |
| 141 ui::ER_CONSUMED : ui::ER_UNHANDLED; | |
| 142 } | |
| 143 case ui::ET_MOUSE_DRAGGED: | 129 case ui::ET_MOUSE_DRAGGED: |
| 144 return HandleDrag(target, event) ? ui::ER_CONSUMED : ui::ER_UNHANDLED; | 130 return HandleDrag(target, event) ? ui::ER_CONSUMED : ui::ER_UNHANDLED; |
| 145 case ui::ET_MOUSE_CAPTURE_CHANGED: | 131 case ui::ET_MOUSE_CAPTURE_CHANGED: |
| 146 case ui::ET_MOUSE_RELEASED: | 132 case ui::ET_MOUSE_RELEASED: |
| 147 CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ? | 133 return HandleMouseReleased(target, event); |
| 148 DRAG_COMPLETE : DRAG_REVERT, | |
| 149 event->flags()); | |
| 150 if (in_move_loop_) { | |
| 151 quit_closure_.Run(); | |
| 152 in_move_loop_ = false; | |
| 153 } | |
| 154 // Completing the drag may result in hiding the window. If this happens | |
| 155 // return true so no other handlers/observers see the event. Otherwise | |
| 156 // they see the event on a hidden window. | |
| 157 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED && | |
| 158 !target->IsVisible()) { | |
| 159 return ui::ER_CONSUMED; | |
| 160 } | |
| 161 break; | |
| 162 case ui::ET_MOUSE_MOVED: | 134 case ui::ET_MOUSE_MOVED: |
| 163 return HandleMouseMoved(target, event) ? | 135 return HandleMouseMoved(target, event); |
| 164 ui::ER_CONSUMED : ui::ER_UNHANDLED; | |
| 165 case ui::ET_MOUSE_EXITED: | 136 case ui::ET_MOUSE_EXITED: |
| 166 return HandleMouseExited(target, event) ? | 137 return HandleMouseExited(target, event); |
| 167 ui::ER_CONSUMED : ui::ER_UNHANDLED; | |
| 168 default: | 138 default: |
| 169 break; | 139 break; |
| 170 } | 140 } |
| 171 return ui::ER_UNHANDLED; | 141 return ui::ER_UNHANDLED; |
| 172 } | 142 } |
| 173 | 143 |
| 174 ui::EventResult ToplevelWindowEventHandler::OnScrollEvent( | 144 ui::EventResult ToplevelWindowEventHandler::OnScrollEvent( |
| 175 ui::ScrollEvent* event) { | 145 ui::ScrollEvent* event) { |
| 176 return ui::ER_UNHANDLED; | 146 return ui::ER_UNHANDLED; |
| 177 } | 147 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 int event_flags) { | 312 int event_flags) { |
| 343 scoped_ptr<ScopedWindowResizer> resizer(window_resizer_.release()); | 313 scoped_ptr<ScopedWindowResizer> resizer(window_resizer_.release()); |
| 344 if (resizer.get()) { | 314 if (resizer.get()) { |
| 345 if (status == DRAG_COMPLETE) | 315 if (status == DRAG_COMPLETE) |
| 346 resizer->resizer()->CompleteDrag(event_flags); | 316 resizer->resizer()->CompleteDrag(event_flags); |
| 347 else | 317 else |
| 348 resizer->resizer()->RevertDrag(); | 318 resizer->resizer()->RevertDrag(); |
| 349 } | 319 } |
| 350 } | 320 } |
| 351 | 321 |
| 352 bool ToplevelWindowEventHandler::HandleDrag(aura::Window* target, | 322 ui::EventResult ToplevelWindowEventHandler::HandleMousePressed( |
| 353 ui::LocatedEvent* event) { | 323 aura::Window* target, |
| 324 ui::MouseEvent* event) { |
| 325 |
| 326 // Move/size operations are initiated post-target handling to give the target |
| 327 // an opportunity to cancel this default behavior by returning ER_HANDLED. |
| 328 if (ui::EventCanceledDefaultHandling(*event)) |
| 329 return ui::ER_UNHANDLED; |
| 330 |
| 331 // We also update the current window component here because for the |
| 332 // mouse-drag-release-press case, where the mouse is released and |
| 333 // pressed without mouse move event. |
| 334 int component = |
| 335 target->delegate()->GetNonClientComponent(event->location()); |
| 336 if ((event->flags() & |
| 337 (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) == 0 && |
| 338 WindowResizer::GetBoundsChangeForWindowComponent(component)) { |
| 339 gfx::Point location_in_parent( |
| 340 ConvertPointToParent(target, event->location())); |
| 341 CreateScopedWindowResizer(target, location_in_parent, component); |
| 342 } else { |
| 343 window_resizer_.reset(); |
| 344 } |
| 345 return WindowResizer::GetBoundsChangeForWindowComponent(component) != 0 ? |
| 346 ui::ER_CONSUMED : ui::ER_UNHANDLED; |
| 347 } |
| 348 |
| 349 ui::EventResult ToplevelWindowEventHandler::HandleMouseReleased( |
| 350 aura::Window* target, |
| 351 ui::MouseEvent* event) { |
| 352 if (event->phase() != ui::EP_PRETARGET) |
| 353 return ui::ER_UNHANDLED; |
| 354 |
| 355 CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ? |
| 356 DRAG_COMPLETE : DRAG_REVERT, |
| 357 event->flags()); |
| 358 if (in_move_loop_) { |
| 359 quit_closure_.Run(); |
| 360 in_move_loop_ = false; |
| 361 } |
| 362 // Completing the drag may result in hiding the window. If this happens |
| 363 // return true so no other handlers/observers see the event. Otherwise |
| 364 // they see the event on a hidden window. |
| 365 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED && |
| 366 !target->IsVisible()) { |
| 367 return ui::ER_CONSUMED; |
| 368 } |
| 369 return ui::ER_UNHANDLED; |
| 370 } |
| 371 |
| 372 ui::EventResult ToplevelWindowEventHandler::HandleDrag( |
| 373 aura::Window* target, |
| 374 ui::LocatedEvent* event) { |
| 354 // This function only be triggered to move window | 375 // This function only be triggered to move window |
| 355 // by mouse drag or touch move event. | 376 // by mouse drag or touch move event. |
| 356 DCHECK(event->type() == ui::ET_MOUSE_DRAGGED || | 377 DCHECK(event->type() == ui::ET_MOUSE_DRAGGED || |
| 357 event->type() == ui::ET_TOUCH_MOVED || | 378 event->type() == ui::ET_TOUCH_MOVED || |
| 358 event->type() == ui::ET_GESTURE_SCROLL_UPDATE); | 379 event->type() == ui::ET_GESTURE_SCROLL_UPDATE); |
| 359 | 380 |
| 381 // Drag actions are performed pre-target handling to prevent spurious mouse |
| 382 // moves from the move/size operation from being sent to the target. |
| 383 if (event->phase() != ui::EP_PRETARGET) |
| 384 return ui::ER_UNHANDLED; |
| 385 |
| 360 if (!window_resizer_.get()) | 386 if (!window_resizer_.get()) |
| 361 return false; | 387 return ui::ER_UNHANDLED; |
| 362 window_resizer_->resizer()->Drag( | 388 window_resizer_->resizer()->Drag( |
| 363 ConvertPointToParent(target, event->location()), event->flags()); | 389 ConvertPointToParent(target, event->location()), event->flags()); |
| 364 return true; | 390 return ui::ER_CONSUMED; |
| 365 } | 391 } |
| 366 | 392 |
| 367 bool ToplevelWindowEventHandler::HandleMouseMoved(aura::Window* target, | 393 ui::EventResult ToplevelWindowEventHandler::HandleMouseMoved( |
| 368 ui::LocatedEvent* event) { | 394 aura::Window* target, |
| 395 ui::LocatedEvent* event) { |
| 396 // Shadow effects are applied after target handling. Note that we don't |
| 397 // respect ER_HANDLED here right now since we have not had a reason to allow |
| 398 // the target to cancel shadow rendering. |
| 399 if (event->phase() != ui::EP_POSTTARGET) |
| 400 return ui::ER_UNHANDLED; |
| 401 |
| 369 // TODO(jamescook): Move the resize cursor update code into here from | 402 // TODO(jamescook): Move the resize cursor update code into here from |
| 370 // CompoundEventFilter? | 403 // CompoundEventFilter? |
| 371 internal::ResizeShadowController* controller = | 404 internal::ResizeShadowController* controller = |
| 372 Shell::GetInstance()->resize_shadow_controller(); | 405 Shell::GetInstance()->resize_shadow_controller(); |
| 373 if (controller) { | 406 if (controller) { |
| 374 if (event->flags() & ui::EF_IS_NON_CLIENT) { | 407 if (event->flags() & ui::EF_IS_NON_CLIENT) { |
| 375 int component = | 408 int component = |
| 376 target->delegate()->GetNonClientComponent(event->location()); | 409 target->delegate()->GetNonClientComponent(event->location()); |
| 377 controller->ShowShadow(target, component); | 410 controller->ShowShadow(target, component); |
| 378 } else { | 411 } else { |
| 379 controller->HideShadow(target); | 412 controller->HideShadow(target); |
| 380 } | 413 } |
| 381 } | 414 } |
| 382 return false; | 415 return ui::ER_UNHANDLED; |
| 383 } | 416 } |
| 384 | 417 |
| 385 bool ToplevelWindowEventHandler::HandleMouseExited(aura::Window* target, | 418 ui::EventResult ToplevelWindowEventHandler::HandleMouseExited( |
| 386 ui::LocatedEvent* event) { | 419 aura::Window* target, |
| 420 ui::LocatedEvent* event) { |
| 421 // Shadow effects are applied after target handling. Note that we don't |
| 422 // respect ER_HANDLED here right now since we have not had a reason to allow |
| 423 // the target to cancel shadow rendering. |
| 424 if (event->phase() != ui::EP_POSTTARGET) |
| 425 return ui::ER_UNHANDLED; |
| 426 |
| 387 internal::ResizeShadowController* controller = | 427 internal::ResizeShadowController* controller = |
| 388 Shell::GetInstance()->resize_shadow_controller(); | 428 Shell::GetInstance()->resize_shadow_controller(); |
| 389 if (controller) | 429 if (controller) |
| 390 controller->HideShadow(target); | 430 controller->HideShadow(target); |
| 391 return false; | 431 return ui::ER_UNHANDLED; |
| 392 } | 432 } |
| 393 | 433 |
| 394 void ToplevelWindowEventHandler::ResizerWindowDestroyed() { | 434 void ToplevelWindowEventHandler::ResizerWindowDestroyed() { |
| 395 // We explicitly don't invoke RevertDrag() since that may do things to window. | 435 // We explicitly don't invoke RevertDrag() since that may do things to window. |
| 396 // Instead we destroy the resizer. | 436 // Instead we destroy the resizer. |
| 397 window_resizer_.reset(); | 437 window_resizer_.reset(); |
| 398 | 438 |
| 399 // End the move loop. This does nothing if we're not in a move loop. | 439 // End the move loop. This does nothing if we're not in a move loop. |
| 400 EndMoveLoop(); | 440 EndMoveLoop(); |
| 401 } | 441 } |
| 402 | 442 |
| 403 } // namespace ash | 443 } // namespace ash |
| OLD | NEW |