diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-12 22:34:32 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-12 22:34:32 +0000 |
commit | cc34d759e73363b27e3e51647d8dd16d04527238 (patch) | |
tree | 760924477ade8080a26bf50621670b504efd53d6 /ash | |
parent | 4ae2c36f5aeea53195878ea2ebfee95b133f8385 (diff) | |
download | chromium_src-cc34d759e73363b27e3e51647d8dd16d04527238.zip chromium_src-cc34d759e73363b27e3e51647d8dd16d04527238.tar.gz chromium_src-cc34d759e73363b27e3e51647d8dd16d04527238.tar.bz2 |
Change the way the ToplevelEventHandler is hooked up. It is now both a pre- and post-target event handler.
Most drag logic still occurs pre-target, but initiation occurs post-target, and only if the target chose not to cancel default behavior.
This allows us to forward all events to the target and perform window moving D&D after the fact, while consuming spurious events during the drag operation. Useful for Apps V2 frames.
http://crbug.com/147653
R=sky@chromium.org,sadrul@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10911256
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156401 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/root_window_controller.cc | 6 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler.cc | 134 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler.h | 13 | ||||
-rw-r--r-- | ash/wm/workspace/workspace2.cc | 1 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_event_handler.cc | 6 |
5 files changed, 103 insertions, 57 deletions
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index e9aff8b..5bcee4d 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -295,7 +295,6 @@ void RootWindowController::CreateContainersInRootWindow( if (!internal::WorkspaceController::IsWorkspace2Enabled()) { default_container_handler_.reset( new ToplevelWindowEventHandler(default_container)); - default_container->AddPreTargetHandler(default_container_handler_.get()); } SetChildWindowVisibilityChangesAnimated(default_container); SetUsesScreenCoordinates(default_container); @@ -306,8 +305,6 @@ void RootWindowController::CreateContainersInRootWindow( non_lock_screen_containers); always_on_top_container_handler_.reset( new ToplevelWindowEventHandler(always_on_top_container)); - always_on_top_container->AddPreTargetHandler( - always_on_top_container_handler_.get()); SetChildWindowVisibilityChangesAnimated(always_on_top_container); SetUsesScreenCoordinates(always_on_top_container); @@ -333,7 +330,6 @@ void RootWindowController::CreateContainersInRootWindow( non_lock_screen_containers); modal_container_handler_.reset( new ToplevelWindowEventHandler(modal_container)); - modal_container->AddPreTargetHandler(modal_container_handler_.get()); modal_container->SetLayoutManager( new internal::SystemModalContainerLayoutManager(modal_container)); SetChildWindowVisibilityChangesAnimated(modal_container); @@ -362,8 +358,6 @@ void RootWindowController::CreateContainersInRootWindow( lock_screen_containers); lock_modal_container_handler_.reset( new ToplevelWindowEventHandler(lock_modal_container)); - lock_modal_container->AddPreTargetHandler( - lock_modal_container_handler_.get()); lock_modal_container->SetLayoutManager( new internal::SystemModalContainerLayoutManager(lock_modal_container)); SetChildWindowVisibilityChangesAnimated(lock_modal_container); diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index ce4be53..0d0349d 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc @@ -22,6 +22,7 @@ #include "ui/aura/window_observer.h" #include "ui/base/cursor/cursor.h" #include "ui/base/events/event.h" +#include "ui/base/events/event_functions.h" #include "ui/base/gestures/gesture_recognizer.h" #include "ui/base/hit_test.h" #include "ui/base/ui_base_types.h" @@ -100,6 +101,8 @@ ToplevelWindowEventHandler::ToplevelWindowEventHandler(aura::Window* owner) move_cancelled_(false) { aura::client::SetWindowMoveClient(owner, this); Shell::GetInstance()->display_controller()->AddObserver(this); + owner->AddPreTargetHandler(this); + owner->AddPostTargetHandler(this); } ToplevelWindowEventHandler::~ToplevelWindowEventHandler() { @@ -122,49 +125,17 @@ ui::EventResult ToplevelWindowEventHandler::OnMouseEvent( aura::Window* target = static_cast<aura::Window*>(event->target()); switch (event->type()) { - case ui::ET_MOUSE_PRESSED: { - // We also update the current window component here because for the - // mouse-drag-release-press case, where the mouse is released and - // pressed without mouse move event. - int component = - target->delegate()->GetNonClientComponent(event->location()); - if ((event->flags() & - (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) == 0 && - WindowResizer::GetBoundsChangeForWindowComponent(component)) { - gfx::Point location_in_parent( - ConvertPointToParent(target, event->location())); - CreateScopedWindowResizer(target, location_in_parent, component); - } else { - window_resizer_.reset(); - } - return WindowResizer::GetBoundsChangeForWindowComponent(component) != 0 ? - ui::ER_CONSUMED : ui::ER_UNHANDLED; - } + case ui::ET_MOUSE_PRESSED: + return HandleMousePressed(target, event); case ui::ET_MOUSE_DRAGGED: return HandleDrag(target, event) ? ui::ER_CONSUMED : ui::ER_UNHANDLED; case ui::ET_MOUSE_CAPTURE_CHANGED: case ui::ET_MOUSE_RELEASED: - CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ? - DRAG_COMPLETE : DRAG_REVERT, - event->flags()); - if (in_move_loop_) { - quit_closure_.Run(); - in_move_loop_ = false; - } - // Completing the drag may result in hiding the window. If this happens - // return true so no other handlers/observers see the event. Otherwise - // they see the event on a hidden window. - if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED && - !target->IsVisible()) { - return ui::ER_CONSUMED; - } - break; + return HandleMouseReleased(target, event); case ui::ET_MOUSE_MOVED: - return HandleMouseMoved(target, event) ? - ui::ER_CONSUMED : ui::ER_UNHANDLED; + return HandleMouseMoved(target, event); case ui::ET_MOUSE_EXITED: - return HandleMouseExited(target, event) ? - ui::ER_CONSUMED : ui::ER_UNHANDLED; + return HandleMouseExited(target, event); default: break; } @@ -349,23 +320,85 @@ void ToplevelWindowEventHandler::CompleteDrag(DragCompletionStatus status, } } -bool ToplevelWindowEventHandler::HandleDrag(aura::Window* target, - ui::LocatedEvent* event) { +ui::EventResult ToplevelWindowEventHandler::HandleMousePressed( + aura::Window* target, + ui::MouseEvent* event) { + // Move/size operations are initiated post-target handling to give the target + // an opportunity to cancel this default behavior by returning ER_HANDLED. + if (ui::EventCanceledDefaultHandling(*event)) + return ui::ER_UNHANDLED; + + // We also update the current window component here because for the + // mouse-drag-release-press case, where the mouse is released and + // pressed without mouse move event. + int component = + target->delegate()->GetNonClientComponent(event->location()); + if ((event->flags() & + (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) == 0 && + WindowResizer::GetBoundsChangeForWindowComponent(component)) { + gfx::Point location_in_parent( + ConvertPointToParent(target, event->location())); + CreateScopedWindowResizer(target, location_in_parent, component); + } else { + window_resizer_.reset(); + } + return WindowResizer::GetBoundsChangeForWindowComponent(component) != 0 ? + ui::ER_CONSUMED : ui::ER_UNHANDLED; +} + +ui::EventResult ToplevelWindowEventHandler::HandleMouseReleased( + aura::Window* target, + ui::MouseEvent* event) { + if (event->phase() != ui::EP_PRETARGET) + return ui::ER_UNHANDLED; + + CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ? + DRAG_COMPLETE : DRAG_REVERT, + event->flags()); + if (in_move_loop_) { + quit_closure_.Run(); + in_move_loop_ = false; + } + // Completing the drag may result in hiding the window. If this happens + // return true so no other handlers/observers see the event. Otherwise + // they see the event on a hidden window. + if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED && + !target->IsVisible()) { + return ui::ER_CONSUMED; + } + return ui::ER_UNHANDLED; +} + +ui::EventResult ToplevelWindowEventHandler::HandleDrag( + aura::Window* target, + ui::LocatedEvent* event) { // This function only be triggered to move window // by mouse drag or touch move event. DCHECK(event->type() == ui::ET_MOUSE_DRAGGED || event->type() == ui::ET_TOUCH_MOVED || event->type() == ui::ET_GESTURE_SCROLL_UPDATE); + // Drag actions are performed pre-target handling to prevent spurious mouse + // moves from the move/size operation from being sent to the target. + if (event->phase() != ui::EP_PRETARGET) + return ui::ER_UNHANDLED; + if (!window_resizer_.get()) - return false; + return ui::ER_UNHANDLED; window_resizer_->resizer()->Drag( ConvertPointToParent(target, event->location()), event->flags()); - return true; + return ui::ER_CONSUMED; } -bool ToplevelWindowEventHandler::HandleMouseMoved(aura::Window* target, - ui::LocatedEvent* event) { +ui::EventResult ToplevelWindowEventHandler::HandleMouseMoved( + aura::Window* target, + ui::LocatedEvent* event) { + // Shadow effects are applied after target handling. Note that we don't + // respect ER_HANDLED here right now since we have not had a reason to allow + // the target to cancel shadow rendering. + if (event->phase() != ui::EP_POSTTARGET) + return ui::ER_UNHANDLED; + // TODO(jamescook): Move the resize cursor update code into here from // CompoundEventFilter? internal::ResizeShadowController* controller = @@ -379,16 +412,23 @@ bool ToplevelWindowEventHandler::HandleMouseMoved(aura::Window* target, controller->HideShadow(target); } } - return false; + return ui::ER_UNHANDLED; } -bool ToplevelWindowEventHandler::HandleMouseExited(aura::Window* target, - ui::LocatedEvent* event) { +ui::EventResult ToplevelWindowEventHandler::HandleMouseExited( + aura::Window* target, + ui::LocatedEvent* event) { + // Shadow effects are applied after target handling. Note that we don't + // respect ER_HANDLED here right now since we have not had a reason to allow + // the target to cancel shadow rendering. + if (event->phase() != ui::EP_POSTTARGET) + return ui::ER_UNHANDLED; + internal::ResizeShadowController* controller = Shell::GetInstance()->resize_shadow_controller(); if (controller) controller->HideShadow(target); - return false; + return ui::ER_UNHANDLED; } void ToplevelWindowEventHandler::ResizerWindowDestroyed() { diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h index e8025b7..48deaea 100644 --- a/ash/wm/toplevel_window_event_handler.h +++ b/ash/wm/toplevel_window_event_handler.h @@ -74,17 +74,24 @@ class ASH_EXPORT ToplevelWindowEventHandler // Finishes the drag. void CompleteDrag(DragCompletionStatus status, int event_flags); + ui::EventResult HandleMousePressed(aura::Window* target, + ui::MouseEvent* event); + ui::EventResult HandleMouseReleased(aura::Window* target, + ui::MouseEvent* event); + // Called during a drag to resize/position the window. // The return value is returned by OnMouseEvent() above. - bool HandleDrag(aura::Window* target, ui::LocatedEvent* event); + ui::EventResult HandleDrag(aura::Window* target, ui::LocatedEvent* event); // Called during mouse moves to update window resize shadows. // Return value is returned by OnMouseEvent() above. - bool HandleMouseMoved(aura::Window* target, ui::LocatedEvent* event); + ui::EventResult HandleMouseMoved(aura::Window* target, + ui::LocatedEvent* event); // Called for mouse exits to hide window resize shadows. // Return value is returned by OnMouseEvent() above. - bool HandleMouseExited(aura::Window* target, ui::LocatedEvent* event); + ui::EventResult HandleMouseExited(aura::Window* target, + ui::LocatedEvent* event); // Invoked from ScopedWindowResizer if the window is destroyed. void ResizerWindowDestroyed(); diff --git a/ash/wm/workspace/workspace2.cc b/ash/wm/workspace/workspace2.cc index 8e1ac5e..3ecbec1 100644 --- a/ash/wm/workspace/workspace2.cc +++ b/ash/wm/workspace/workspace2.cc @@ -31,7 +31,6 @@ Workspace2::Workspace2(WorkspaceManager2* manager, window_->layer()->SetMasksToBounds(true); window_->Hide(); window_->SetParent(parent); - window_->AddPreTargetHandler(event_handler_.get()); window_->SetProperty(internal::kUsesScreenCoordinatesKey, true); } diff --git a/ash/wm/workspace/workspace_event_handler.cc b/ash/wm/workspace/workspace_event_handler.cc index 4762f5a..8969bb3a 100644 --- a/ash/wm/workspace/workspace_event_handler.cc +++ b/ash/wm/workspace/workspace_event_handler.cc @@ -12,6 +12,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/base/events/event.h" +#include "ui/base/events/event_functions.h" #include "ui/base/hit_test.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/screen.h" @@ -80,6 +81,11 @@ ui::EventResult WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) { case ui::ET_MOUSE_EXITED: break; case ui::ET_MOUSE_PRESSED: { + // Maximize behavior is implemented as post-target handling so the target + // can cancel it. + if (ui::EventCanceledDefaultHandling(*event)) + return ToplevelWindowEventHandler::OnMouseEvent(event); + if (event->flags() & ui::EF_IS_DOUBLE_CLICK && target->delegate()->GetNonClientComponent(event->location()) == HTCAPTION) { |