diff options
-rw-r--r-- | ash/tooltips/tooltip_controller.cc | 1 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_filter.cc | 1 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_aura.cc | 11 | ||||
-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 |
11 files changed, 121 insertions, 24 deletions
diff --git a/ash/tooltips/tooltip_controller.cc b/ash/tooltips/tooltip_controller.cc index 48a4d9b..a999c59 100644 --- a/ash/tooltips/tooltip_controller.cc +++ b/ash/tooltips/tooltip_controller.cc @@ -265,6 +265,7 @@ bool TooltipController::PreHandleMouseEvent(aura::Window* target, case ui::ET_MOUSE_RELEASED: case ui::ET_MOUSE_DRAGGED: case ui::ET_MOUSEWHEEL: + case ui::ET_MOUSE_CAPTURE_CHANGED: // Hide the tooltip for click, release, drag, wheel events. if (tooltip_->IsVisible()) tooltip_->Hide(); diff --git a/ash/wm/toplevel_window_event_filter.cc b/ash/wm/toplevel_window_event_filter.cc index 88f0307..bbeadb2 100644 --- a/ash/wm/toplevel_window_event_filter.cc +++ b/ash/wm/toplevel_window_event_filter.cc @@ -189,6 +189,7 @@ bool ToplevelWindowEventFilter::PreHandleMouseEvent(aura::Window* target, kBoundsChange_None; case ui::ET_MOUSE_DRAGGED: return HandleDrag(target, event); + case ui::ET_MOUSE_CAPTURE_CHANGED: case ui::ET_MOUSE_RELEASED: CompleteDrag(target); if (in_move_loop_) { diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index c311abf..12bcda1 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -68,10 +68,13 @@ void UpdateWebTouchEventAfterDispatch(WebKit::WebTouchEvent* event, } } -bool CanRendererHandleEvent(const base::NativeEvent& native_event) { +bool CanRendererHandleEvent(const aura::MouseEvent* event) { + if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) + return false; + #if defined(OS_WIN) // Renderer cannot handle WM_XBUTTON events. - switch (native_event.message) { + switch (event->native_event().message) { case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDBLCLK: @@ -838,7 +841,7 @@ bool RenderWidgetHostViewAura::OnMouseEvent(aura::MouseEvent* event) { } // Forward event to renderer. - if (CanRendererHandleEvent(event->native_event())) + if (CanRendererHandleEvent(event)) host_->ForwardMouseEvent(mouse_event); } @@ -855,7 +858,7 @@ bool RenderWidgetHostViewAura::OnMouseEvent(aura::MouseEvent* event) { content::MakeWebMouseWheelEvent(static_cast<aura::ScrollEvent*>(event)); if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) host_->ForwardWheelEvent(mouse_wheel_event); - } else if (CanRendererHandleEvent(event->native_event())) { + } else if (CanRendererHandleEvent(event)) { WebKit::WebMouseEvent mouse_event = content::MakeWebMouseEvent(event); ModifyEventMovementAndCoords(&mouse_event); host_->ForwardMouseEvent(mouse_event); 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, |