summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/ash_constants.cc2
-rw-r--r--ash/ash_constants.h4
-rw-r--r--ash/wm/custom_frame_view_ash.cc2
-rw-r--r--ash/wm/frame_border_hit_test_controller.cc88
-rw-r--r--ash/wm/immersive_fullscreen_controller.cc11
-rw-r--r--ash/wm/immersive_fullscreen_controller_unittest.cc143
-rw-r--r--ash/wm/resize_handle_window_targeter.cc99
-rw-r--r--ash/wm/resize_handle_window_targeter.h56
-rw-r--r--chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc25
-rw-r--r--chrome/browser/ui/views/frame/immersive_mode_controller_ash.h7
-rw-r--r--chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc73
-rw-r--r--chrome/chrome_tests.gypi3
13 files changed, 293 insertions, 222 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index b14c275..a8c2e59 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -543,6 +543,8 @@
'wm/partial_screenshot_view.h',
'wm/power_button_controller.cc',
'wm/power_button_controller.h',
+ 'wm/resize_handle_window_targeter.cc',
+ 'wm/resize_handle_window_targeter.h',
'wm/resize_shadow.cc',
'wm/resize_shadow.h',
'wm/resize_shadow_controller.cc',
diff --git a/ash/ash_constants.cc b/ash/ash_constants.cc
index 82501f2..d8551d1 100644
--- a/ash/ash_constants.cc
+++ b/ash/ash_constants.cc
@@ -18,4 +18,6 @@ const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe);
const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
+const int kImmersiveFullscreenTopEdgeInset = 8;
+
} // namespace ash
diff --git a/ash/ash_constants.h b/ash/ash_constants.h
index cad4354..f139032 100644
--- a/ash/ash_constants.h
+++ b/ash/ash_constants.h
@@ -33,6 +33,10 @@ extern const SkColor kChromeOsBootColor;
// The border color of keyboard focus for launcher items and system tray.
extern const SkColor kFocusBorderColor;
+// How many pixels are reserved for touch-events towards the top of an
+// immersive-fullscreen window.
+extern const int kImmersiveFullscreenTopEdgeInset;
+
} // namespace ash
#endif // ASH_ASH_CONSTANTS_H_
diff --git a/ash/wm/custom_frame_view_ash.cc b/ash/wm/custom_frame_view_ash.cc
index 50e9e23..5b8a36c 100644
--- a/ash/wm/custom_frame_view_ash.cc
+++ b/ash/wm/custom_frame_view_ash.cc
@@ -394,7 +394,7 @@ CustomFrameViewAsh::CustomFrameViewAsh(views::Widget* frame)
if (!window_state->HasDelegate()) {
window_state->SetDelegate(scoped_ptr<wm::WindowStateDelegate>(
new CustomFrameViewAshWindowStateDelegate(
- window_state, this)).Pass());
+ window_state, this)));
}
}
diff --git a/ash/wm/frame_border_hit_test_controller.cc b/ash/wm/frame_border_hit_test_controller.cc
index 5504d2a..0b730fb 100644
--- a/ash/wm/frame_border_hit_test_controller.cc
+++ b/ash/wm/frame_border_hit_test_controller.cc
@@ -6,7 +6,7 @@
#include "ash/ash_constants.h"
#include "ash/wm/header_painter.h"
-#include "ash/wm/window_state.h"
+#include "ash/wm/resize_handle_window_targeter.h"
#include "ash/wm/window_state_observer.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
@@ -19,90 +19,6 @@
namespace ash {
-namespace {
-
-// To allow easy resize, the resize handles should slightly overlap the content
-// area of non-maximized and non-fullscreen windows.
-class ResizeHandleWindowTargeter : public wm::WindowStateObserver,
- public aura::WindowObserver,
- public aura::WindowTargeter {
- public:
- explicit ResizeHandleWindowTargeter(aura::Window* window)
- : window_(window) {
- wm::WindowState* window_state = wm::GetWindowState(window_);
- OnWindowShowTypeChanged(window_state, wm::SHOW_TYPE_DEFAULT);
- window_state->AddObserver(this);
- window_->AddObserver(this);
- }
-
- virtual ~ResizeHandleWindowTargeter() {
- if (window_) {
- window_->RemoveObserver(this);
- wm::GetWindowState(window_)->RemoveObserver(this);
- }
- }
-
- private:
- // wm::WindowStateObserver:
- virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
- wm::WindowShowType old_type) OVERRIDE {
- if (window_state->IsMaximizedOrFullscreen()) {
- frame_border_inset_ = gfx::Insets();
- } else {
- frame_border_inset_ = gfx::Insets(kResizeInsideBoundsSize,
- kResizeInsideBoundsSize,
- kResizeInsideBoundsSize,
- kResizeInsideBoundsSize);
- }
- }
-
- // aura::WindowObserver:
- virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
- CHECK_EQ(window_, window);
- wm::GetWindowState(window_)->RemoveObserver(this);
- window_ = NULL;
- }
-
- // aura::WindowTargeter:
- virtual ui::EventTarget* FindTargetForLocatedEvent(
- ui::EventTarget* root,
- ui::LocatedEvent* event) OVERRIDE {
- // If the event falls very close to the inside of the frame border, then
- // target the window itself, so that the window can be resized easily.
- aura::Window* window = static_cast<aura::Window*>(root);
- if (window == window_ && !frame_border_inset_.empty()) {
- gfx::Rect bounds = gfx::Rect(window_->bounds().size());
- bounds.Inset(frame_border_inset_);
- if (!bounds.Contains(event->location()))
- return window_;
- }
- return aura::WindowTargeter::FindTargetForLocatedEvent(root, event);
- }
-
- virtual bool SubtreeShouldBeExploredForEvent(
- ui::EventTarget* target,
- const ui::LocatedEvent& event) OVERRIDE {
- if (target == window_) {
- // Defer to the parent's targeter on whether |window_| should be able to
- // receive the event.
- ui::EventTarget* parent = target->GetParentTarget();
- if (parent) {
- ui::EventTargeter* targeter = parent->GetEventTargeter();
- if (targeter)
- return targeter->SubtreeShouldBeExploredForEvent(target, event);
- }
- }
- return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(target, event);
- }
-
- aura::Window* window_;
- gfx::Insets frame_border_inset_;
-
- DISALLOW_COPY_AND_ASSIGN(ResizeHandleWindowTargeter);
-};
-
-} // namespace
-
FrameBorderHitTestController::FrameBorderHitTestController(views::Widget* frame)
: frame_window_(frame->GetNativeWindow()) {
gfx::Insets mouse_outer_insets(-kResizeOutsideBoundsSize,
@@ -116,7 +32,7 @@ FrameBorderHitTestController::FrameBorderHitTestController(views::Widget* frame)
touch_outer_insets);
frame_window_->set_event_targeter(scoped_ptr<ui::EventTargeter>(
- new ResizeHandleWindowTargeter(frame_window_)));
+ new ResizeHandleWindowTargeter(frame_window_, NULL)));
}
FrameBorderHitTestController::~FrameBorderHitTestController() {
diff --git a/ash/wm/immersive_fullscreen_controller.cc b/ash/wm/immersive_fullscreen_controller.cc
index b31c8b8..92697ed 100644
--- a/ash/wm/immersive_fullscreen_controller.cc
+++ b/ash/wm/immersive_fullscreen_controller.cc
@@ -6,7 +6,9 @@
#include <set>
+#include "ash/ash_constants.h"
#include "ash/shell.h"
+#include "ash/wm/resize_handle_window_targeter.h"
#include "ash/wm/window_state.h"
#include "base/metrics/histogram.h"
#include "ui/aura/client/activation_client.h"
@@ -49,11 +51,6 @@ const int kMouseRevealDelayMs = 200;
// without holding the cursor completely still.
const int kMouseRevealXThresholdPixels = 3;
-// How many pixels a gesture can start away from |top_container_| when in
-// closed state and still be considered near it. This is needed to overcome
-// issues with poor location values near the edge of the display.
-const int kNearTopContainerDistance = 8;
-
// Used to multiply x value of an update in check to determine if gesture is
// vertical. This is used to make sure that gesture is close to vertical instead
// of just more vertical then horizontal.
@@ -258,6 +255,8 @@ void ImmersiveFullscreenController::Init(Delegate* delegate,
top_container_ = top_container;
widget_ = widget;
native_window_ = widget_->GetNativeWindow();
+ native_window_->set_event_targeter(scoped_ptr<ui::EventTargeter>(
+ new ResizeHandleWindowTargeter(native_window_, this)));
}
void ImmersiveFullscreenController::SetEnabled(WindowType window_type,
@@ -901,7 +900,7 @@ bool ImmersiveFullscreenController::ShouldHandleGestureEvent(
// When the top-of-window views are not fully revealed, handle gestures which
// start in the top few pixels of the screen.
gfx::Rect hit_bounds_in_screen(GetDisplayBoundsInScreen(native_window_));
- hit_bounds_in_screen.set_height(kNearTopContainerDistance);
+ hit_bounds_in_screen.set_height(kImmersiveFullscreenTopEdgeInset);
if (hit_bounds_in_screen.Contains(location))
return true;
diff --git a/ash/wm/immersive_fullscreen_controller_unittest.cc b/ash/wm/immersive_fullscreen_controller_unittest.cc
index 3172034..ef0a605 100644
--- a/ash/wm/immersive_fullscreen_controller_unittest.cc
+++ b/ash/wm/immersive_fullscreen_controller_unittest.cc
@@ -15,9 +15,13 @@
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/event_generator.h"
+#include "ui/aura/test/test_event_handler.h"
+#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
+#include "ui/events/event_utils.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
@@ -75,6 +79,21 @@ class MockImmersiveFullscreenControllerDelegate
DISALLOW_COPY_AND_ASSIGN(MockImmersiveFullscreenControllerDelegate);
};
+class ConsumeEventHandler : public aura::test::TestEventHandler {
+ public:
+ ConsumeEventHandler() {}
+ virtual ~ConsumeEventHandler() {}
+
+ private:
+ virtual void OnEvent(ui::Event* event) OVERRIDE {
+ aura::test::TestEventHandler::OnEvent(event);
+ if (event->cancelable())
+ event->SetHandled();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ConsumeEventHandler);
+};
+
} // namespace
/////////////////////////////////////////////////////////////////////////////
@@ -83,21 +102,30 @@ class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
public:
enum Modality {
MODALITY_MOUSE,
- MODALITY_TOUCH,
- MODALITY_GESTURE
+ MODALITY_GESTURE_TAP,
+ MODALITY_GESTURE_SCROLL
};
- ImmersiveFullscreenControllerTest() : widget_(NULL), top_container_(NULL) {}
+ ImmersiveFullscreenControllerTest()
+ : widget_(NULL),
+ top_container_(NULL),
+ content_view_(NULL) {}
virtual ~ImmersiveFullscreenControllerTest() {}
ImmersiveFullscreenController* controller() {
return controller_.get();
}
+ views::NativeViewHost* content_view() {
+ return content_view_;
+ }
+
views::View* top_container() {
return top_container_;
}
+ views::Widget* widget() { return widget_; }
+
aura::Window* window() {
return widget_->GetNativeWindow();
}
@@ -127,9 +155,14 @@ class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
window()->SetProperty(aura::client::kShowStateKey,
ui::SHOW_STATE_FULLSCREEN);
+ gfx::Size window_size = widget_->GetWindowBoundsInScreen().size();
+ content_view_ = new views::NativeViewHost();
+ content_view_->SetBounds(0, 0, window_size.width(), window_size.height());
+ widget_->GetContentsView()->AddChildView(content_view_);
+
top_container_ = new views::View();
top_container_->SetBounds(
- 0, 0, widget_->GetWindowBoundsInScreen().width(), 100);
+ 0, 0, window_size.width(), 100);
top_container_->SetFocusable(true);
widget_->GetContentsView()->AddChildView(top_container_);
@@ -152,7 +185,7 @@ class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
// Attempt to reveal the top-of-window views via |modality|.
// The top-of-window views can only be revealed via mouse hover or a gesture.
void AttemptReveal(Modality modality) {
- ASSERT_NE(modality, MODALITY_TOUCH);
+ ASSERT_NE(modality, MODALITY_GESTURE_TAP);
AttemptRevealStateChange(true, modality);
}
@@ -196,22 +229,25 @@ class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
MoveMouse(event_position.x(), event_position.y());
break;
}
- case MODALITY_TOUCH: {
+ case MODALITY_GESTURE_TAP: {
gfx::Point screen_position = event_position;
views::View::ConvertPointToScreen(top_container_, &screen_position);
-
aura::test::EventGenerator& event_generator(GetEventGenerator());
event_generator.MoveTouch(event_position);
event_generator.PressTouch();
event_generator.ReleaseTouch();
break;
}
- case MODALITY_GESTURE: {
- aura::client::GetCursorClient(CurrentContext())->DisableMouseEvents();
- ImmersiveFullscreenController::SwipeType swipe_type = revealed ?
- ImmersiveFullscreenController::SWIPE_OPEN :
- ImmersiveFullscreenController::SWIPE_CLOSE;
- controller_->UpdateRevealedLocksForSwipe(swipe_type);
+ case MODALITY_GESTURE_SCROLL: {
+ gfx::Point start(0, revealed ? 0 : top_container_->height() - 2);
+ gfx::Vector2d scroll_delta(0, 40);
+ gfx::Point end = revealed ? start + scroll_delta : start - scroll_delta;
+ views::View::ConvertPointToScreen(top_container_, &start);
+ views::View::ConvertPointToScreen(top_container_, &end);
+ aura::test::EventGenerator& event_generator(GetEventGenerator());
+ event_generator.GestureScrollSequence(
+ start, end,
+ base::TimeDelta::FromMilliseconds(30), 1);
break;
}
}
@@ -220,7 +256,8 @@ class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
scoped_ptr<ImmersiveFullscreenController> controller_;
scoped_ptr<MockImmersiveFullscreenControllerDelegate> delegate_;
views::Widget* widget_; // Owned by the native widget.
- views::View* top_container_; // Owned by |root_view_|.
+ views::View* top_container_; // Owned by |widget_|'s root-view.
+ views::NativeViewHost* content_view_; // Owned by |widget_|'s root-view.
DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerTest);
};
@@ -615,7 +652,7 @@ TEST_F(ImmersiveFullscreenControllerTest, DifferentModalityEnterExit) {
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via gesture, end reveal via mouse.
- AttemptReveal(MODALITY_GESTURE);
+ AttemptReveal(MODALITY_GESTURE_SCROLL);
EXPECT_TRUE(controller()->IsRevealed());
MoveMouse(1, 1);
EXPECT_TRUE(controller()->IsRevealed());
@@ -623,21 +660,21 @@ TEST_F(ImmersiveFullscreenControllerTest, DifferentModalityEnterExit) {
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via gesture, end reveal via touch.
- AttemptReveal(MODALITY_GESTURE);
+ AttemptReveal(MODALITY_GESTURE_SCROLL);
EXPECT_TRUE(controller()->IsRevealed());
- AttemptUnreveal(MODALITY_TOUCH);
+ AttemptUnreveal(MODALITY_GESTURE_TAP);
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via mouse, end reveal via gesture.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
- AttemptUnreveal(MODALITY_GESTURE);
+ AttemptUnreveal(MODALITY_GESTURE_SCROLL);
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via mouse, end reveal via touch.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
- AttemptUnreveal(MODALITY_TOUCH);
+ AttemptUnreveal(MODALITY_GESTURE_TAP);
EXPECT_FALSE(controller()->IsRevealed());
}
@@ -652,7 +689,7 @@ TEST_F(ImmersiveFullscreenControllerTest, EndRevealViaGesture) {
AttemptReveal(MODALITY_MOUSE);
top_container()->RequestFocus();
EXPECT_TRUE(controller()->IsRevealed());
- AttemptUnreveal(MODALITY_GESTURE);
+ AttemptUnreveal(MODALITY_GESTURE_SCROLL);
EXPECT_FALSE(controller()->IsRevealed());
// The top-of-window views should no longer have focus. Clearing focus is
@@ -666,12 +703,76 @@ TEST_F(ImmersiveFullscreenControllerTest, EndRevealViaGesture) {
scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
EXPECT_TRUE(controller()->IsRevealed());
- AttemptUnreveal(MODALITY_GESTURE);
+ AttemptUnreveal(MODALITY_GESTURE_SCROLL);
EXPECT_TRUE(controller()->IsRevealed());
lock.reset();
EXPECT_FALSE(controller()->IsRevealed());
}
+// Tests that touch-gesture can be used to reveal the top-of-window views when
+// the child window consumes all events.
+TEST_F(ImmersiveFullscreenControllerTest, RevealViaGestureChildConsumesEvents) {
+ // Enabling initially hides the top views.
+ SetEnabled(true);
+ EXPECT_TRUE(controller()->IsEnabled());
+ EXPECT_FALSE(controller()->IsRevealed());
+
+ aura::test::TestWindowDelegate child_delegate;
+ scoped_ptr<aura::Window> child(
+ CreateTestWindowInShellWithDelegateAndType(&child_delegate,
+ ui::wm::WINDOW_TYPE_CONTROL,
+ 1234,
+ gfx::Rect()));
+ content_view()->Attach(child.get());
+ child->Show();
+
+ ConsumeEventHandler handler;
+ child->AddPreTargetHandler(&handler);
+
+ // Reveal the top views using a touch-scroll gesture. The child window should
+ // not receive the touch events.
+ AttemptReveal(MODALITY_GESTURE_SCROLL);
+ EXPECT_TRUE(controller()->IsRevealed());
+ EXPECT_EQ(0, handler.num_touch_events());
+
+ AttemptUnreveal(MODALITY_GESTURE_TAP);
+ EXPECT_FALSE(controller()->IsRevealed());
+ EXPECT_GT(handler.num_touch_events(), 0);
+ child->RemovePreTargetHandler(&handler);
+}
+
+// Make sure touch events towards the top of the window do not leak through to
+// windows underneath.
+TEST_F(ImmersiveFullscreenControllerTest, EventsDoNotLeakToWindowUnderneath) {
+ gfx::Rect window_bounds = window()->GetBoundsInScreen();
+ aura::test::TestWindowDelegate child_delegate;
+ scoped_ptr<aura::Window> behind(CreateTestWindowInShellWithDelegate(
+ &child_delegate, 1234, window_bounds));
+ behind->Show();
+ behind->SetBounds(window_bounds);
+ widget()->StackAbove(behind.get());
+
+ // Make sure the windows are aligned on top.
+ EXPECT_EQ(behind->GetBoundsInScreen().y(), window()->GetBoundsInScreen().y());
+ int top = behind->GetBoundsInScreen().y();
+
+ ui::TouchEvent touch(ui::ET_TOUCH_MOVED, gfx::Point(10, top), 0,
+ ui::EventTimeForNow());
+ ui::EventTarget* root = window()->GetRootWindow();
+ ui::EventTargeter* targeter = root->GetEventTargeter();
+ EXPECT_EQ(window(), targeter->FindTargetForEvent(root, &touch));
+
+ SetEnabled(true);
+ EXPECT_FALSE(controller()->IsRevealed());
+ // Make sure the windows are still aligned on top.
+ EXPECT_EQ(behind->GetBoundsInScreen().y(), window()->GetBoundsInScreen().y());
+ top = behind->GetBoundsInScreen().y();
+ ui::TouchEvent touch2(ui::ET_TOUCH_MOVED, gfx::Point(10, top), 0,
+ ui::EventTimeForNow());
+ // The event should still be targeted to window().
+ EXPECT_EQ(window(), targeter->FindTargetForEvent(root, &touch2));
+}
+
// Do not test under windows because focus testing is not reliable on
// Windows. (crbug.com/79493)
#if !defined(OS_WIN)
diff --git a/ash/wm/resize_handle_window_targeter.cc b/ash/wm/resize_handle_window_targeter.cc
new file mode 100644
index 0000000..144e0fd
--- /dev/null
+++ b/ash/wm/resize_handle_window_targeter.cc
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/resize_handle_window_targeter.h"
+
+#include "ash/ash_constants.h"
+#include "ash/wm/immersive_fullscreen_controller.h"
+#include "ash/wm/window_state.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+
+ResizeHandleWindowTargeter::ResizeHandleWindowTargeter(
+ aura::Window* window,
+ ImmersiveFullscreenController* controller)
+ : window_(window),
+ immersive_controller_(controller) {
+ wm::WindowState* window_state = wm::GetWindowState(window_);
+ OnWindowShowTypeChanged(window_state, wm::SHOW_TYPE_DEFAULT);
+ window_state->AddObserver(this);
+ window_->AddObserver(this);
+}
+
+ResizeHandleWindowTargeter::~ResizeHandleWindowTargeter() {
+ if (window_) {
+ window_->RemoveObserver(this);
+ wm::GetWindowState(window_)->RemoveObserver(this);
+ }
+}
+
+void ResizeHandleWindowTargeter::OnWindowShowTypeChanged(
+ wm::WindowState* window_state,
+ wm::WindowShowType old_type) {
+ if (window_state->IsMaximizedOrFullscreen()) {
+ frame_border_inset_ = gfx::Insets();
+ } else {
+ frame_border_inset_ = gfx::Insets(kResizeInsideBoundsSize,
+ kResizeInsideBoundsSize,
+ kResizeInsideBoundsSize,
+ kResizeInsideBoundsSize);
+ }
+}
+
+void ResizeHandleWindowTargeter::OnWindowDestroying(aura::Window* window) {
+ CHECK_EQ(window_, window);
+ wm::GetWindowState(window_)->RemoveObserver(this);
+ window_ = NULL;
+}
+
+ui::EventTarget* ResizeHandleWindowTargeter::FindTargetForLocatedEvent(
+ ui::EventTarget* root,
+ ui::LocatedEvent* event) {
+ aura::Window* window = static_cast<aura::Window*>(root);
+ if (window == window_) {
+ gfx::Insets insets;
+ if (immersive_controller_ && immersive_controller_->IsEnabled() &&
+ !immersive_controller_->IsRevealed() &&
+ event->IsTouchEvent()) {
+ // If the window is in immersive fullscreen, and top-of-window views are
+ // not revealed, then touch events towards the top of the window
+ // should not reach the child window so that touch gestures can be used to
+ // reveal the top-of-windows views. This is needed because the child
+ // window may consume touch events and prevent touch-scroll gesture from
+ // being generated.
+ insets = gfx::Insets(kImmersiveFullscreenTopEdgeInset, 0, 0, 0);
+ } else {
+ // If the event falls very close to the inside of the frame border, then
+ // target the window itself, so that the window can be resized easily.
+ insets = frame_border_inset_;
+ }
+
+ if (!insets.empty()) {
+ gfx::Rect bounds = gfx::Rect(window_->bounds().size());
+ bounds.Inset(insets);
+ if (!bounds.Contains(event->location()))
+ return window_;
+ }
+ }
+ return aura::WindowTargeter::FindTargetForLocatedEvent(root, event);
+}
+
+bool ResizeHandleWindowTargeter::SubtreeShouldBeExploredForEvent(
+ ui::EventTarget* target,
+ const ui::LocatedEvent& event) {
+ if (target == window_) {
+ // Defer to the parent's targeter on whether |window_| should be able to
+ // receive the event.
+ ui::EventTarget* parent = target->GetParentTarget();
+ if (parent) {
+ ui::EventTargeter* targeter = parent->GetEventTargeter();
+ if (targeter)
+ return targeter->SubtreeShouldBeExploredForEvent(target, event);
+ }
+ }
+ return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(target, event);
+}
+
+} // namespace ash
diff --git a/ash/wm/resize_handle_window_targeter.h b/ash/wm/resize_handle_window_targeter.h
new file mode 100644
index 0000000..828d2fc
--- /dev/null
+++ b/ash/wm/resize_handle_window_targeter.h
@@ -0,0 +1,56 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_WM_RESIZE_HANDLE_WINDOW_TARGETER_H_
+#define ASH_WM_RESIZE_HANDLE_WINDOW_TARGETER_H_
+
+#include "ash/wm/window_state_observer.h"
+#include "ui/aura/window_observer.h"
+#include "ui/aura/window_targeter.h"
+#include "ui/gfx/geometry/insets.h"
+
+namespace ash {
+
+class ImmersiveFullscreenController;
+
+// To allow easy resize, the resize handles should slightly overlap the content
+// area of non-maximized and non-fullscreen windows. For immersive fullscreen
+// windows, this targeter makes sure that touch-events towards the top of the
+// screen are targeted to the window itself (instead of a child window that may
+// otherwise have been targeted) when the top-of-window views are not revealed.
+class ResizeHandleWindowTargeter : public wm::WindowStateObserver,
+ public aura::WindowObserver,
+ public aura::WindowTargeter {
+ public:
+ ResizeHandleWindowTargeter(aura::Window* window,
+ ImmersiveFullscreenController* immersive);
+ virtual ~ResizeHandleWindowTargeter();
+
+ private:
+ // wm::WindowStateObserver:
+ virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
+ wm::WindowShowType old_type) OVERRIDE;
+ // aura::WindowObserver:
+ virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
+
+ // aura::WindowTargeter:
+ virtual ui::EventTarget* FindTargetForLocatedEvent(
+ ui::EventTarget* root,
+ ui::LocatedEvent* event) OVERRIDE;
+ virtual bool SubtreeShouldBeExploredForEvent(
+ ui::EventTarget* target,
+ const ui::LocatedEvent& event) OVERRIDE;
+
+ // The targeter does not take ownership of |window_| or
+ // |immersive_controller_|.
+ aura::Window* window_;
+ gfx::Insets frame_border_inset_;
+ ImmersiveFullscreenController* immersive_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResizeHandleWindowTargeter);
+};
+
+} // namespace ash
+
+#endif // ASH_WM_RESIZE_HANDLE_WINDOW_TARGETER_H_
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 8880b27b..adb88d4 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -26,12 +26,6 @@ namespace {
// "pop" as the 3-pixel tall "light bar" style tab strip becomes visible.
const int kAnimationOffsetY = 3;
-// The height of the region in pixels at the top edge of the screen in which to
-// steal touch events targetted at the web contents while in immersive
-// fullscreen. This region is used to allow us to get edge gestures even if the
-// web contents consumes all touch events.
-const int kStealTouchEventsFromWebContentsRegionHeightPx = 8;
-
// Converts from ImmersiveModeController::AnimateReveal to
// ash::ImmersiveFullscreenController::AnimateReveal.
ash::ImmersiveFullscreenController::AnimateReveal
@@ -153,21 +147,6 @@ void ImmersiveModeControllerAsh::LayoutBrowserRootView() {
widget->GetRootView()->Layout();
}
-void ImmersiveModeControllerAsh::SetRenderWindowTopInsetsForTouch(
- int top_inset) {
- content::WebContents* contents = browser_view_->GetActiveWebContents();
- if (contents) {
- aura::Window* window = contents->GetView()->GetContentNativeView();
- // |window| is NULL if the renderer crashed.
- if (window) {
- gfx::Insets inset(top_inset, 0, 0, 0);
- window->SetHitTestBoundsOverrideOuter(
- window->hit_test_bounds_override_outer_mouse(),
- inset);
- }
- }
-}
-
bool ImmersiveModeControllerAsh::UpdateTabIndicators() {
bool has_tabstrip = browser_view_->IsBrowserTypeNormal();
if (!IsEnabled() || !has_tabstrip) {
@@ -190,7 +169,6 @@ void ImmersiveModeControllerAsh::OnImmersiveRevealStarted() {
visible_fraction_ = 0;
browser_view_->top_container()->SetPaintToLayer(true);
UpdateTabIndicators();
- SetRenderWindowTopInsetsForTouch(0);
LayoutBrowserRootView();
FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
}
@@ -199,15 +177,12 @@ void ImmersiveModeControllerAsh::OnImmersiveRevealEnded() {
visible_fraction_ = 0;
browser_view_->top_container()->SetPaintToLayer(false);
UpdateTabIndicators();
- SetRenderWindowTopInsetsForTouch(
- kStealTouchEventsFromWebContentsRegionHeightPx);
LayoutBrowserRootView();
}
void ImmersiveModeControllerAsh::OnImmersiveFullscreenExited() {
browser_view_->top_container()->SetPaintToLayer(false);
UpdateTabIndicators();
- SetRenderWindowTopInsetsForTouch(0);
LayoutBrowserRootView();
}
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
index 7f69334..2358a60 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
@@ -50,13 +50,6 @@ class ImmersiveModeControllerAsh
// Updates the browser root view's layout including window caption controls.
void LayoutBrowserRootView();
- // Shrinks or expands the touch hit test by updating insets for the render
- // window depending on if top_inset is positive or negative respectively.
- // Used to ensure that touch events at the top of the screen go to the top
- // container so a slide gesture can be generated when the content window is
- // consuming all touch events sent to it.
- void SetRenderWindowTopInsetsForTouch(int top_inset);
-
// Updates whether the tab strip is painted in a short "light bar" style.
// Returns true if the visibility of the tab indicators has changed.
bool UpdateTabIndicators();
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
deleted file mode 100644
index 41311ca..0000000
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "ui/aura/window.h"
-
-// TODO(jamescook): If immersive mode becomes popular on CrOS, consider porting
-// it to other Aura platforms (win_aura, linux_aura). http://crbug.com/163931
-class ImmersiveModeControllerAshTest : public InProcessBrowserTest {
- public:
- ImmersiveModeControllerAshTest() : browser_view_(NULL), controller_(NULL) {}
- virtual ~ImmersiveModeControllerAshTest() {}
-
- BrowserView* browser_view() { return browser_view_; }
- ImmersiveModeController* controller() { return controller_; }
-
- // content::BrowserTestBase overrides:
- virtual void SetUpOnMainThread() OVERRIDE {
- browser_view_ = static_cast<BrowserView*>(browser()->window());
- controller_ = browser_view_->immersive_mode_controller();
- controller_->SetupForTest();
- }
-
- private:
- BrowserView* browser_view_;
- ImmersiveModeController* controller_;
-
- DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTest);
-};
-
-// Validate top container touch insets are being updated at the correct time in
-// immersive mode.
-IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest,
- ImmersiveTopContainerInsets) {
- content::WebContents* contents = browser_view()->GetActiveWebContents();
- aura::Window* window = contents->GetView()->GetContentNativeView();
-
- // Turning immersive mode on sets positive top touch insets on the render view
- // window.
- chrome::ToggleFullscreenMode(browser());
- ASSERT_TRUE(browser_view()->IsFullscreen());
- ASSERT_TRUE(controller()->IsEnabled());
- ASSERT_FALSE(controller()->IsRevealed());
- EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() > 0);
-
- // Trigger a reveal resets insets as now the touch target for the top
- // container is large enough.
- scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
- ImmersiveModeController::ANIMATE_REVEAL_NO));
- EXPECT_TRUE(controller()->IsRevealed());
- EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() == 0);
-
- // End reveal by moving the mouse off the top-of-window views. We
- // should see the top insets being positive again to allow a bigger touch
- // target.
- lock.reset();
- EXPECT_FALSE(controller()->IsRevealed());
- EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() > 0);
-
- // Disabling immersive mode resets the top touch insets to 0.
- chrome::ToggleFullscreenMode(browser());
- ASSERT_FALSE(browser_view()->IsFullscreen());
- ASSERT_FALSE(controller()->IsEnabled());
- EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() == 0);
-}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index fae7bf4..91858e1 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1467,7 +1467,6 @@
'browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc',
'browser/ui/views/frame/browser_view_browsertest.cc',
'browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc',
- 'browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc',
'browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc',
'browser/ui/views/new_avatar_menu_button_browsertest.cc',
'browser/ui/views/select_file_dialog_extension_browsertest.cc',
@@ -1774,7 +1773,6 @@
'browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc',
'browser/ui/ash/caps_lock_delegate_chromeos_browsertest.cc',
'browser/ui/views/select_file_dialog_extension_browsertest.cc',
- 'browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc',
'test/data/webui/certificate_viewer_dialog_test.js',
'test/data/webui/certificate_viewer_ui_test-inl.h',
],
@@ -1885,7 +1883,6 @@
'browser/ui/ash/shelf_browsertest.cc',
'browser/ui/views/frame/app_non_client_frame_view_ash_browsertest.cc',
'browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc',
- 'browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc',
],
}, { # else: OS != "win"
'sources!': [