diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 04:04:35 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 04:04:35 +0000 |
commit | bbb59f8114092ee4761598966c5ec8c3fb1c9d68 (patch) | |
tree | 02fad3de3ce27f3832caadfd20a45b4c7f78aba8 /ui | |
parent | 2ebf05cb61a5019289a982ba2fd2318debe0d02b (diff) | |
download | chromium_src-bbb59f8114092ee4761598966c5ec8c3fb1c9d68.zip chromium_src-bbb59f8114092ee4761598966c5ec8c3fb1c9d68.tar.gz chromium_src-bbb59f8114092ee4761598966c5ec8c3fb1c9d68.tar.bz2 |
Reland: Ash: Allow resize along 1 pixel edge inside window content
The mocks call for resize handles to function along a single pixel edge inside the window, overlapping the web content. Refactored aura::Window::set_hit_test_bounds_inset() into SetHitTestBoundsOverride() to make hover/click events along that border pass through to the non-client area of the window frames. This also allows windows to be resized when they are flush against the top/left/right edges of the screen.
BUG=117542
TEST=aura_shell_unittests ShelfLayoutManager, manually resize window from left/right/bottom/top edges
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=126539
Reverted: http://src.chromium.org/viewvc/chrome?view=rev&revision=126544
Review URL: https://chromiumcodereview.appspot.com/9694012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126554 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/window.cc | 29 | ||||
-rw-r--r-- | ui/aura/window.h | 16 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 19 | ||||
-rw-r--r-- | ui/oak/oak_aura_window_display.cc | 4 |
4 files changed, 54 insertions, 14 deletions
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 71fedda..206a5c0 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -55,7 +55,8 @@ Window::Window(WindowDelegate* delegate) user_data_(NULL), stops_event_propagation_(false), ignore_events_(false), - hit_test_bounds_inset_(0) { + hit_test_bounds_override_outer_(0), + hit_test_bounds_override_inner_(0) { } Window::~Window() { @@ -372,6 +373,13 @@ void Window::RemoveObserver(WindowObserver* observer) { observers_.RemoveObserver(observer); } +void Window::SetHitTestBoundsOverride(int outer, int inner) { + DCHECK(outer >= 0); + DCHECK(inner >= 0); + hit_test_bounds_override_outer_ = outer; + hit_test_bounds_override_inner_ = inner; +} + bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) { Window* root_window = GetRootWindow(); if (!root_window) @@ -387,8 +395,11 @@ bool Window::ContainsPoint(const gfx::Point& local_point) { } bool Window::HitTest(const gfx::Point& local_point) { + // Expand my bounds for hit testing (override is usually zero but it's + // probably cheaper to do the math every time than to branch). gfx::Rect local_bounds(gfx::Point(), bounds().size()); - local_bounds.Inset(hit_test_bounds_inset_, hit_test_bounds_inset_); + local_bounds.Inset(-hit_test_bounds_override_outer_, + -hit_test_bounds_override_outer_); // TODO(beng): hittest masks. return local_bounds.Contains(local_point); } @@ -616,6 +627,20 @@ Window* Window::GetWindowForPoint(const gfx::Point& local_point, (!for_event_handling && !ContainsPoint(local_point))) return NULL; + // Check if I should claim this event and not pass it to my children because + // the location is inside my hit test override area. For details, see + // SetHitTestBoundsOverride(). + if (for_event_handling && hit_test_bounds_override_inner_ != 0) { + gfx::Rect inset_local_bounds(gfx::Point(), bounds().size()); + inset_local_bounds.Inset(hit_test_bounds_override_inner_, + hit_test_bounds_override_inner_); + // We know we're inside the normal local bounds, so if we're outside the + // inset bounds we must be in the special hit test override area. + DCHECK(HitTest(local_point)); + if (!inset_local_bounds.Contains(local_point)) + return delegate_ ? this : NULL; + } + if (!return_tightest && delegate_) return this; diff --git a/ui/aura/window.h b/ui/aura/window.h index ebd3f13..6f6ea8b 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h @@ -229,11 +229,12 @@ class AURA_EXPORT Window : public ui::LayerDelegate { void set_ignore_events(bool ignore_events) { ignore_events_ = ignore_events; } - // When non-zero insets the window's bounds by |inset| when performing hit - // tests for event handling. Pass a negative value for |inset| to respond to - // events that occur slightly outside a window's bounds. - void set_hit_test_bounds_inset(int inset) { hit_test_bounds_inset_ = inset; } - int hit_test_bounds_inset() const { return hit_test_bounds_inset_; } + // Sets the window to grab hits for an area extending |outer| pixels outside + // its bounds and |inner| pixels inside its bounds (even if that inner region + // overlaps a child window). This can be used to create an invisible non- + // client area, for example if your windows have no visible frames but still + // need to have resize edges. Both |outer| and |inner| must be >= 0. + void SetHitTestBoundsOverride(int outer, int inner); // Returns true if the |point_in_root| in root window's coordinate falls // within this window's bounds. Returns false if the window is detached @@ -440,8 +441,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate { // Makes the window pass all events through to any windows behind it. bool ignore_events_; - // Inset the window bounds by this amount when doing hit testing for events. - int hit_test_bounds_inset_; + // See SetHitTestBoundsOverride(). + int hit_test_bounds_override_outer_; + int hit_test_bounds_override_inner_; ObserverList<WindowObserver> observers_; diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc index ee3aeaf..e4c9def 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc @@ -282,7 +282,7 @@ TEST_F(WindowTest, HitTest) { EXPECT_FALSE(w1.HitTest(gfx::Point(-1, -1))); // We can expand the bounds slightly to track events outside our border. - w1.set_hit_test_bounds_inset(-1); + w1.SetHitTestBoundsOverride(1, 0); EXPECT_TRUE(w1.HitTest(gfx::Point(-1, -1))); EXPECT_FALSE(w1.HitTest(gfx::Point(-2, -2))); @@ -318,6 +318,23 @@ TEST_F(WindowTest, GetEventHandlerForPoint) { EXPECT_EQ(w13.get(), root->GetEventHandlerForPoint(gfx::Point(26, 481))); } +TEST_F(WindowTest, GetEventHandlerForPointWithOverride) { + // If our child is flush to our top-left corner he gets events just inside the + // window edges. + scoped_ptr<Window> parent( + CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 20, 400, 500), NULL)); + scoped_ptr<Window> child( + CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 60, 70), parent.get())); + EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0))); + EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(1, 1))); + + // We can override the hit test bounds of the parent to make the parent grab + // events along that edge. + parent->SetHitTestBoundsOverride(0, 1); + EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0))); + EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(1, 1))); +} + TEST_F(WindowTest, GetTopWindowContainingPoint) { Window* root = root_window(); root->SetBounds(gfx::Rect(0, 0, 300, 300)); diff --git a/ui/oak/oak_aura_window_display.cc b/ui/oak/oak_aura_window_display.cc index 153685a..afaeb70 100644 --- a/ui/oak/oak_aura_window_display.cc +++ b/ui/oak/oak_aura_window_display.cc @@ -33,7 +33,6 @@ ROW_TRANSIENTPARENT, ROW_USERDATA, ROW_STOPSEVENTPROPAGATION, ROW_IGNOREEVENTS, -ROW_HITTESTBOUNDSINSET, ROW_CANFOCUS, ROW_COUNT }; @@ -142,9 +141,6 @@ string16 OakAuraWindowDisplay::GetText(int row, int column_id) { case ROW_IGNOREEVENTS: return PropertyWithBool("Can receive events: ", window_->CanReceiveEvents()); - case ROW_HITTESTBOUNDSINSET: - return PropertyWithInteger("Hit-test bounds inset: ", - window_->hit_test_bounds_inset()); case ROW_CANFOCUS: return PropertyWithBool("Can Focus: ", window_->CanFocus()); default: |