summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-12 22:34:32 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-12 22:34:32 +0000
commitcc34d759e73363b27e3e51647d8dd16d04527238 (patch)
tree760924477ade8080a26bf50621670b504efd53d6 /ash
parent4ae2c36f5aeea53195878ea2ebfee95b133f8385 (diff)
downloadchromium_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.cc6
-rw-r--r--ash/wm/toplevel_window_event_handler.cc134
-rw-r--r--ash/wm/toplevel_window_event_handler.h13
-rw-r--r--ash/wm/workspace/workspace2.cc1
-rw-r--r--ash/wm/workspace/workspace_event_handler.cc6
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) {