summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-18 08:52:09 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-18 08:52:09 +0000
commita7a40614447afeb87a2ad5242782e8bfbe7f0340 (patch)
treeb4fc9031a56f549d3dfe8b40e4accb0ce792e867 /ui
parenta3bce33e8c38ef03d9582cf69b02234955b4398d (diff)
downloadchromium_src-a7a40614447afeb87a2ad5242782e8bfbe7f0340.zip
chromium_src-a7a40614447afeb87a2ad5242782e8bfbe7f0340.tar.gz
chromium_src-a7a40614447afeb87a2ad5242782e8bfbe7f0340.tar.bz2
events: Add a few more masked window targeter for Widgets with hit-test masks.
Notable changes: * Add a BubbleWindowTargeter that can be used for bubbles (and use it for tray-bubble and app-list bubble). * Change the wm::MaskedWindowTargeter to fall-back to the default WindowTargeter if setting the mask fails. BUG=318879 R=ben@chromium.org Review URL: https://codereview.chromium.org/132233015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245757 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/app_list/app_list.gyp1
-rw-r--r--ui/app_list/views/app_list_view.cc6
-rw-r--r--ui/keyboard/keyboard_controller.cc3
-rw-r--r--ui/views/bubble/bubble_delegate.h1
-rw-r--r--ui/views/bubble/bubble_window_targeter.cc30
-rw-r--r--ui/views/bubble/bubble_window_targeter.h33
-rw-r--r--ui/views/bubble/bubble_window_targeter_unittest.cc116
-rw-r--r--ui/views/bubble/tray_bubble_view.cc4
-rw-r--r--ui/views/touchui/touch_selection_controller_impl.cc5
-rw-r--r--ui/views/views.gyp4
-rw-r--r--ui/wm/core/masked_window_targeter.cc3
-rw-r--r--ui/wm/public/masked_window_targeter.h4
12 files changed, 203 insertions, 7 deletions
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index 6b070bc..6ddddb7 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -145,6 +145,7 @@
'../events/events.gyp:events',
'../views/controls/webview/webview.gyp:webview',
'../views/views.gyp:views',
+ '../wm/wm.gyp:wm_public',
],
}, { # toolkit_views==0
'sources/': [
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index f712b84..b023847 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -27,6 +27,7 @@
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/bubble/bubble_window_targeter.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
@@ -308,11 +309,14 @@ void AppListView::InitAsBubbleInternal(gfx::NativeView parent,
SetBubbleArrow(arrow);
#if defined(USE_AURA)
- GetWidget()->GetNativeWindow()->layer()->SetMasksToBounds(true);
+ aura::Window* window = GetWidget()->GetNativeWindow();
+ window->layer()->SetMasksToBounds(true);
GetBubbleFrameView()->set_background(new AppListBackground(
GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
app_list_main_view_));
set_background(NULL);
+ window->set_event_targeter(scoped_ptr<ui::EventTargeter>(
+ new views::BubbleWindowTargeter(this)));
#else
set_background(new AppListBackground(
GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 9b0b3d1..15d5208 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -50,11 +50,12 @@ class KeyboardContainerTargeter : public wm::MaskedWindowTargeter {
private:
// wm::MaskedWindowTargeter:
- virtual void GetHitTestMask(aura::Window* window,
+ virtual bool GetHitTestMask(aura::Window* window,
gfx::Path* mask) const OVERRIDE {
gfx::Rect keyboard_bounds = proxy_ ? proxy_->GetKeyboardWindow()->bounds() :
KeyboardBoundsFromWindowBounds(window->bounds());
mask->addRect(RectToSkRect(keyboard_bounds));
+ return true;
}
keyboard::KeyboardControllerProxy* proxy_;
diff --git a/ui/views/bubble/bubble_delegate.h b/ui/views/bubble/bubble_delegate.h
index 4bf8ff6..3a38bf9 100644
--- a/ui/views/bubble/bubble_delegate.h
+++ b/ui/views/bubble/bubble_delegate.h
@@ -158,6 +158,7 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
private:
friend class BubbleBorderDelegate;
+ friend class BubbleWindowTargeter;
FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CreateDelegate);
FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, NonClientHitTest);
diff --git a/ui/views/bubble/bubble_window_targeter.cc b/ui/views/bubble/bubble_window_targeter.cc
new file mode 100644
index 0000000..19e0c85
--- /dev/null
+++ b/ui/views/bubble/bubble_window_targeter.cc
@@ -0,0 +1,30 @@
+// 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 "ui/views/bubble/bubble_window_targeter.h"
+
+#include "ui/aura/window.h"
+#include "ui/gfx/path.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_frame_view.h"
+
+namespace views {
+
+BubbleWindowTargeter::BubbleWindowTargeter(BubbleDelegateView* bubble)
+ : wm::MaskedWindowTargeter(bubble->GetWidget()->GetNativeView()),
+ bubble_(bubble) {
+}
+
+BubbleWindowTargeter::~BubbleWindowTargeter() {
+}
+
+bool BubbleWindowTargeter::GetHitTestMask(aura::Window* window,
+ gfx::Path* mask) const {
+ mask->addRect(
+ gfx::RectToSkRect(bubble_->GetBubbleFrameView()->GetContentsBounds()));
+ return true;
+}
+
+} // namespace views
diff --git a/ui/views/bubble/bubble_window_targeter.h b/ui/views/bubble/bubble_window_targeter.h
new file mode 100644
index 0000000..09a96c7
--- /dev/null
+++ b/ui/views/bubble/bubble_window_targeter.h
@@ -0,0 +1,33 @@
+// 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 "ui/views/views_export.h"
+#include "ui/wm/public/masked_window_targeter.h"
+
+namespace aura {
+class Window;
+}
+
+namespace views {
+class BubbleDelegateView;
+
+// A convenient window-targeter that uses a mask based on the content-bounds of
+// the bubble-frame.
+class VIEWS_EXPORT BubbleWindowTargeter
+ : public NON_EXPORTED_BASE(wm::MaskedWindowTargeter) {
+ public:
+ explicit BubbleWindowTargeter(BubbleDelegateView* bubble);
+ virtual ~BubbleWindowTargeter();
+
+ private:
+ // wm::MaskedWindowTargeter:
+ virtual bool GetHitTestMask(aura::Window* window,
+ gfx::Path* mask) const OVERRIDE;
+
+ views::BubbleDelegateView* bubble_;
+
+ DISALLOW_COPY_AND_ASSIGN(BubbleWindowTargeter);
+};
+
+} // namespace views
diff --git a/ui/views/bubble/bubble_window_targeter_unittest.cc b/ui/views/bubble/bubble_window_targeter_unittest.cc
new file mode 100644
index 0000000..bdd233d
--- /dev/null
+++ b/ui/views/bubble/bubble_window_targeter_unittest.cc
@@ -0,0 +1,116 @@
+// 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 "ui/views/bubble/bubble_window_targeter.h"
+
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/views/bubble/bubble_border.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+
+namespace {
+
+class WidgetOwnsNativeBubble : public BubbleDelegateView {
+ public:
+ WidgetOwnsNativeBubble(View* content, BubbleBorder::Arrow arrow)
+ : BubbleDelegateView(content, arrow) {
+ }
+
+ virtual ~WidgetOwnsNativeBubble() {}
+
+ private:
+ // BubbleDelegateView:
+ virtual void OnBeforeBubbleWidgetInit(Widget::InitParams* params,
+ Widget* widget) const OVERRIDE {
+ params->ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetOwnsNativeBubble);
+};
+
+} // namespace
+
+class BubbleWindowTargeterTest : public ViewsTestBase {
+ public:
+ BubbleWindowTargeterTest()
+ : bubble_delegate_(NULL) {
+ }
+ virtual ~BubbleWindowTargeterTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ ViewsTestBase::SetUp();
+ CreateAnchorWidget();
+ CreateBubbleWidget();
+
+ anchor_widget()->Show();
+ bubble_widget()->Show();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ bubble_delegate_ = NULL;
+ bubble_widget_.reset();
+ anchor_.reset();
+ ViewsTestBase::TearDown();
+ }
+
+ Widget* anchor_widget() { return anchor_.get(); }
+ Widget* bubble_widget() { return bubble_widget_.get(); }
+ BubbleDelegateView* bubble_delegate() { return bubble_delegate_; }
+
+ private:
+ void CreateAnchorWidget() {
+ anchor_.reset(new Widget());
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ anchor_->Init(params);
+ }
+
+ void CreateBubbleWidget() {
+ bubble_delegate_ = new WidgetOwnsNativeBubble(
+ anchor_->GetContentsView(), BubbleBorder::NONE);
+ bubble_delegate_->set_color(SK_ColorGREEN);
+ bubble_widget_.reset(BubbleDelegateView::CreateBubble(bubble_delegate_));
+ }
+
+ scoped_ptr<Widget> anchor_;
+ scoped_ptr<Widget> bubble_widget_;
+ BubbleDelegateView* bubble_delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(BubbleWindowTargeterTest);
+};
+
+TEST_F(BubbleWindowTargeterTest, HitTest) {
+ ui::EventTarget* root = bubble_widget()->GetNativeWindow()->GetRootWindow();
+ ui::EventTargeter* targeter = root->GetEventTargeter();
+ aura::Window* bubble_window = bubble_widget()->GetNativeWindow();
+ gfx::Rect bubble_bounds = bubble_window->GetBoundsInRootWindow();
+
+ {
+ bubble_delegate()->set_margins(gfx::Insets());
+ ui::MouseEvent move1(ui::ET_MOUSE_MOVED, bubble_bounds.origin(),
+ bubble_bounds.origin(), ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(bubble_window, targeter->FindTargetForEvent(root, &move1));
+ }
+ {
+ bubble_delegate()->set_margins(gfx::Insets(20, 20, 20, 20));
+ ui::MouseEvent move1(ui::ET_MOUSE_MOVED, bubble_bounds.origin(),
+ bubble_bounds.origin(), ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(bubble_window, targeter->FindTargetForEvent(root, &move1));
+ }
+
+ bubble_window->set_event_targeter(scoped_ptr<ui::EventTargeter>(
+ new BubbleWindowTargeter(bubble_delegate())));
+ {
+ bubble_delegate()->set_margins(gfx::Insets(20, 20, 20, 20));
+ ui::MouseEvent move1(ui::ET_MOUSE_MOVED, bubble_bounds.origin(),
+ bubble_bounds.origin(), ui::EF_NONE, ui::EF_NONE);
+ EXPECT_NE(bubble_window, targeter->FindTargetForEvent(root, &move1));
+ }
+}
+
+} // namespace views
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc
index 3f947ab..4b67515 100644
--- a/ui/views/bubble/tray_bubble_view.cc
+++ b/ui/views/bubble/tray_bubble_view.cc
@@ -11,6 +11,7 @@
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
+#include "ui/aura/window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer.h"
@@ -22,6 +23,7 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/bubble/bubble_window_targeter.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"
@@ -354,6 +356,8 @@ void TrayBubbleView::InitializeAndShowBubble() {
layer()->parent()->SetMaskLayer(bubble_content_mask_->layer());
GetWidget()->Show();
+ GetWidget()->GetNativeWindow()->set_event_targeter(
+ scoped_ptr<ui::EventTargeter>(new BubbleWindowTargeter(this)));
UpdateBubble();
}
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc
index 11868f6..c87eb82 100644
--- a/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -127,7 +127,7 @@ class TouchHandleWindowTargeter : public wm::MaskedWindowTargeter {
private:
// wm::MaskedWindowTargeter:
- virtual void GetHitTestMask(aura::Window* window,
+ virtual bool GetHitTestMask(aura::Window* window,
gfx::Path* mask) const OVERRIDE;
EditingHandleView* handle_view_;
@@ -300,7 +300,7 @@ TouchHandleWindowTargeter::TouchHandleWindowTargeter(
handle_view_(handle_view) {
}
-void TouchHandleWindowTargeter::GetHitTestMask(aura::Window* window,
+bool TouchHandleWindowTargeter::GetHitTestMask(aura::Window* window,
gfx::Path* mask) const {
const gfx::Rect& selection_rect = handle_view_->selection_rect();
gfx::Size image_size = GetHandleImageSize();
@@ -308,6 +308,7 @@ void TouchHandleWindowTargeter::GetHitTestMask(aura::Window* window,
SkIntToScalar(image_size.width()) + 2 * kSelectionHandleHorizPadding,
SkIntToScalar(selection_rect.height() + image_size.height() +
kSelectionHandleVertPadding));
+ return true;
}
TouchSelectionControllerImpl::TouchSelectionControllerImpl(
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index e0d5f0d..a9d9e617 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -64,6 +64,8 @@
'bubble/bubble_delegate.h',
'bubble/bubble_frame_view.cc',
'bubble/bubble_frame_view.h',
+ 'bubble/bubble_window_targeter.cc',
+ 'bubble/bubble_window_targeter.h',
'bubble/tray_bubble_view.cc',
'bubble/tray_bubble_view.h',
'button_drag_utils.cc',
@@ -726,6 +728,7 @@
'../resources/ui_resources.gyp:ui_test_pak',
'../ui.gyp:ui',
'../ui_unittests.gyp:ui_test_support',
+ '../wm/wm.gyp:wm_public',
'views',
'views_test_support',
],
@@ -739,6 +742,7 @@
'bubble/bubble_border_unittest.cc',
'bubble/bubble_delegate_unittest.cc',
'bubble/bubble_frame_view_unittest.cc',
+ 'bubble/bubble_window_targeter_unittest.cc',
'controls/button/custom_button_unittest.cc',
'controls/button/image_button_unittest.cc',
'controls/button/label_button_unittest.cc',
diff --git a/ui/wm/core/masked_window_targeter.cc b/ui/wm/core/masked_window_targeter.cc
index 3de6140..c6277fb 100644
--- a/ui/wm/core/masked_window_targeter.cc
+++ b/ui/wm/core/masked_window_targeter.cc
@@ -20,7 +20,8 @@ bool MaskedWindowTargeter::EventLocationInsideBounds(
const ui::LocatedEvent& event) const {
if (window == masked_window_) {
gfx::Path mask;
- GetHitTestMask(window, &mask);
+ if (!GetHitTestMask(window, &mask))
+ return WindowTargeter::EventLocationInsideBounds(window, event);
gfx::Size size = window->bounds().size();
SkRegion clip_region;
diff --git a/ui/wm/public/masked_window_targeter.h b/ui/wm/public/masked_window_targeter.h
index edb050f..ad3140d3 100644
--- a/ui/wm/public/masked_window_targeter.h
+++ b/ui/wm/public/masked_window_targeter.h
@@ -20,8 +20,8 @@ class MaskedWindowTargeter : public aura::WindowTargeter {
protected:
// Sets the hit-test mask for |window| in |mask| (in |window|'s local
- // coordinate system).
- virtual void GetHitTestMask(aura::Window* window, gfx::Path* mask) const = 0;
+ // coordinate system). Returns whether a valid mask has been set in |mask|.
+ virtual bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const = 0;
// aura::WindowTargeter:
virtual bool EventLocationInsideBounds(