Caret may fail to blink if a focus handler brings up a modal dialog
authorjhoneycutt@apple.com <jhoneycutt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 May 2010 00:49:01 +0000 (00:49 +0000)
committerjhoneycutt@apple.com <jhoneycutt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 May 2010 00:49:01 +0000 (00:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=38372

Reviewed by Darin Adler.

WebCore:

* manual-tests/onfocus-alert-blinking-caret.html: Added.

* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent):
Moved the call to setCaretBlinkingSuspended() from here...
(WebCore::EventHandler::handleMousePressEvent):
... to here. This makes us suspend caret blinking before dispatching the
mouse down event. If dispatching the mouse down event allows the message
loop to run, we want mouse up events received in that message loop to be
able to resume caret blinking.
(WebCore::EventHandler::lostMouseCapture):
We've lost mouse capture and won't be notified of mouse up events;
resume caret blinking.

* page/EventHandler.h:
Declare lostMouseCapture().

WebKit/win:

* WebView.cpp:
(WebView::handleMouseEvent):
If the message is WM_CANCELMODE, which indicates that we our capturing
of mouse events has been cancelled, tell the EventHandler.
It's possible to re-enter this function if handling a mouse event allows
the message loop to run; moved up the call to setMouseActivated(), so
that if we do re-enter this function, the later mouse event will not be
considered as activating the window.
(WebView::WebViewWndProc):
Handle WM_CANCELMODE by calling handleMouseEvent().

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

WebCore/ChangeLog
WebCore/manual-tests/onfocus-alert-blinking-caret.html [new file with mode: 0644]
WebCore/page/EventHandler.cpp
WebCore/page/EventHandler.h
WebKit/win/ChangeLog
WebKit/win/WebView.cpp

index e2a426a..373cfa6 100644 (file)
@@ -1,3 +1,27 @@
+2010-04-30  Jon Honeycutt  <jhoneycutt@apple.com>
+
+        Caret may fail to blink if a focus handler brings up a modal dialog 
+        https://bugs.webkit.org/show_bug.cgi?id=38372
+
+        Reviewed by Darin Adler.
+
+        * manual-tests/onfocus-alert-blinking-caret.html: Added.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleMousePressEvent):
+        Moved the call to setCaretBlinkingSuspended() from here...
+        (WebCore::EventHandler::handleMousePressEvent):
+        ... to here. This makes us suspend caret blinking before dispatching the
+        mouse down event. If dispatching the mouse down event allows the message
+        loop to run, we want mouse up events received in that message loop to be
+        able to resume caret blinking.
+        (WebCore::EventHandler::lostMouseCapture):
+        We've lost mouse capture and won't be notified of mouse up events;
+        resume caret blinking.
+
+        * page/EventHandler.h:
+        Declare lostMouseCapture().
+
 2010-04-30  Dimitri Glazkov  <dglazkov@chromium.org>
 
         Unreviewed, build fix.
diff --git a/WebCore/manual-tests/onfocus-alert-blinking-caret.html b/WebCore/manual-tests/onfocus-alert-blinking-caret.html
new file mode 100644 (file)
index 0000000..26b9812
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+
+<body>
+Focus the field below, then dismiss the alert. The field should retain the focus,
+and the caret in the field should blink.
+<br>
+<input onfocus="alert('Test');">
+</body>
index 14d567e..3b8f4f6 100644 (file)
@@ -439,7 +439,6 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
 #endif
 
     bool swallowEvent = false;
-    m_frame->selection()->setCaretBlinkingSuspended(true);
     m_mousePressed = true;
     m_beganSelectingText = false;
 
@@ -620,7 +619,12 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
     }
 }
 #endif // ENABLE(DRAG_SUPPORT)
-    
+
+void EventHandler::lostMouseCapture()
+{
+    m_frame->selection()->setCaretBlinkingSuspended(false);
+}
+
 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
 {
     if (eventLoopHandleMouseUp(event))
@@ -1269,6 +1273,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
         }
     }
 
+    m_frame->selection()->setCaretBlinkingSuspended(true);
+
     bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
     m_capturesDragging = !swallowEvent;
 
index c24a08a..c83925c 100644 (file)
@@ -147,6 +147,8 @@ public:
 
     bool mouseMoved(const PlatformMouseEvent&);
 
+    void lostMouseCapture();
+
     bool handleMousePressEvent(const PlatformMouseEvent&);
     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
index 457cd1e..f15eb07 100644 (file)
@@ -1,3 +1,21 @@
+2010-04-30  Jon Honeycutt  <jhoneycutt@apple.com>
+
+        Caret may fail to blink if a focus handler brings up a modal dialog 
+        https://bugs.webkit.org/show_bug.cgi?id=38372
+
+        Reviewed by Darin Adler.
+
+        * WebView.cpp:
+        (WebView::handleMouseEvent):
+        If the message is WM_CANCELMODE, which indicates that we our capturing
+        of mouse events has been cancelled, tell the EventHandler.
+        It's possible to re-enter this function if handling a mouse event allows
+        the message loop to run; moved up the call to setMouseActivated(), so
+        that if we do re-enter this function, the later mouse event will not be
+        considered as activating the window.
+        (WebView::WebViewWndProc):
+        Handle WM_CANCELMODE by calling handleMouseEvent().
+
 2010-04-29  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Dan Bernstein.
index 6abc8b7..f8ffb72 100644 (file)
@@ -1326,12 +1326,19 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
     static MouseButton globalPrevButton;
     static LONG globalPrevMouseDownTime;
 
+    if (message == WM_CANCELMODE) {
+        m_page->mainFrame()->eventHandler()->lostMouseCapture();
+        return true;
+    }
+
     // Create our event.
     // 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);
-   
+
+    setMouseActivated(false);
+
     bool insideThreshold = abs(globalPrevPoint.x() - mouseEvent.pos().x()) < ::GetSystemMetrics(SM_CXDOUBLECLK) &&
                            abs(globalPrevPoint.y() - mouseEvent.pos().y()) < ::GetSystemMetrics(SM_CYDOUBLECLK);
     LONG messageTime = ::GetMessageTime();
@@ -1390,7 +1397,6 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
             ::TrackMouseEvent(m_mouseOutTracker.get());
         }
     }
-    setMouseActivated(false);
     return handled;
 }
 
@@ -2022,6 +2028,7 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
         case WM_MBUTTONUP:
         case WM_RBUTTONUP:
         case WM_MOUSELEAVE:
+        case WM_CANCELMODE:
             if (Frame* coreFrame = core(mainFrameImpl))
                 if (coreFrame->view()->didFirstLayout())
                     handled = webView->handleMouseEvent(message, wParam, lParam);