summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-17 16:22:00 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-17 16:22:00 +0000
commit83926efa82ad28cac5766154d6dbb37bdb7473bd (patch)
tree3739db259d1f0a4c4d3dc1151877d4715bbfc092
parent30c55372215faa0d58b6f52896b2dadb0f6b1f0c (diff)
downloadchromium_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.cc29
-rw-r--r--ash/wm/root_window_event_filter.h17
-rw-r--r--ash/wm/toplevel_window_event_filter_unittest.cc25
-rw-r--r--ash/wm/window_resizer.cc13
-rw-r--r--ash/wm/window_resizer.h6
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);
};