summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-09 23:50:51 +0000
committerpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-09 23:50:51 +0000
commitfe83e217ef9fd73d832e8858ce0fdce8052d99b2 (patch)
treefc3e94df34a0093aac9618fa4cc13f637332141a /ui
parent01fdb8df6bc3fb709bb969b70fbeba3b9a2bad22 (diff)
downloadchromium_src-fe83e217ef9fd73d832e8858ce0fdce8052d99b2.zip
chromium_src-fe83e217ef9fd73d832e8858ce0fdce8052d99b2.tar.gz
chromium_src-fe83e217ef9fd73d832e8858ce0fdce8052d99b2.tar.bz2
1) Adds support for OS level mouse capture lost (eg from a popup)
2) Adds support for capture lost events due to Window::SetCapture BUG=107875 TEST= 1) Make sure that browser does not brash when drag and drop from bookmarks tab and Ctrl-Tab 2) Make sure that bug 105993 does not repro Review URL: https://chromiumcodereview.appspot.com/9228004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121338 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/root_window.cc25
-rw-r--r--ui/aura/root_window.h4
-rw-r--r--ui/aura/root_window_host.h6
-rw-r--r--ui/aura/root_window_host_linux.cc14
-rw-r--r--ui/aura/root_window_host_win.cc25
-rw-r--r--ui/aura/root_window_host_win.h7
-rw-r--r--ui/aura/window_unittest.cc47
-rw-r--r--ui/base/events.h1
8 files changed, 111 insertions, 18 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index f79d4e0..390c00b 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -289,8 +289,10 @@ void RootWindow::OnWindowDestroying(Window* window) {
mouse_pressed_handler_ = NULL;
if (mouse_moved_handler_ == window)
mouse_moved_handler_ = NULL;
- if (capture_window_ == window)
+ if (capture_window_ == window) {
capture_window_ = NULL;
+ host_->ReleaseCapture();
+ }
if (touch_event_handler_ == window)
touch_event_handler_ = NULL;
if (gesture_handler_ == window)
@@ -359,10 +361,11 @@ void RootWindow::SetCapture(Window* window) {
if (capture_window_ == window)
return;
- if (capture_window_ && capture_window_->delegate())
- capture_window_->delegate()->OnCaptureLost();
+ aura::Window* old_capture_window = capture_window_;
capture_window_ = window;
+ HandleMouseCaptureChanged(old_capture_window);
+
if (capture_window_) {
// Make all subsequent mouse events and touch go to the capture window. We
// shouldn't need to send an event here as OnCaptureLost should take care of
@@ -477,6 +480,22 @@ RootWindow::~RootWindow() {
instance_ = NULL;
}
+void RootWindow::HandleMouseCaptureChanged(Window* old_capture_window) {
+ if (capture_window_)
+ host_->SetCapture();
+ else
+ host_->ReleaseCapture();
+
+ if (old_capture_window && old_capture_window->delegate()) {
+ // Send a capture changed event with bogus location data.
+ MouseEvent event(
+ ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(), gfx::Point(), 0);
+ ProcessMouseEvent(old_capture_window, &event);
+
+ old_capture_window->delegate()->OnCaptureLost();
+ }
+}
+
void RootWindow::HandleMouseMoved(const MouseEvent& event, Window* target) {
if (target == mouse_moved_handler_)
return;
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 740b259..3b08c39 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -199,6 +199,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// sending exited and entered events as its value changes.
void HandleMouseMoved(const MouseEvent& event, Window* target);
+ // Called whenever the |capture_window_| changes.
+ // Sends capture changed events to event filters for old capture window.
+ void HandleMouseCaptureChanged(Window* old_capture_window);
+
bool ProcessMouseEvent(Window* target, MouseEvent* event);
bool ProcessKeyEvent(Window* target, KeyEvent* event);
ui::TouchStatus ProcessTouchEvent(Window* target, TouchEvent* event);
diff --git a/ui/aura/root_window_host.h b/ui/aura/root_window_host.h
index 476ba6a..551aaf9 100644
--- a/ui/aura/root_window_host.h
+++ b/ui/aura/root_window_host.h
@@ -58,6 +58,12 @@ class RootWindowHost : public MessageLoop::Dispatcher {
// Returns the location of the RootWindow on native screen.
virtual gfx::Point GetLocationOnNativeScreen() const = 0;
+ // Set the OS capture to the root window.
+ virtual void SetCapture() = 0;
+
+ // Release OS capture of the root window.
+ virtual void ReleaseCapture() = 0;
+
// Sets the currently displayed cursor. Shows the cursor by default.
// If you want to update hidden cursor, should call ShowCursor(false)
// after this function.
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index b234623..2af7ef9 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -291,6 +291,8 @@ class RootWindowHostLinux : public RootWindowHost,
virtual gfx::Size GetSize() const OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
+ virtual void SetCapture() OVERRIDE;
+ virtual void ReleaseCapture() OVERRIDE;
virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE;
virtual void ShowCursor(bool show) OVERRIDE;
virtual gfx::Point QueryMouseLocation() OVERRIDE;
@@ -353,7 +355,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
CWBackPixmap,
&swa);
- long event_mask = ButtonPressMask | ButtonReleaseMask |
+ long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
KeyPressMask | KeyReleaseMask |
EnterWindowMask | LeaveWindowMask |
ExposureMask | VisibilityChangeMask |
@@ -419,6 +421,10 @@ base::MessagePumpDispatcher::DispatchStatus RootWindowHostLinux::Dispatch(
handled = root_window_->DispatchMouseEvent(&mouseev);
break;
}
+ case FocusOut:
+ if (xev->xfocus.mode != NotifyGrab)
+ root_window_->SetCapture(NULL);
+ break;
case ConfigureNotify: {
if (xev->xconfigure.window == x_root_window_) {
root_window_->OnNativeScreenResized(
@@ -590,6 +596,12 @@ gfx::Point RootWindowHostLinux::GetLocationOnNativeScreen() const {
return bounds_.origin();
}
+void RootWindowHostLinux::SetCapture() {
+}
+
+void RootWindowHostLinux::ReleaseCapture() {
+}
+
void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) {
if (cursor == kCursorNone && is_cursor_visible_) {
current_cursor_ = cursor;
diff --git a/ui/aura/root_window_host_win.cc b/ui/aura/root_window_host_win.cc
index 705cf9a..a4f60b6 100644
--- a/ui/aura/root_window_host_win.cc
+++ b/ui/aura/root_window_host_win.cc
@@ -115,6 +115,7 @@ gfx::Size RootWindowHost::GetNativeScreenSize() {
RootWindowHostWin::RootWindowHostWin(const gfx::Rect& bounds)
: root_window_(NULL),
fullscreen_(false),
+ has_capture_(false),
saved_window_style_(0),
saved_window_ex_style_(0) {
Init(NULL, bounds);
@@ -223,6 +224,20 @@ void RootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor) {
::SetCursor(LoadCursor(NULL, cursor_id));
}
+void RootWindowHostWin::SetCapture() {
+ if (!has_capture_) {
+ has_capture_ = true;
+ ::SetCapture(hwnd());
+ }
+}
+
+void RootWindowHostWin::ReleaseCapture() {
+ if (has_capture_) {
+ has_capture_ = false;
+ ::ReleaseCapture();
+ }
+}
+
void RootWindowHostWin::ShowCursor(bool show) {
// NOTIMPLEMENTED();
}
@@ -284,6 +299,16 @@ LRESULT RootWindowHostWin::OnMouseRange(UINT message,
return 0;
}
+LRESULT RootWindowHostWin::OnCaptureChanged(UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ if (has_capture_) {
+ has_capture_ = false;
+ root_window_->SetCapture(NULL);
+ }
+ return 0;
+}
+
void RootWindowHostWin::OnPaint(HDC dc) {
root_window_->Draw();
ValidateRect(hwnd(), NULL);
diff --git a/ui/aura/root_window_host_win.h b/ui/aura/root_window_host_win.h
index b3b4443..3e1edcb 100644
--- a/ui/aura/root_window_host_win.h
+++ b/ui/aura/root_window_host_win.h
@@ -28,6 +28,8 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl {
virtual gfx::Size GetSize() const OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
+ virtual void SetCapture() OVERRIDE;
+ virtual void ReleaseCapture() OVERRIDE;
virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE;
virtual void ShowCursor(bool show) OVERRIDE;
virtual gfx::Point QueryMouseLocation() OVERRIDE;
@@ -42,6 +44,9 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl {
MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
MESSAGE_RANGE_HANDLER_EX(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange)
+ // Mouse capture events.
+ MESSAGE_HANDLER_EX(WM_CAPTURECHANGED, OnCaptureChanged)
+
// Key events.
MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent)
MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent)
@@ -59,12 +64,14 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl {
void OnClose();
LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param);
+ LRESULT OnCaptureChanged(UINT message, WPARAM w_param, LPARAM l_param);
void OnPaint(HDC dc);
void OnSize(UINT param, const CSize& size);
RootWindow* root_window_;
bool fullscreen_;
+ bool has_capture_;
RECT saved_window_rect_;
DWORD saved_window_style_;
DWORD saved_window_ex_style_;
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 78b9142..dbf8367 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -112,20 +112,27 @@ class DestroyOrphanDelegate : public TestWindowDelegate {
// Used in verifying mouse capture.
class CaptureWindowDelegateImpl : public TestWindowDelegate {
public:
- explicit CaptureWindowDelegateImpl()
- : capture_lost_count_(0),
- mouse_event_count_(0),
- touch_event_count_(0) {
+ CaptureWindowDelegateImpl() {
+ ResetCounts();
}
+ void ResetCounts() {
+ capture_changed_event_count_ = 0;
+ capture_lost_count_ = 0;
+ mouse_event_count_ = 0;
+ touch_event_count_ = 0;
+ }
+
+ int capture_changed_event_count() const {
+ return capture_changed_event_count_;
+ }
int capture_lost_count() const { return capture_lost_count_; }
- void set_capture_lost_count(int value) { capture_lost_count_ = value; }
int mouse_event_count() const { return mouse_event_count_; }
- void set_mouse_event_count(int value) { mouse_event_count_ = value; }
int touch_event_count() const { return touch_event_count_; }
- void set_touch_event_count(int value) { touch_event_count_ = value; }
virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE {
+ if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
+ capture_changed_event_count_++;
mouse_event_count_++;
return false;
}
@@ -141,6 +148,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
}
private:
+ int capture_changed_event_count_;
int capture_lost_count_;
int mouse_event_count_;
int touch_event_count_;
@@ -479,29 +487,34 @@ TEST_F(WindowTest, CaptureTests) {
&delegate, 0, gfx::Rect(0, 0, 20, 20), NULL));
EXPECT_FALSE(window->HasCapture());
+ delegate.ResetCounts();
+
// Do a capture.
window->SetCapture();
EXPECT_TRUE(window->HasCapture());
EXPECT_EQ(0, delegate.capture_lost_count());
+ EXPECT_EQ(0, delegate.capture_changed_event_count());
EventGenerator generator(gfx::Point(50, 50));
generator.PressLeftButton();
EXPECT_EQ(1, delegate.mouse_event_count());
generator.ReleaseLeftButton();
EXPECT_EQ(2, delegate.mouse_event_count());
- delegate.set_mouse_event_count(0);
+ delegate.ResetCounts();
TouchEvent touchev(ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 0);
root_window->DispatchTouchEvent(&touchev);
EXPECT_EQ(1, delegate.touch_event_count());
- delegate.set_touch_event_count(0);
+ delegate.ResetCounts();
window->ReleaseCapture();
EXPECT_FALSE(window->HasCapture());
EXPECT_EQ(1, delegate.capture_lost_count());
+ EXPECT_EQ(1, delegate.capture_changed_event_count());
+ EXPECT_EQ(1, delegate.mouse_event_count());
generator.PressLeftButton();
- EXPECT_EQ(0, delegate.mouse_event_count());
+ EXPECT_EQ(1, delegate.mouse_event_count());
root_window->DispatchTouchEvent(&touchev);
EXPECT_EQ(0, delegate.touch_event_count());
@@ -526,21 +539,27 @@ TEST_F(WindowTest, ChangeCaptureWhileMouseDown) {
EXPECT_FALSE(window->HasCapture());
// Do a capture.
+ delegate.ResetCounts();
window->SetCapture();
- delegate.set_mouse_event_count(0);
EXPECT_TRUE(window->HasCapture());
EXPECT_EQ(0, delegate.capture_lost_count());
+ EXPECT_EQ(0, delegate.capture_changed_event_count());
EventGenerator generator(gfx::Point(50, 50));
generator.PressLeftButton();
+ EXPECT_EQ(1, delegate.capture_lost_count());
+ EXPECT_EQ(1, delegate.capture_changed_event_count());
EXPECT_EQ(1, delegate.mouse_event_count());
- delegate.set_mouse_event_count(0);
// Reset the capture.
window->ReleaseCapture();
+ delegate.ResetCounts();
+ delegate2.ResetCounts();
+
w2->SetCapture();
- delegate2.set_mouse_event_count(0);
generator.MoveMouseTo(gfx::Point(40, 40), 2);
- EXPECT_EQ(0, delegate.mouse_event_count());
+ EXPECT_EQ(1, delegate.capture_lost_count());
+ EXPECT_EQ(1, delegate.capture_changed_event_count());
+ EXPECT_EQ(1, delegate.mouse_event_count());
EXPECT_EQ(2, delegate2.mouse_event_count());
}
diff --git a/ui/base/events.h b/ui/base/events.h
index 1028688..0d20256 100644
--- a/ui/base/events.h
+++ b/ui/base/events.h
@@ -32,6 +32,7 @@ enum EventType {
ET_KEY_PRESSED,
ET_KEY_RELEASED,
ET_MOUSEWHEEL,
+ ET_MOUSE_CAPTURE_CHANGED, // Event has no location.
ET_TOUCH_RELEASED,
ET_TOUCH_PRESSED,
ET_TOUCH_MOVED,