<rdar://problem/7694674> Hover states not updated when overflow section scrolls under...
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Mar 2010 17:06:39 +0000 (17:06 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Mar 2010 17:06:39 +0000 (17:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=35949

Reviewed by Darin Adler.

WebCore:

Test: fast/events/overflow-scroll-fake-mouse-move.html

Soon after an overflow section scrolls under the mouse pointer, dispatch
a fake mouse move event. This is similar to how frame scrolling is handled
in WebKit, and has the effect of updating hover state, dispatching DOM mouse
events, and updating the tool tip.

* page/EventHandler.cpp:
(WebCore::EventHandler::EventHandler): Initialize m_fakeMouseMoveEventTimer.
(WebCore::EventHandler::~EventHandler): Assert that the timer is not active.
(WebCore::EventHandler::clear): Stop the timer.
(WebCore::EventHandler::handleMousePressEvent): Cancel pending fake mouse
move events.
(WebCore::EventHandler::handleMouseMoveEvent): Ditto.
(WebCore::EventHandler::dispatchFakeMouseMoveEventSoonInQuad): If the mouse
is in the passed-in quad, ensure that a fake mouse move event is scheduled
to fire soon.
(WebCore::EventHandler::cancelFakeMouseMoveEvent): Does what the name says.
(WebCore::EventHandler::fakeMouseMoveEventTimerFired): Constructs a
PlatformMouseEvent with the current mouse location, modifier key state and
time stamp and calls mouseMoved().
* page/EventHandler.h:
* platform/PlatformKeyboardEvent.h: Declared getCurrentModifierState().
* platform/android/KeyEventAndroid.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
* platform/brew/PlatformKeyboardEventBrew.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
* platform/chromium/PlatformKeyboardEventChromium.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
* platform/efl/PlatformKeyboardEventEfl.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
* platform/gtk/KeyEventGtk.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
* platform/haiku/PlatformKeyboardEventHaiku.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
* platform/mac/KeyEventMac.mm:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
* platform/qt/PlatformKeyboardEventQt.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
* platform/win/KeyEventWin.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
* platform/wx/KeyboardEventWx.cpp:
(WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollToOffset): Call
EventHandler::dispatchFakeMouseMoveEventSoonInQuad(). Moved things around
a little to avoid computing the repaint rect twice.

LayoutTests:

* fast/events/overflow-scroll-fake-mouse-move-expected.txt: Added.
* fast/events/overflow-scroll-fake-mouse-move.html: Added.
* fast/events/touch/basic-multi-touch-events.html:
* fast/events/touch/basic-single-touch-events.html:

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/overflow-scroll-fake-mouse-move-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/overflow-scroll-fake-mouse-move.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/page/EventHandler.cpp
WebCore/page/EventHandler.h
WebCore/platform/PlatformKeyboardEvent.h
WebCore/platform/android/KeyEventAndroid.cpp
WebCore/platform/brew/PlatformKeyboardEventBrew.cpp
WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
WebCore/platform/efl/PlatformKeyboardEventEfl.cpp
WebCore/platform/gtk/KeyEventGtk.cpp
WebCore/platform/haiku/PlatformKeyboardEventHaiku.cpp
WebCore/platform/mac/KeyEventMac.mm
WebCore/platform/qt/PlatformKeyboardEventQt.cpp
WebCore/platform/win/KeyEventWin.cpp
WebCore/platform/wx/KeyboardEventWx.cpp
WebCore/rendering/RenderLayer.cpp

index 412993e..18c4937 100644 (file)
@@ -1,3 +1,15 @@
+2010-03-12  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/7694674> Hover states not updated when overflow section scrolls under stationary mouse pointer
+        https://bugs.webkit.org/show_bug.cgi?id=35949
+
+        * fast/events/overflow-scroll-fake-mouse-move-expected.txt: Added.
+        * fast/events/overflow-scroll-fake-mouse-move.html: Added.
+        * fast/events/touch/basic-multi-touch-events.html:
+        * fast/events/touch/basic-single-touch-events.html:
+
 2010-03-12  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         [Qt] css1/box_properties/acid_test.html failed in release mode (32 bit).
diff --git a/LayoutTests/fast/events/overflow-scroll-fake-mouse-move-expected.txt b/LayoutTests/fast/events/overflow-scroll-fake-mouse-move-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/fast/events/overflow-scroll-fake-mouse-move.html b/LayoutTests/fast/events/overflow-scroll-fake-mouse-move.html
new file mode 100644 (file)
index 0000000..1603898
--- /dev/null
@@ -0,0 +1,33 @@
+<div id="target" style="overflow: auto; height: 200px; width: 200px;">
+    <div onmouseover="mouseOver(event)" style="margin: 300px 0; width: 100px; height: 100px; background-color: blue;"></div>
+</div>
+<div id="result">Test did not run</div>
+<script>
+    var passed = false;
+
+    function mouseOver(event)
+    {
+        passed = true;
+    }
+
+    function finish()
+    {
+        document.getElementById("result").innerText = passed ? "PASS" : "FAIL";
+        layoutTestController.notifyDone();
+    }
+
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+
+        // WebKit schedules a fake mouse move event as part of installing the WebView in
+        // a window. For the test to be valid, it must begin only after that event
+        // gets dispatched.
+        setTimeout(function()
+        {
+            eventSender.mouseMoveTo(50, 100);
+            document.getElementById("target").scrollTop = 250;
+            setTimeout(finish, 200);
+        }, 200);
+    }
+</script>
index 0dab13d..fb01f67 100644 (file)
@@ -1,3 +1,58 @@
+2010-03-12  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/7694674> Hover states not updated when overflow section scrolls under stationary mouse pointer
+        https://bugs.webkit.org/show_bug.cgi?id=35949
+
+        Test: fast/events/overflow-scroll-fake-mouse-move.html
+
+        Soon after an overflow section scrolls under the mouse pointer, dispatch
+        a fake mouse move event. This is similar to how frame scrolling is handled
+        in WebKit, and has the effect of updating hover state, dispatching DOM mouse
+        events, and updating the tool tip.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::EventHandler): Initialize m_fakeMouseMoveEventTimer.
+        (WebCore::EventHandler::~EventHandler): Assert that the timer is not active.
+        (WebCore::EventHandler::clear): Stop the timer.
+        (WebCore::EventHandler::handleMousePressEvent): Cancel pending fake mouse
+        move events.
+        (WebCore::EventHandler::handleMouseMoveEvent): Ditto.
+        (WebCore::EventHandler::dispatchFakeMouseMoveEventSoonInQuad): If the mouse
+        is in the passed-in quad, ensure that a fake mouse move event is scheduled
+        to fire soon.
+        (WebCore::EventHandler::cancelFakeMouseMoveEvent): Does what the name says.
+        (WebCore::EventHandler::fakeMouseMoveEventTimerFired): Constructs a
+        PlatformMouseEvent with the current mouse location, modifier key state and
+        time stamp and calls mouseMoved().
+        * page/EventHandler.h:
+        * platform/PlatformKeyboardEvent.h: Declared getCurrentModifierState().
+        * platform/android/KeyEventAndroid.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
+        * platform/brew/PlatformKeyboardEventBrew.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
+        * platform/chromium/PlatformKeyboardEventChromium.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
+        * platform/efl/PlatformKeyboardEventEfl.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
+        * platform/gtk/KeyEventGtk.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
+        * platform/haiku/PlatformKeyboardEventHaiku.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
+        * platform/mac/KeyEventMac.mm:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
+        * platform/qt/PlatformKeyboardEventQt.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Stubbed out.
+        * platform/win/KeyEventWin.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Added.
+        * platform/wx/KeyboardEventWx.cpp:
+        (WebCore::PlatformKeyboardEvent::getCurrentModifierState): Ditto.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollToOffset): Call
+        EventHandler::dispatchFakeMouseMoveEventSoonInQuad(). Moved things around
+        a little to avoid computing the repaint rect twice.
+
 2010-03-12  Kent Hansen  <kent.hansen@nokia.com>
 
         Reviewed by Darin Adler.
index ba5a04b..d544492 100644 (file)
@@ -67,6 +67,7 @@
 #include "TextEvent.h"
 #include "WheelEvent.h"
 #include "htmlediting.h" // for comparePositions()
+#include <wtf/CurrentTime.h>
 #include <wtf/StdLibExtras.h>
 
 #if ENABLE(SVG)
@@ -106,6 +107,8 @@ using namespace SVGNames;
 // When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
 const double autoscrollInterval = 0.05;
 
+const double fakeMouseMoveInterval = 0.1;
+
 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
 
 static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
@@ -168,6 +171,7 @@ EventHandler::EventHandler(Frame* frame)
     , m_autoscrollInProgress(false)
     , m_mouseDownMayStartAutoscroll(false)
     , m_mouseDownWasInSubframe(false)
+    , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired)
 #if ENABLE(SVG)
     , m_svgPan(false)
 #endif
@@ -187,6 +191,7 @@ EventHandler::EventHandler(Frame* frame)
 
 EventHandler::~EventHandler()
 {
+    ASSERT(!m_fakeMouseMoveEventTimer.isActive());
 }
     
 #if ENABLE(DRAG_SUPPORT)
@@ -200,6 +205,7 @@ EventHandler::EventHandlerDragState& EventHandler::dragState()
 void EventHandler::clear()
 {
     m_hoverTimer.stop();
+    m_fakeMouseMoveEventTimer.stop();
     m_resizeLayer = 0;
     m_nodeUnderMouse = 0;
     m_lastNodeUnderMouse = 0;
@@ -375,6 +381,8 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
     dragState().m_dragSrc = 0;
 #endif
 
+    cancelFakeMouseMoveEvent();
+
     if (ScrollView* scrollView = m_frame->view()) {
         if (scrollView->isPointInScrollbarCorner(event.event().pos()))
             return false;
@@ -1150,6 +1158,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
 {
     RefPtr<FrameView> protector(m_frame->view());
 
+    cancelFakeMouseMoveEvent();
     m_mousePressed = true;
     m_capturesDragging = true;
     m_currentMousePosition = mouseEvent.pos();
@@ -1341,6 +1350,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
     if (m_hoverTimer.isActive())
         m_hoverTimer.stop();
 
+    cancelFakeMouseMoveEvent();
+
 #if ENABLE(SVG)
     if (m_svgPan) {
         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);
@@ -1943,6 +1954,43 @@ void EventHandler::scheduleHoverStateUpdate()
         m_hoverTimer.startOneShot(0);
 }
 
+void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
+{
+    FrameView* view = m_frame->view();
+    if (!view)
+        return;
+
+    if (m_mousePressed || !quad.containsPoint(view->windowToContents(m_currentMousePosition)))
+        return;
+
+    if (!m_fakeMouseMoveEventTimer.isActive())
+        m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveInterval);
+}
+
+void EventHandler::cancelFakeMouseMoveEvent()
+{
+    m_fakeMouseMoveEventTimer.stop();
+}
+
+void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
+{
+    ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
+    ASSERT(!m_mousePressed);
+
+    FrameView* view = m_frame->view();
+    if (!view)
+        return;
+
+    bool shiftKey;
+    bool ctrlKey;
+    bool altKey;
+    bool metaKey;
+    PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
+    IntPoint globalPoint = view->contentsToScreen(IntRect(view->windowToContents(m_currentMousePosition), IntSize())).location();
+    PlatformMouseEvent fakeMouseMoveEvent(m_currentMousePosition, globalPoint, NoButton, MouseEventMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
+    mouseMoved(fakeMouseMoveEvent);
+}
+
 // Whether or not a mouse down can begin the creation of a selection.  Fires the selectStart event.
 bool EventHandler::canMouseDownStartSelect(Node* node)
 {
index b655db4..282100d 100644 (file)
@@ -50,6 +50,7 @@ class Cursor;
 class Event;
 class EventTarget;
 class FloatPoint;
+class FloatQuad;
 class Frame;
 class HitTestRequest;
 class HitTestResult;
@@ -102,6 +103,8 @@ public:
     RenderObject* autoscrollRenderer() const;
     void updateAutoscrollRenderer();
 
+    void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
+
     HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars);
 
     bool mousePressed() const { return m_mousePressed; }
@@ -266,6 +269,9 @@ private:
     void setAutoscrollRenderer(RenderObject*);
     void autoscrollTimerFired(Timer<EventHandler>*);
 
+    void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
+    void cancelFakeMouseMoveEvent();
+
     void invalidateClick();
 
     Node* nodeUnderMouse() const;
@@ -373,6 +379,8 @@ private:
     bool m_mouseDownMayStartAutoscroll;
     bool m_mouseDownWasInSubframe;
 
+    Timer<EventHandler> m_fakeMouseMoveEventTimer;
+
 #if ENABLE(SVG)
     bool m_svgPan;
     RefPtr<SVGElementInstance> m_instanceUnderMouse;
index 03f5f8f..d11d456 100644 (file)
@@ -155,6 +155,7 @@ namespace WebCore {
         }
 
         static bool currentCapsLockState();
+        static void getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey);
 
 #if PLATFORM(MAC)
         PlatformKeyboardEvent(NSEvent*);
index af29598..c30d540 100644 (file)
@@ -251,6 +251,15 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return false;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    notImplemented();
+    shiftKey = false;
+    ctrlKey = false;
+    altKey = false;
+    metaKey = false;
+}
+
 void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
 {
     // Copied with modification from the mac port.
index 758d15c..b69b7ee 100644 (file)
@@ -170,5 +170,13 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return false;
 }
 
-} // namespace WebCore
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    notImplemented();
+    shiftKey = false;
+    ctrlKey = false;
+    altKey = false;
+    metaKey = false;
+}
 
+} // namespace WebCore
index 74643f7..5105c6d 100644 (file)
@@ -82,4 +82,22 @@ bool PlatformKeyboardEvent::currentCapsLockState()
 #endif
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+#if OS(WINDOWS)
+    shiftKey = GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT;
+    ctrlKey = GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT;
+    altKey = GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT;
+    metaKey = false;
+#elif OS(DARWIN)
+    UInt32 currentModifiers = GetCurrentKeyModifiers();
+    shiftKey = currentModifiers & ::shiftKey;
+    ctrlKey = currentModifiers & ::controlKey;
+    altKey = currentModifiers & ::optionKey;
+    metaKey = currentModifiers & ::cmdKey;
+#else
+    notImplemented();
+#endif
+}
+
 } // namespace WebCore
index 2cfe8e9..6f57883 100644 (file)
@@ -241,4 +241,13 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return false;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    notImplemented();
+    shiftKey = false;
+    ctrlKey = false;
+    altKey = false;
+    metaKey = false;
+}
+
 }
index e00ea43..edb8fb5 100644 (file)
@@ -586,6 +586,15 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return false;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    notImplemented();
+    shiftKey = false;
+    ctrlKey = false;
+    altKey = false;
+    metaKey = false;
+}
+
 GdkEventKey* PlatformKeyboardEvent::gdkEventKey() const
 {
     return m_gdkEventKey;
index 053e30a..f6d81bc 100644 (file)
@@ -377,5 +377,14 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return ::modifiers() & B_CAPS_LOCK;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    unit32 modifiers = ::modifiers();
+    shiftKey = modifiers & B_SHIFT_KEY;
+    ctrlKey = modifiers & B_COMMAND_KEY;
+    altKey = modifiers & B_CONTROL_KEY;
+    metaKey = modifiers & B_OPTION_KEY;
+}
+
 } // namespace WebCore
 
index 3638cb1..2f77734 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2010 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -876,4 +876,13 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return GetCurrentKeyModifiers() & alphaLock;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    UInt32 currentModifiers = GetCurrentKeyModifiers();
+    shiftKey = currentModifiers & ::shiftKey;
+    ctrlKey = currentModifiers & ::controlKey;
+    altKey = currentModifiers & ::optionKey;
+    metaKey = currentModifiers & ::cmdKey;
+}
+
 }
index c56c3bb..895b152 100644 (file)
@@ -551,6 +551,15 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return false;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    notImplemented();
+    shiftKey = false;
+    ctrlKey = false;
+    altKey = false;
+    metaKey = false;
+}
+
 }
 
 // vim: ts=4 sw=4 et
index 99dfe44..43fb0a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -214,4 +214,12 @@ bool PlatformKeyboardEvent::currentCapsLockState()
      return GetKeyState(VK_CAPITAL) & 1;
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    shiftKey = GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT;
+    ctrlKey = GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT;
+    altKey = GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT;
+    metaKey = false;
+}
+
 }
index 7f57073..4ce5a76 100644 (file)
@@ -388,5 +388,13 @@ bool PlatformKeyboardEvent::currentCapsLockState()
     return wxGetKeyState(WXK_CAPITAL);
 }
 
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+    shiftKey = wxGetKeyState(WXK_SHIFT);
+    ctrlKey = wxGetKeyState(WXK_CONTROL);
+    altKey = wxGetKeyState(WXK_ALT);
+    metaKey = false;
+}
+
 }
 
index 60387b6..c6c68de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
  *
@@ -1235,15 +1235,24 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
         view->updateWidgetPositions();
     }
 
-    // The caret rect needs to be invalidated after scrolling
+    RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+    IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
+
     Frame* frame = renderer()->document()->frame();
-    if (frame)
+    if (frame) {
+        // The caret rect needs to be invalidated after scrolling
         frame->selection()->setNeedsLayout();
 
+        FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
+        if (repaintContainer)
+            quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+        frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
+    }
+
     // Just schedule a full repaint of our object.
-    if (repaint)
-        renderer()->repaint();
-    
+    if (view && repaint)
+        renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+
     if (updateScrollbars) {
         if (m_hBar)
             m_hBar->setValue(scrollXOffset());