diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-17 16:22:00 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-17 16:22:00 +0000 |
commit | 83926efa82ad28cac5766154d6dbb37bdb7473bd (patch) | |
tree | 3739db259d1f0a4c4d3dc1151877d4715bbfc092 | |
parent | 30c55372215faa0d58b6f52896b2dadb0f6b1f0c (diff) | |
download | chromium_src-83926efa82ad28cac5766154d6dbb37bdb7473bd.zip chromium_src-83926efa82ad28cac5766154d6dbb37bdb7473bd.tar.gz chromium_src-83926efa82ad28cac5766154d6dbb37bdb7473bd.tar.bz2 |
Adds ability to stop updating the cursor and wires it up when
dragging/moving windows. We need this when resizing along the grid as
it's possible to move outside the drag area so that the cursor would
normally be reset.
BUG=none
TEST=none
R=ben@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9365071
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122519 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/wm/root_window_event_filter.cc | 29 | ||||
-rw-r--r-- | ash/wm/root_window_event_filter.h | 17 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_filter_unittest.cc | 25 | ||||
-rw-r--r-- | ash/wm/window_resizer.cc | 13 | ||||
-rw-r--r-- | ash/wm/window_resizer.h | 6 |
5 files changed, 80 insertions, 10 deletions
diff --git a/ash/wm/root_window_event_filter.cc b/ash/wm/root_window_event_filter.cc index a48fc7f..401798c 100644 --- a/ash/wm/root_window_event_filter.cc +++ b/ash/wm/root_window_event_filter.cc @@ -45,7 +45,10 @@ gfx::NativeCursor CursorForWindowComponent(int window_component) { // RootWindowEventFilter, public: RootWindowEventFilter::RootWindowEventFilter() - : update_cursor_visibility_(true) { + : cursor_lock_count_(0), + did_cursor_change_(false), + cursor_to_set_on_unlock_(0), + update_cursor_visibility_(true) { } RootWindowEventFilter::~RootWindowEventFilter() { @@ -54,6 +57,23 @@ RootWindowEventFilter::~RootWindowEventFilter() { // check_empty == true and will DCHECK failure if it is not empty. } +void RootWindowEventFilter::LockCursor() { + cursor_lock_count_++; +} + +void RootWindowEventFilter::UnlockCursor() { + cursor_lock_count_--; + DCHECK_GE(0, cursor_lock_count_); + if (cursor_lock_count_ == 0) { + if (did_cursor_change_) { + did_cursor_change_ = false; + aura::RootWindow::GetInstance()->SetCursor(cursor_to_set_on_unlock_); + } + did_cursor_change_ = false; + cursor_to_set_on_unlock_ = 0; + } +} + void RootWindowEventFilter::AddFilter(aura::EventFilter* filter) { filters_.AddObserver(filter); } @@ -128,7 +148,12 @@ void RootWindowEventFilter::UpdateCursor(aura::Window* target, target->delegate()->GetNonClientComponent(event->location()); cursor = CursorForWindowComponent(window_component); } - aura::RootWindow::GetInstance()->SetCursor(cursor); + if (cursor_lock_count_ == 0) { + aura::RootWindow::GetInstance()->SetCursor(cursor); + } else { + cursor_to_set_on_unlock_ = cursor; + did_cursor_change_ = true; + } } void RootWindowEventFilter::SetCursorVisible(aura::Window* target, diff --git a/ash/wm/root_window_event_filter.h b/ash/wm/root_window_event_filter.h index 8801f3d..a6a1c76 100644 --- a/ash/wm/root_window_event_filter.h +++ b/ash/wm/root_window_event_filter.h @@ -28,6 +28,12 @@ class ASH_EXPORT RootWindowEventFilter : public aura::EventFilter { RootWindowEventFilter(); virtual ~RootWindowEventFilter(); + // Freezes updates to the cursor until UnlockCursor() is invoked. + void LockCursor(); + + // Unlocks the cursor. + void UnlockCursor(); + void set_update_cursor_visibility(bool update) { update_cursor_visibility_ = update; } @@ -68,6 +74,17 @@ class ASH_EXPORT RootWindowEventFilter : public aura::EventFilter { // Additional event filters that pre-handles events. ObserverList<aura::EventFilter, true> filters_; + // Number of times LockCursor() has been invoked without a corresponding + // UnlockCursor(). + int cursor_lock_count_; + + // Set to true if UpdateCursor() is invoked while |cursor_lock_count_| == 0. + bool did_cursor_change_; + + // Cursor to set once |cursor_lock_count_| is set to 0. Only valid if + // |did_cursor_change_| is true. + gfx::NativeCursor cursor_to_set_on_unlock_; + // Should we show the mouse cursor when we see mouse movement and hide it when // we see a touch event? bool update_cursor_visibility_; diff --git a/ash/wm/toplevel_window_event_filter_unittest.cc b/ash/wm/toplevel_window_event_filter_unittest.cc index b1b19db..79e154d 100644 --- a/ash/wm/toplevel_window_event_filter_unittest.cc +++ b/ash/wm/toplevel_window_event_filter_unittest.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "ash/wm/toplevel_window_event_filter.h" + +#include "ash/test/aura_shell_test_base.h" #include "ash/wm/window_util.h" #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -59,20 +61,26 @@ class TestWindowDelegate : public aura::test::TestWindowDelegate { DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate); }; -class ToplevelWindowEventFilterTest : public aura::test::AuraTestBase { +class ToplevelWindowEventFilterTest : public AuraShellTestBase { public: - ToplevelWindowEventFilterTest() : filter_(NULL) {} + ToplevelWindowEventFilterTest() : filter_(NULL), parent_(NULL) {} virtual ~ToplevelWindowEventFilterTest() {} virtual void SetUp() OVERRIDE { - aura::test::AuraTestBase::SetUp(); - filter_ = new ToplevelWindowEventFilter(aura::RootWindow::GetInstance()); - aura::RootWindow::GetInstance()->SetEventFilter(filter_); + AuraShellTestBase::SetUp(); + parent_ = new aura::Window(NULL); + parent_->Init(ui::Layer::LAYER_NOT_DRAWN); + parent_->Show(); + aura::RootWindow::GetInstance()->AddChild(parent_); + parent_->SetBounds(aura::RootWindow::GetInstance()->bounds()); + filter_ = new ToplevelWindowEventFilter(parent_); + parent_->SetEventFilter(filter_); } virtual void TearDown() OVERRIDE { filter_ = NULL; - aura::test::AuraTestBase::TearDown(); + parent_ = NULL; + AuraShellTestBase::TearDown(); } protected: @@ -81,7 +89,7 @@ class ToplevelWindowEventFilterTest : public aura::test::AuraTestBase { aura::Window* w1 = new aura::Window(d1); w1->set_id(1); w1->Init(ui::Layer::LAYER_TEXTURED); - w1->SetParent(NULL); + w1->SetParent(parent_); w1->SetBounds(gfx::Rect(0, 0, 100, 100)); w1->Show(); return w1; @@ -100,6 +108,9 @@ class ToplevelWindowEventFilterTest : public aura::test::AuraTestBase { ToplevelWindowEventFilter* filter_; private: + // Window |filter_| is installed on. Owned by RootWindow. + aura::Window* parent_; + DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventFilterTest); }; diff --git a/ash/wm/window_resizer.cc b/ash/wm/window_resizer.cc index 3953fb9..9cc1c2a 100644 --- a/ash/wm/window_resizer.cc +++ b/ash/wm/window_resizer.cc @@ -4,7 +4,10 @@ #include "ash/wm/window_resizer.h" +#include "ash/shell.h" +#include "ash/wm/root_window_event_filter.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/root_window.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/base/hit_test.h" @@ -142,10 +145,18 @@ WindowResizer::WindowResizer(aura::Window* window, is_resizable_(bounds_change_ != kBoundsChangeDirection_None && IsNormalWindow(window)), grid_size_(grid_size), - did_move_or_resize_(false) { + did_move_or_resize_(false), + root_filter_(NULL) { + if (is_resizable_) { + root_filter_ = Shell::GetInstance()->root_filter(); + if (root_filter_) + root_filter_->LockCursor(); + } } WindowResizer::~WindowResizer() { + if (root_filter_) + root_filter_->UnlockCursor(); } // static diff --git a/ash/wm/window_resizer.h b/ash/wm/window_resizer.h index daa3426..f44081b 100644 --- a/ash/wm/window_resizer.h +++ b/ash/wm/window_resizer.h @@ -16,6 +16,10 @@ class Window; namespace ash { +namespace internal { +class RootWindowEventFilter; +} + // WindowResizer is used by ToplevelWindowEventFilter to handle dragging, // moving or resizing a window. class ASH_EXPORT WindowResizer { @@ -109,6 +113,8 @@ class ASH_EXPORT WindowResizer { // Set to true once Drag() is invoked and the bounds of the window change. bool did_move_or_resize_; + internal::RootWindowEventFilter* root_filter_; + DISALLOW_COPY_AND_ASSIGN(WindowResizer); }; |