diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 23:50:51 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 23:50:51 +0000 |
commit | fe83e217ef9fd73d832e8858ce0fdce8052d99b2 (patch) | |
tree | fc3e94df34a0093aac9618fa4cc13f637332141a /ui | |
parent | 01fdb8df6bc3fb709bb969b70fbeba3b9a2bad22 (diff) | |
download | chromium_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.cc | 25 | ||||
-rw-r--r-- | ui/aura/root_window.h | 4 | ||||
-rw-r--r-- | ui/aura/root_window_host.h | 6 | ||||
-rw-r--r-- | ui/aura/root_window_host_linux.cc | 14 | ||||
-rw-r--r-- | ui/aura/root_window_host_win.cc | 25 | ||||
-rw-r--r-- | ui/aura/root_window_host_win.h | 7 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 47 | ||||
-rw-r--r-- | ui/base/events.h | 1 |
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, |