diff options
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/ash_constants.cc | 2 | ||||
-rw-r--r-- | ash/ash_constants.h | 4 | ||||
-rw-r--r-- | ash/wm/custom_frame_view_ash.cc | 2 | ||||
-rw-r--r-- | ash/wm/frame_border_hit_test_controller.cc | 88 | ||||
-rw-r--r-- | ash/wm/immersive_fullscreen_controller.cc | 11 | ||||
-rw-r--r-- | ash/wm/immersive_fullscreen_controller_unittest.cc | 143 | ||||
-rw-r--r-- | ash/wm/resize_handle_window_targeter.cc | 99 | ||||
-rw-r--r-- | ash/wm/resize_handle_window_targeter.h | 56 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc | 25 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/immersive_mode_controller_ash.h | 7 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc | 73 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 3 |
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!': [ |