From c5be8d67a355904dd9e9904b5f5943283a8dfe4f Mon Sep 17 00:00:00 2001
From: "sadrul@chromium.org"
 <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Tue, 7 Jan 2014 13:33:41 +0000
Subject: ash: Use the easy-resize window targeter for some window containers.

BUG=318879
R=ben@chromium.org

Review URL: https://codereview.chromium.org/125333004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243286 0039d316-1c4b-4281-b951-d872f2087c98
---
 ash/root_window_controller.cc           | 17 ++++++++++
 ash/wm/workspace_controller_unittest.cc | 58 +++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

(limited to 'ash')

diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 8332a2a..1af782d 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -67,6 +67,7 @@
 #include "ui/views/corewm/visibility_controller.h"
 #include "ui/views/view_model.h"
 #include "ui/views/view_model_utils.h"
+#include "ui/wm/public/easy_resize_window_targeter.h"
 #include "ui/wm/public/window_types.h"
 
 #if defined(OS_CHROMEOS)
@@ -189,6 +190,18 @@ void DescendantShouldStayInSameRootWindow(aura::Window* container) {
   container->SetProperty(internal::kStayInSameRootWindowKey, true);
 }
 
+void SetUsesEasyResizeTargeter(aura::Window* container) {
+  gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
+                           -kResizeOutsideBoundsSize,
+                           -kResizeOutsideBoundsSize,
+                           -kResizeOutsideBoundsSize);
+  gfx::Insets touch_extend = mouse_extend.Scale(
+      kResizeOutsideBoundsScaleForTouch);
+  container->set_event_targeter(scoped_ptr<ui::EventTargeter>(
+      new ::wm::EasyResizeWindowTargeter(container, mouse_extend,
+                                         touch_extend)));
+}
+
 // A window delegate which does nothing. Used to create a window that
 // is a event target, but do nothing.
 class EmptyWindowDelegate : public aura::WindowDelegate {
@@ -827,6 +840,7 @@ void RootWindowController::CreateContainersInRootWindow(
       non_lock_screen_containers);
   views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
   SetUsesScreenCoordinates(default_container);
+  SetUsesEasyResizeTargeter(default_container);
 
   aura::Window* always_on_top_container = CreateContainer(
       kShellWindowId_AlwaysOnTopContainer,
@@ -857,6 +871,7 @@ void RootWindowController::CreateContainersInRootWindow(
       "PanelContainer",
       non_lock_screen_containers);
   SetUsesScreenCoordinates(panel_container);
+  SetUsesEasyResizeTargeter(panel_container);
 
   aura::Window* shelf_bubble_container =
       CreateContainer(kShellWindowId_ShelfBubbleContainer,
@@ -881,6 +896,7 @@ void RootWindowController::CreateContainersInRootWindow(
       new SystemModalContainerLayoutManager(modal_container));
   views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
   SetUsesScreenCoordinates(modal_container);
+  SetUsesEasyResizeTargeter(modal_container);
 
   aura::Window* input_method_container = CreateContainer(
       kShellWindowId_InputMethodContainer,
@@ -911,6 +927,7 @@ void RootWindowController::CreateContainersInRootWindow(
       new SystemModalContainerLayoutManager(lock_modal_container));
   views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
   SetUsesScreenCoordinates(lock_modal_container);
+  SetUsesEasyResizeTargeter(lock_modal_container);
 
   aura::Window* status_container =
       CreateContainer(kShellWindowId_StatusContainer,
diff --git a/ash/wm/workspace_controller_unittest.cc b/ash/wm/workspace_controller_unittest.cc
index f1aa39e..4b5fd926 100644
--- a/ash/wm/workspace_controller_unittest.cc
+++ b/ash/wm/workspace_controller_unittest.cc
@@ -30,6 +30,7 @@
 #include "ui/base/ui_base_types.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/events/event_utils.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/corewm/window_animations.h"
 #include "ui/views/widget/widget.h"
@@ -1300,5 +1301,62 @@ TEST_P(WorkspaceControllerTestDragging, DragWindowOverlapShelf) {
 INSTANTIATE_TEST_CASE_P(DockedOrNot, WorkspaceControllerTestDragging,
                         ::testing::Bool());
 
+// Verifies that events are targeted properly just outside the window edges.
+TEST_F(WorkspaceControllerTest, WindowEdgeHitTest) {
+  aura::test::TestWindowDelegate d_first, d_second;
+  scoped_ptr<Window> first(aura::test::CreateTestWindowWithDelegate(&d_first,
+      123, gfx::Rect(20, 10, 100, 50), NULL));
+  ParentWindowInPrimaryRootWindow(first.get());
+  first->Show();
+
+  scoped_ptr<Window> second(aura::test::CreateTestWindowWithDelegate(&d_second,
+      234, gfx::Rect(30, 40, 40, 10), NULL));
+  ParentWindowInPrimaryRootWindow(second.get());
+  second->Show();
+
+  ui::EventTarget* root = first->GetRootWindow();
+  ui::EventTargeter* targeter = root->GetEventTargeter();
+
+  // The windows overlap, and |second| is on top of |first|. Events targetted
+  // slightly outside the edges of the |second| window should still be targetted
+  // to |second| to allow resizing the windows easily.
+
+  const int kNumPoints = 4;
+  struct {
+    const char *direction;
+    gfx::Point location;
+  } points[kNumPoints] = {
+    { "left", gfx::Point(28, 45) },  // outside the left edge.
+    { "top", gfx::Point(50, 38) },  // outside the top edge.
+    { "right", gfx::Point(72, 45) },  // outside the right edge.
+    { "bottom", gfx::Point(50, 52) },  // outside the bottom edge.
+  };
+  // Do two iterations, first without any transform on |second|, and the second
+  // time after applying some transform on |second| so that it doesn't get
+  // targetted.
+  for (int times = 0; times < 2; ++times) {
+    SCOPED_TRACE(times == 0 ? "Without transform" : "With transform");
+    aura::Window* expected_target = times == 0 ? second.get() : first.get();
+    for (int i = 0; i < kNumPoints; ++i) {
+      SCOPED_TRACE(points[i].direction);
+      const gfx::Point& location = points[i].location;
+      ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, location, location, ui::EF_NONE,
+                           ui::EF_NONE);
+      ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
+      EXPECT_EQ(expected_target, target);
+
+      ui::TouchEvent touch(ui::ET_TOUCH_PRESSED, location, 0,
+                           ui::EventTimeForNow());
+      target = targeter->FindTargetForEvent(root, &touch);
+      EXPECT_EQ(expected_target, target);
+    }
+    // Apply a transform on |second|. After the transform is applied, the window
+    // should no longer be targetted.
+    gfx::Transform transform;
+    transform.Translate(70, 40);
+    second->SetTransform(transform);
+  }
+}
+
 }  // namespace internal
 }  // namespace ash
-- 
cgit v1.1