diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-11 20:46:11 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-11 20:46:11 +0000 |
commit | 759017e03abb02554ad06a1745290631c43d7751 (patch) | |
tree | 72e1dba4bff28d67a55401c04e49f992bc857a46 /ui | |
parent | d871f21cb2266670edc0ff636a2d65e4c30b55f7 (diff) | |
download | chromium_src-759017e03abb02554ad06a1745290631c43d7751.zip chromium_src-759017e03abb02554ad06a1745290631c43d7751.tar.gz chromium_src-759017e03abb02554ad06a1745290631c43d7751.tar.bz2 |
1) Invoke RootWindow::SetCapture(NULL) as a result from OS level mouse capture lost (eg from a popup)
2) Invoke OS level SetCapture, ReleaseCapture as a result of setting capture on root window
BUG=107875
TEST=
1) 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@121655 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 | 50 | ||||
-rw-r--r-- | ui/base/events.h | 1 |
8 files changed, 112 insertions, 20 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 742d265..193a50d 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -296,8 +296,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) @@ -366,10 +368,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 @@ -487,6 +490,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 917b0c0..3122b53 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -202,6 +202,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 0459ad9..67655fe 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 18e85f4..372dc3f 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc @@ -116,20 +116,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; } @@ -145,6 +152,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate { } private: + int capture_changed_event_count_; int capture_lost_count_; int mouse_event_count_; int touch_event_count_; @@ -483,29 +491,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()); @@ -530,21 +543,26 @@ 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(0, delegate.capture_lost_count()); + EXPECT_EQ(0, delegate.capture_changed_event_count()); EXPECT_EQ(1, delegate.mouse_event_count()); - delegate.set_mouse_event_count(0); - // Reset the capture. - window->ReleaseCapture(); + // Set capture to |w2|, should implicitly unset capture for |window|. + 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 0989e9f..60620f1 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, |