Changeset 137539 in webkit


Ignore:
Timestamp:
Dec 12, 2012 5:04:35 PM (11 years ago)
Author:
aestes@apple.com
Message:

Don't dispatch fake mousemove events when we don't know where the cursor is
https://bugs.webkit.org/show_bug.cgi?id=104861

Reviewed by Sam Weinig.

When EventHandler is instantiated or cleared, it sets the current mouse
position to (0, 0), even though this is probably not where the mouse
cursor really is (and we won't know until the mouse moves into the WebView).
If a fake mousemove event fires and the page has an element at (0, 0)
that responds to mousemove, we might end up changing the cursor or
displaying a tooltip at the current mouse position, even if it is
outside the WebView.

Fake mousemove events are dispatched in order to update a cursor that
is already over the WebView. Don't dispatch the event if we don't know
this to be true.

  • page/EventHandler.cpp:

(WebCore::EventHandler::EventHandler): Instantiate m_mousePositionIsUnknown to true.
(WebCore::EventHandler::clear): Reset m_mousePositionIsUnknown to true.
(WebCore::EventHandler::dispatchFakeMouseMoveEventSoon): Return early if the mouse position is unknown.
(WebCore::EventHandler::setLastKnownMousePosition): Set the mouse position from the PlatformMouseEvent and set m_mousePositionIsUnknown to false.
(WebCore::EventHandler::handleMousePressEvent): Call setLastKnownMousePosition() instead of setting the position directly.
(WebCore::EventHandler::handleMouseDoubleClickEvent): Ditto.
(WebCore::EventHandler::handleMouseMoveEvent): Ditto.
(WebCore::EventHandler::handleMouseReleaseEvent): Ditto.
(WebCore::EventHandler::updateSelectionForMouseDrag): Rename currentMouse(Global)Position to lastKnownMouse(Global)Position.
(WebCore::EventHandler::handleAutoscroll): Ditto.
(WebCore::EventHandler::updatePanScrollState): Ditto.
(WebCore::EventHandler::lastKnownMousePosition): Ditto.
(WebCore::EventHandler::dispatchFakeMouseMoveEventSoonInQuad): Ditto.
(WebCore::EventHandler::fakeMouseMoveEventTimerFired): Ditto.
(WebCore::EventHandler::hoverTimerFired): Ditto.

  • page/FrameView.cpp:

(WebCore::FrameView::lastKnownMousePosition): Ditto.

  • platform/ScrollableArea.h:

(WebCore::ScrollableArea::lastKnownMousePosition): Ditto.

  • platform/mac/ScrollAnimatorMac.mm:

(-[WebScrollbarPainterControllerDelegate mouseLocationInContentAreaForScrollerImpPair:]): Ditto.
(-[WebScrollbarPainterDelegate mouseLocationInScrollerForScrollerImp:]): Ditto.

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::panScrollFromPoint): Ditto.
(WebCore::RenderLayer::autoscroll): Ditto.
(WebCore::RenderLayer::lastKnownMousePosition): Ditto.

  • rendering/RenderListBox.cpp:

(WebCore::RenderListBox::panScroll): Ditto.
(WebCore::RenderListBox::autoscroll): Ditto.
(WebCore::RenderListBox::lastKnownMousePosition): Ditto.

Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r137536 r137539  
     12012-12-12  Andy Estes  <aestes@apple.com>
     2
     3        Don't dispatch fake mousemove events when we don't know where the cursor is
     4        https://bugs.webkit.org/show_bug.cgi?id=104861
     5
     6        Reviewed by Sam Weinig.
     7
     8        When EventHandler is instantiated or cleared, it sets the current mouse
     9        position to (0, 0), even though this is probably not where the mouse
     10        cursor really is (and we won't know until the mouse moves into the WebView).
     11        If a fake mousemove event fires and the page has an element at (0, 0)
     12        that responds to mousemove, we might end up changing the cursor or
     13        displaying a tooltip at the current mouse position, even if it is
     14        outside the WebView.
     15
     16        Fake mousemove events are dispatched in order to update a cursor that
     17        is already over the WebView. Don't dispatch the event if we don't know
     18        this to be true.
     19
     20        * page/EventHandler.cpp:
     21        (WebCore::EventHandler::EventHandler): Instantiate m_mousePositionIsUnknown to true.
     22        (WebCore::EventHandler::clear): Reset m_mousePositionIsUnknown to true.
     23        (WebCore::EventHandler::dispatchFakeMouseMoveEventSoon): Return early if the mouse position is unknown.
     24        (WebCore::EventHandler::setLastKnownMousePosition): Set the mouse position from the PlatformMouseEvent and set m_mousePositionIsUnknown to false.
     25        (WebCore::EventHandler::handleMousePressEvent): Call setLastKnownMousePosition() instead of setting the position directly.
     26        (WebCore::EventHandler::handleMouseDoubleClickEvent): Ditto.
     27        (WebCore::EventHandler::handleMouseMoveEvent): Ditto.
     28        (WebCore::EventHandler::handleMouseReleaseEvent): Ditto.
     29        (WebCore::EventHandler::updateSelectionForMouseDrag): Rename currentMouse(Global)Position to lastKnownMouse(Global)Position.
     30        (WebCore::EventHandler::handleAutoscroll): Ditto.
     31        (WebCore::EventHandler::updatePanScrollState): Ditto.
     32        (WebCore::EventHandler::lastKnownMousePosition): Ditto.
     33        (WebCore::EventHandler::dispatchFakeMouseMoveEventSoonInQuad): Ditto.
     34        (WebCore::EventHandler::fakeMouseMoveEventTimerFired): Ditto.
     35        (WebCore::EventHandler::hoverTimerFired): Ditto.
     36        * page/FrameView.cpp:
     37        (WebCore::FrameView::lastKnownMousePosition): Ditto.
     38        * platform/ScrollableArea.h:
     39        (WebCore::ScrollableArea::lastKnownMousePosition): Ditto.
     40        * platform/mac/ScrollAnimatorMac.mm:
     41        (-[WebScrollbarPainterControllerDelegate mouseLocationInContentAreaForScrollerImpPair:]): Ditto.
     42        (-[WebScrollbarPainterDelegate mouseLocationInScrollerForScrollerImp:]): Ditto.
     43        * rendering/RenderLayer.cpp:
     44        (WebCore::RenderLayer::panScrollFromPoint): Ditto.
     45        (WebCore::RenderLayer::autoscroll): Ditto.
     46        (WebCore::RenderLayer::lastKnownMousePosition): Ditto.
     47        * rendering/RenderListBox.cpp:
     48        (WebCore::RenderListBox::panScroll): Ditto.
     49        (WebCore::RenderListBox::autoscroll): Ditto.
     50        (WebCore::RenderListBox::lastKnownMousePosition): Ditto.
     51
    1522012-12-12  Martin Robinson  <mrobinson@igalia.com>
    253
  • trunk/Source/WebCore/page/EventHandler.cpp

    r137295 r137539  
    348348    , m_eventHandlerWillResetCapturingMouseEventsNode(0)
    349349    , m_clickCount(0)
     350    , m_mousePositionIsUnknown(true)
    350351    , m_mouseDownTimestamp(0)
    351352    , m_widgetIsLatched(false)
     
    399400    m_shouldOnlyFireDragOverEvent = false;
    400401#endif
    401     m_currentMousePosition = IntPoint();
    402     m_currentMouseGlobalPosition = IntPoint();
     402    m_mousePositionIsUnknown = true;
     403    m_lastKnownMousePosition = IntPoint();
     404    m_lastKnownMouseGlobalPosition = IntPoint();
    403405    m_mousePressNode = 0;
    404406    m_mousePressed = false;
     
    821823                           HitTestRequest::Active |
    822824                           HitTestRequest::Move);
    823     HitTestResult result(view->windowToContents(m_currentMousePosition));
     825    HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
    824826    renderer->hitTest(request, result);
    825827    updateSelectionForMouseDrag(result);
     
    9991001#if ENABLE(PAN_SCROLLING)
    10001002    if (m_panScrollInProgress) {
    1001         m_panScrollStartPos = currentMousePosition();
     1003        m_panScrollStartPos = lastKnownMousePosition();
    10021004        if (FrameView* view = m_frame->view())
    10031005            view->addPanScrollIcon(m_panScrollStartPos);
     
    10611063    // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll
    10621064    // So we don't want to change the cursor over this area
    1063     bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - ScrollView::noPanScrollRadius);
    1064     bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + ScrollView::noPanScrollRadius);
    1065     bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + ScrollView::noPanScrollRadius);
    1066     bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - ScrollView::noPanScrollRadius);
     1065    bool east = m_panScrollStartPos.x() < (m_lastKnownMousePosition.x() - ScrollView::noPanScrollRadius);
     1066    bool west = m_panScrollStartPos.x() > (m_lastKnownMousePosition.x() + ScrollView::noPanScrollRadius);
     1067    bool north = m_panScrollStartPos.y() > (m_lastKnownMousePosition.y() + ScrollView::noPanScrollRadius);
     1068    bool south = m_panScrollStartPos.y() < (m_lastKnownMousePosition.y() - ScrollView::noPanScrollRadius);
    10671069         
    10681070    if ((east || west || north || south) && m_panScrollButtonPressed)
     
    13381340}
    13391341
    1340 IntPoint EventHandler::currentMousePosition() const
    1341 {
    1342     return m_currentMousePosition;
     1342IntPoint EventHandler::lastKnownMousePosition() const
     1343{
     1344    return m_lastKnownMousePosition;
    13431345}
    13441346
     
    16081610    m_mousePressed = true;
    16091611    m_capturesDragging = true;
    1610     m_currentMousePosition = mouseEvent.position();
    1611     m_currentMouseGlobalPosition = mouseEvent.globalPosition();
     1612    setLastKnownMousePosition(mouseEvent);
    16121613    m_mouseDownTimestamp = mouseEvent.timestamp();
    16131614#if ENABLE(DRAG_SUPPORT)
     
    17371738    // We get this instead of a second mouse-up
    17381739    m_mousePressed = false;
    1739     m_currentMousePosition = mouseEvent.position();
    1740     m_currentMouseGlobalPosition = mouseEvent.globalPosition();
     1740    setLastKnownMousePosition(mouseEvent);
    17411741
    17421742    HitTestRequest request(HitTestRequest::Active);
     
    18321832
    18331833    RefPtr<FrameView> protector(m_frame->view());
    1834     m_currentMousePosition = mouseEvent.position();
    1835     m_currentMouseGlobalPosition = mouseEvent.globalPosition();
     1834   
     1835    setLastKnownMousePosition(mouseEvent);
    18361836
    18371837    if (m_hoverTimer.isActive())
     
    18421842#if ENABLE(SVG)
    18431843    if (m_svgPan) {
    1844         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_currentMousePosition));
     1844        static_cast<SVGDocument*>(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
    18451845        return true;
    18461846    }
     
    19581958
    19591959    m_mousePressed = false;
    1960     m_currentMousePosition = mouseEvent.position();
    1961     m_currentMouseGlobalPosition = mouseEvent.globalPosition();
     1960    setLastKnownMousePosition(mouseEvent);
    19621961
    19631962#if ENABLE(SVG)
    19641963    if (m_svgPan) {
    19651964        m_svgPan = false;
    1966         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_currentMousePosition));
     1965        static_cast<SVGDocument*>(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
    19671966        return true;
    19681967    }
     
    29942993        return;
    29952994
     2995    if (m_mousePositionIsUnknown)
     2996        return;
     2997
    29962998    Settings* settings = m_frame->settings();
    29972999    if (settings && !settings->deviceSupportsMouse())
     
    30183020        return;
    30193021
    3020     if (!quad.containsPoint(view->windowToContents(m_currentMousePosition)))
     3022    if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
    30213023        return;
    30223024
     
    30503052    bool metaKey;
    30513053    PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
    3052     PlatformMouseEvent fakeMouseMoveEvent(m_currentMousePosition, m_currentMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
     3054    PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
    30533055    mouseMoved(fakeMouseMoveEvent);
    30543056}
     
    30753077        if (FrameView* view = m_frame->view()) {
    30763078            HitTestRequest request(HitTestRequest::Move);
    3077             HitTestResult result(view->windowToContents(m_currentMousePosition));
     3079            HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
    30783080            renderer->hitTest(request, result);
    30793081            m_frame->document()->updateStyleIfNeeded();
     
    40714073#endif
    40724074
    4073 }
     4075void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
     4076{
     4077    m_mousePositionIsUnknown = false;
     4078    m_lastKnownMousePosition = event.position();
     4079    m_lastKnownMouseGlobalPosition = event.globalPosition();
     4080}
     4081
     4082} // namespace WebCore
  • trunk/Source/WebCore/page/EventHandler.h

    r137220 r137539  
    143143    void resizeLayerDestroyed();
    144144
    145     IntPoint currentMousePosition() const;
     145    IntPoint lastKnownMousePosition() const;
    146146    Cursor currentMouseCursor() const { return m_currentMouseCursor; }
    147147
     
    381381#endif
    382382
     383    void setLastKnownMousePosition(const PlatformMouseEvent&);
     384
    383385    Frame* m_frame;
    384386
     
    445447    LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
    446448   
    447     IntPoint m_currentMousePosition;
    448     IntPoint m_currentMouseGlobalPosition;
     449    bool m_mousePositionIsUnknown;
     450    IntPoint m_lastKnownMousePosition;
     451    IntPoint m_lastKnownMouseGlobalPosition;
    449452    IntPoint m_mouseDownPos; // In our view's coords.
    450453    double m_mouseDownTimestamp;
  • trunk/Source/WebCore/page/FrameView.cpp

    r137387 r137539  
    15051505}
    15061506
    1507 IntPoint FrameView::currentMousePosition() const
    1508 {
    1509     return m_frame ? m_frame->eventHandler()->currentMousePosition() : IntPoint();
     1507IntPoint FrameView::lastKnownMousePosition() const
     1508{
     1509    return m_frame ? m_frame->eventHandler()->lastKnownMousePosition() : IntPoint();
    15101510}
    15111511
  • trunk/Source/WebCore/page/FrameView.h

    r137178 r137539  
    324324    static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
    325325
    326     virtual IntPoint currentMousePosition() const;
     326    virtual IntPoint lastKnownMousePosition() const;
    327327
    328328    virtual bool scrollbarsCanBeActive() const OVERRIDE;
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r137108 r137539  
    144144    virtual IntSize contentsSize() const = 0;
    145145    virtual IntSize overhangAmount() const { return IntSize(); }
    146     virtual IntPoint currentMousePosition() const { return IntPoint(); }
     146    virtual IntPoint lastKnownMousePosition() const { return IntPoint(); }
    147147
    148148    virtual bool shouldSuspendScrollAnimations() const { return true; }
  • trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm

    r136303 r137539  
    227227        return NSZeroPoint;
    228228
    229     return _scrollableArea->currentMousePosition();
     229    return _scrollableArea->lastKnownMousePosition();
    230230}
    231231
     
    449449    ASSERT_UNUSED(scrollerImp, scrollerImp == scrollbarPainterForScrollbar(_scrollbar));
    450450
    451     return _scrollbar->convertFromContainingView(_scrollbar->scrollableArea()->currentMousePosition());
     451    return _scrollbar->convertFromContainingView(_scrollbar->scrollableArea()->lastKnownMousePosition());
    452452}
    453453
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r137492 r137539  
    16591659        return;
    16601660   
    1661     IntPoint currentMousePosition = frame->eventHandler()->currentMousePosition();
    1662    
    1663     // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
     1661    IntPoint lastKnownMousePosition = frame->eventHandler()->lastKnownMousePosition();
     1662   
     1663    // We need to check if the last known mouse position is out of the window. When the mouse is out of the window, the position is incoherent
    16641664    static IntPoint previousMousePosition;
    1665     if (currentMousePosition.x() < 0 || currentMousePosition.y() < 0)
    1666         currentMousePosition = previousMousePosition;
     1665    if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
     1666        lastKnownMousePosition = previousMousePosition;
    16671667    else
    1668         previousMousePosition = currentMousePosition;
    1669 
    1670     IntSize delta = currentMousePosition - sourcePoint;
     1668        previousMousePosition = lastKnownMousePosition;
     1669
     1670    IntSize delta = lastKnownMousePosition - sourcePoint;
    16711671
    16721672    if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
     
    20192019#endif
    20202020
    2021     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
     2021    IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->lastKnownMousePosition());
    20222022    scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
    20232023}
     
    22982298}
    22992299
    2300 IntPoint RenderLayer::currentMousePosition() const
    2301 {
    2302     return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();
     2300IntPoint RenderLayer::lastKnownMousePosition() const
     2301{
     2302    return renderer()->frame() ? renderer()->frame()->eventHandler()->lastKnownMousePosition() : IntPoint();
    23032303}
    23042304
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r137108 r137539  
    857857    virtual IntSize contentsSize() const;
    858858    virtual IntSize overhangAmount() const;
    859     virtual IntPoint currentMousePosition() const;
     859    virtual IntPoint lastKnownMousePosition() const;
    860860    virtual bool shouldSuspendScrollAnimations() const;
    861861    virtual bool scrollbarsCanBeActive() const;
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

    r132112 r137539  
    500500    FloatPoint absOffset = localToAbsolute();
    501501
    502     IntPoint currentMousePosition = frame()->eventHandler()->currentMousePosition();
    503     // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
     502    IntPoint lastKnownMousePosition = frame()->eventHandler()->lastKnownMousePosition();
     503    // We need to check if the last known mouse position is out of the window. When the mouse is out of the window, the position is incoherent
    504504    static IntPoint previousMousePosition;
    505     if (currentMousePosition.y() < 0)
    506         currentMousePosition = previousMousePosition;
     505    if (lastKnownMousePosition.y() < 0)
     506        lastKnownMousePosition = previousMousePosition;
    507507    else
    508         previousMousePosition = currentMousePosition;
    509 
    510     int yDelta = currentMousePosition.y() - panStartMousePosition.y();
     508        previousMousePosition = lastKnownMousePosition;
     509
     510    int yDelta = lastKnownMousePosition.y() - panStartMousePosition.y();
    511511
    512512    // If the point is too far from the center we limit the speed
     
    557557void RenderListBox::autoscroll()
    558558{
    559     IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler()->currentMousePosition());
     559    IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler()->lastKnownMousePosition());
    560560
    561561    int endIndex = scrollToward(pos);
     
    804804}
    805805
    806 IntPoint RenderListBox::currentMousePosition() const
     806IntPoint RenderListBox::lastKnownMousePosition() const
    807807{
    808808    RenderView* view = this->view();
    809809    if (!view)
    810810        return IntPoint();
    811     return view->frameView()->currentMousePosition();
     811    return view->frameView()->lastKnownMousePosition();
    812812}
    813813
  • trunk/Source/WebCore/rendering/RenderListBox.h

    r132753 r137539  
    118118    virtual int visibleHeight() const OVERRIDE;
    119119    virtual int visibleWidth() const OVERRIDE;
    120     virtual IntPoint currentMousePosition() const OVERRIDE;
     120    virtual IntPoint lastKnownMousePosition() const OVERRIDE;
    121121    virtual bool shouldSuspendScrollAnimations() const OVERRIDE;
    122122    virtual bool scrollbarsCanBeActive() const OVERRIDE;
Note: See TracChangeset for help on using the changeset viewer.