<rdar://problem/5071781> window.mouseout events are not sent to window when mouse...
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2007 10:57:15 +0000 (10:57 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2007 10:57:15 +0000 (10:57 +0000)
Reviewed by Maciej.

Hook up the windows mouse tracking logic to allow us to detect the mouse leaving the window.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28646 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/mouseout-on-window-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/mouseout-on-window.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/platform/win/PlatformMouseEventWin.cpp
WebKit/win/ChangeLog
WebKit/win/WebView.cpp
WebKit/win/WebView.h

index a74aaa9..c7d412d 100644 (file)
@@ -1,3 +1,16 @@
+2007-12-12  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Maciej.
+        
+        <rdar://problem/5071781> window.mouseout events are not 
+        sent to window when mouse moves out of window 
+
+        Layout tests to make sure we correctly handle mouse out 
+        on the window object.
+
+        * fast/events/mouseout-on-window-expected.txt: Added.
+        * fast/events/mouseout-on-window.html: Added.
+
 2007-12-11  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Maciej Stachowiak.
diff --git a/LayoutTests/fast/events/mouseout-on-window-expected.txt b/LayoutTests/fast/events/mouseout-on-window-expected.txt
new file mode 100644 (file)
index 0000000..28f1366
--- /dev/null
@@ -0,0 +1,4 @@
+creating digester
+creating digester
+This test ensures that mouse out events are sent to the window.
+PASS: Received mouseout event.
diff --git a/LayoutTests/fast/events/mouseout-on-window.html b/LayoutTests/fast/events/mouseout-on-window.html
new file mode 100644 (file)
index 0000000..8e46a2d
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<head>
+<script>
+addEventListener("mouseout", function(event){ 
+    if (event.clientX < 0 && event.clientY < 0)
+        document.getElementById("target").innerHTML = "PASS: Received mouseout event.";
+}, true);
+
+</script>
+</head>
+<body>
+This test ensures that mouse out events are sent to the window.<br />
+<div id="target">
+FAIL: No mouseout was sent.
+</div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+if (window.eventSender) {
+    // Initial move on windows is used to force the webview to 
+    // initialise the windows mouse event tracker. 
+    eventSender.mouseMoveTo(5, 5);
+    eventSender.mouseMoveTo(-5, -5);
+}
+</script>
+</body>
+</html>
index 1cbf4f7..54f1df1 100644 (file)
@@ -1,3 +1,16 @@
+2007-12-12  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Maciej.
+
+        <rdar://problem/5071781> window.mouseout events are not sent 
+        to window when mouse moves out of window 
+
+        Make PlatformMouseEvent recognise WM_MOUSELEAVE.
+
+        * platform/win/PlatformMouseEventWin.cpp:
+        (WebCore::messageToEventType):
+        (WebCore::PlatformMouseEvent::PlatformMouseEvent):
+
 2007-12-12  Sam Weinig  <sam@webkit.org>
 
         Fix Mac release build.
index c8b41fd..7110b39 100644 (file)
@@ -63,6 +63,7 @@ static MouseEventType messageToEventType(UINT message)
         case WM_MBUTTONUP:
             return MouseEventReleased;
 
+        case WM_MOUSELEAVE:
         case WM_MOUSEMOVE:
             return MouseEventMoved;
 
@@ -103,6 +104,7 @@ PlatformMouseEvent::PlatformMouseEvent(HWND hWnd, UINT message, WPARAM wParam, L
             m_button = MiddleButton;
             break;
         case WM_MOUSEMOVE:
+        case WM_MOUSELEAVE:
             if (wParam & MK_LBUTTON)
                 m_button = LeftButton;
             else if (wParam & MK_MBUTTON)
index 7f46740..c2a9ee6 100644 (file)
@@ -1,3 +1,19 @@
+2007-12-12  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Maciej.
+
+        <rdar://problem/5071781> window.mouseout events are not 
+        sent to window when mouse moves out of window 
+        
+        Hook up the windows mouse tracking logic to allow us to 
+        detect the mouse leaving the window.
+
+        * WebView.cpp:
+        (WebView::close):
+        (WebView::handleMouseEvent):
+        (WebViewWndProc):
+        * WebView.h:
+
 2007-12-12  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Alexey Proskuryakov.
index b18584b..da44567 100644 (file)
@@ -567,6 +567,12 @@ void WebView::close()
     if (frame)
         frame->loader()->detachFromParent();
 
+    if (m_mouseOutTracker) {
+        m_mouseOutTracker->dwFlags = TME_CANCEL;
+        ::TrackMouseEvent(m_mouseOutTracker.get());
+        m_mouseOutTracker.set(0);
+    }
+
     m_page->setGroupName(String());
     setHostWindow(0);
 
@@ -1147,7 +1153,10 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
     static LONG globalPrevMouseDownTime;
 
     // Create our event.
-    PlatformMouseEvent mouseEvent(m_viewWindow, message, wParam, lParam, m_mouseActivated);
+    // On WM_MOUSELEAVE we need to create a mouseout event, so we force the position
+    // of the event to be at (MINSHORT, MINSHORT).
+    LPARAM position = (message == WM_MOUSELEAVE) ? ((MINSHORT << 16) | MINSHORT) : lParam;
+    PlatformMouseEvent mouseEvent(m_viewWindow, message, wParam, position, m_mouseActivated);
    
     bool insideThreshold = abs(globalPrevPoint.x() - mouseEvent.pos().x()) < ::GetSystemMetrics(SM_CXDOUBLECLK) &&
                            abs(globalPrevPoint.y() - mouseEvent.pos().y()) < ::GetSystemMetrics(SM_CYDOUBLECLK);
@@ -1187,11 +1196,24 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
         mouseEvent.setClickCount(globalClickCount);
         m_page->mainFrame()->eventHandler()->handleMouseReleaseEvent(mouseEvent);
         ::ReleaseCapture();
+    } else if (message == WM_MOUSELEAVE && m_mouseOutTracker) {
+        // Once WM_MOUSELEAVE is fired windows clears this tracker
+        // so there is no need to disable it ourselves.
+        m_mouseOutTracker.set(0);
+        m_page->mainFrame()->eventHandler()->mouseMoved(mouseEvent);
+        handled = true;
     } else if (message == WM_MOUSEMOVE) {
         if (!insideThreshold)
             globalClickCount = 0;
         mouseEvent.setClickCount(globalClickCount);
         handled = m_page->mainFrame()->eventHandler()->mouseMoved(mouseEvent);
+        if (!m_mouseOutTracker) {
+            m_mouseOutTracker.set(new TRACKMOUSEEVENT);
+            m_mouseOutTracker->cbSize = sizeof(TRACKMOUSEEVENT);
+            m_mouseOutTracker->dwFlags = TME_LEAVE;
+            m_mouseOutTracker->hwndTrack = m_viewWindow;
+            ::TrackMouseEvent(m_mouseOutTracker.get());
+        }
     }
     setMouseActivated(false);
     return handled;
@@ -1573,6 +1595,7 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
         case WM_LBUTTONUP:
         case WM_MBUTTONUP:
         case WM_RBUTTONUP:
+        case WM_MOUSELEAVE:
             if (Frame* coreFrame = core(mainFrameImpl))
                 if (coreFrame->view()->didFirstLayout())
                     handled = webView->handleMouseEvent(message, wParam, lParam);
index e8b6388..d01213a 100644 (file)
@@ -768,6 +768,7 @@ protected:
     static bool s_allowSiteSpecificHacks;
 
     WebCore::Timer<WebView> m_closeWindowTimer;
+    OwnPtr<TRACKMOUSEEVENT> m_mouseOutTracker;
 };
 
 #endif