[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

ap at apple.com ap at apple.com
Fri Feb 26 22:26:08 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit d7abf4a9281fa4b42414888d60a90e73c6500bf7
Author: ap at apple.com <ap at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Feb 20 01:23:12 2010 +0000

            Reviewed by Maciej Stachowiak.
    
            https://bugs.webkit.org/show_bug.cgi?id=35132
            <rdar://problem/7664353> Mouse cursor sometimes flickers over Flash content (35132)
    
    WebCore:
            * page/EventHandler.cpp: (WebCore::EventHandler::handleMouseMoveEvent): Don't set mouse
            pointer when above a plug-in or applet to prevent flicker.
    
    WebKit:
            * Plugins/WebNetscapePluginEventHandlerCarbon.mm:
            (WebNetscapePluginEventHandlerCarbon::mouseMoved): Send adjustCursor events on every mouse
            move. This matches Firefox, and is actually required for plug-ins to manipulate cursor wihout
            resorting to techniques such as fast firing timers.
    
            * Plugins/WebNetscapePluginView.mm:
            (-[WebNetscapePluginView handleMouseEntered:]): Some plug-ins handle mouse cursor internally,
            but those that don't just need to get an arrow cursor (matching Firefox). This means that
            e.g. a plugin inside <A> won't get a finger mouse pointer.
    
            * Plugins/WebHostedNetscapePluginView.mm:
            (-[WebNetscapePluginView handleMouseEntered:]):
            (-[WebNetscapePluginView handleMouseExited:]):
            Implement this behavior here, too. Also, out of process code didn't reset mouse pointer on
            mouse exit, which it needed to do.
    
            * WebView/WebHTMLView.mm:
            (needsCursorRectsSupportAtPoint):
            (setCursor):
            (resetCursorRects):
            Make sure that the same workaround we have for Web content also applies to Netscape plug-ins,
            as AppKit would reset the mouse pointer to arrow if given a chance.
            (+[WebHTMLViewPrivate initialize]): Renamed setCursorIMP on Leopard and higher to prevent
            confusion - the method we override is completely different.
            (-[WebHTMLView hitTest:]): Added a FIXME about a likely bug.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55041 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index c343854..3a4db22 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-19  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Maciej Stachowiak.
+
+        https://bugs.webkit.org/show_bug.cgi?id=35132
+        <rdar://problem/7664353> Mouse cursor sometimes flickers over Flash content (35132)
+
+        * page/EventHandler.cpp: (WebCore::EventHandler::handleMouseMoveEvent): Don't set mouse
+        pointer when above a plug-in or applet to prevent flicker.
+
 2010-02-18  Peter Kasting  <pkasting at google.com>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 8a77867..0c776db 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -1396,8 +1396,18 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
             scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
         if (Page* page = m_frame->page()) {
             if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !page->mainFrame()->eventHandler()->panScrollInProgress()) {
-                if (FrameView* view = m_frame->view())
-                    view->setCursor(selectCursor(mev, scrollbar));
+                // Plugins set cursor on their own. The only case WebKit intervenes is resetting cursor to arrow on mouse enter,
+                // in case the particular plugin doesn't manipulate cursor at all. Thus,  even a CSS cursor set on body has no
+                // effect on plugins (which matches Firefox).
+                bool overPluginElement = false;
+                if (mev.targetNode() && mev.targetNode()->isHTMLElement()) {
+                    HTMLElement* el = static_cast<HTMLElement*>(mev.targetNode());
+                    overPluginElement = el->hasTagName(appletTag) || el->hasTagName(objectTag) || el->hasTagName(embedTag);
+                }
+                if (!overPluginElement) {
+                    if (FrameView* view = m_frame->view())
+                        view->setCursor(selectCursor(mev, scrollbar));
+                }
             }
         }
     }
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index e1d0cc3..0ae5c95 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,36 @@
+2010-02-19  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Maciej Stachowiak.
+
+        https://bugs.webkit.org/show_bug.cgi?id=35132
+        <rdar://problem/7664353> Mouse cursor sometimes flickers over Flash content (35132)
+
+        * Plugins/WebNetscapePluginEventHandlerCarbon.mm:
+        (WebNetscapePluginEventHandlerCarbon::mouseMoved): Send adjustCursor events on every mouse
+        move. This matches Firefox, and is actually required for plug-ins to manipulate cursor wihout
+        resorting to techniques such as fast firing timers.
+
+        * Plugins/WebNetscapePluginView.mm:
+        (-[WebNetscapePluginView handleMouseEntered:]): Some plug-ins handle mouse cursor internally,
+        but those that don't just need to get an arrow cursor (matching Firefox). This means that
+        e.g. a plugin inside <A> won't get a finger mouse pointer.
+
+        * Plugins/WebHostedNetscapePluginView.mm:
+        (-[WebNetscapePluginView handleMouseEntered:]):
+        (-[WebNetscapePluginView handleMouseExited:]):
+        Implement this behavior here, too. Also, out of process code didn't reset mouse pointer on
+        mouse exit, which it needed to do.
+
+        * WebView/WebHTMLView.mm:
+        (needsCursorRectsSupportAtPoint):
+        (setCursor):
+        (resetCursorRects):
+        Make sure that the same workaround we have for Web content also applies to Netscape plug-ins,
+        as AppKit would reset the mouse pointer to arrow if given a chance.
+        (+[WebHTMLViewPrivate initialize]): Renamed setCursorIMP on Leopard and higher to prevent
+        confusion - the method we override is completely different.
+        (-[WebHTMLView hitTest:]): Added a FIXME about a likely bug.
+
 2010-02-19  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
index 0ad76f0..6f097cc 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
@@ -287,6 +287,9 @@ extern "C" {
 
 - (void)handleMouseEntered:(NSEvent *)event
 {
+    // Set cursor to arrow. Plugins often handle cursor internally, but those that don't will just get this default one.
+    [[NSCursor arrowCursor] set];
+
     if (_isStarted && _proxy)
         _proxy->mouseEvent(self, event, NPCocoaEventMouseEntered);
 }
@@ -295,6 +298,11 @@ extern "C" {
 {
     if (_isStarted && _proxy)
         _proxy->mouseEvent(self, event, NPCocoaEventMouseExited);
+
+    // Set cursor back to arrow cursor.  Because NSCursor doesn't know about changes that the plugin made, we could get confused about what we think the
+    // current cursor is otherwise.  Therefore we have no choice but to unconditionally reset the cursor when the mouse exits the plugin.
+    // FIXME: This should be job of plugin host, see <rdar://problem/7654434>.
+    [[NSCursor arrowCursor] set];
 }
 
 - (void)scrollWheel:(NSEvent *)event
diff --git a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
index d8324f7..a5e8f73 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
@@ -199,8 +199,17 @@ void WebNetscapePluginEventHandlerCarbon::mouseDragged(NSEvent*)
 {
 }
 
-void WebNetscapePluginEventHandlerCarbon::mouseMoved(NSEvent*)
+void WebNetscapePluginEventHandlerCarbon::mouseMoved(NSEvent* theEvent)
 {
+    EventRecord event;
+    
+    getCarbonEvent(&event, theEvent);
+    event.what = adjustCursorEvent;
+    
+    BOOL acceptedEvent;
+    acceptedEvent = sendEvent(&event);
+    
+    LOG(PluginEvents, "NPP_HandleEvent(mouseMoved): %d", acceptedEvent);
 }
 
 void WebNetscapePluginEventHandlerCarbon::keyDown(NSEvent *theEvent)
diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.mm b/WebKit/mac/Plugins/WebNetscapePluginView.mm
index 8fb1503..dd74f5b 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginView.mm
@@ -754,6 +754,9 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     if (!_isStarted)
         return;
 
+    // Set cursor to arrow. Plugins often handle cursor internally, but those that don't will just get this default one.
+    [[NSCursor arrowCursor] set];
+
     _eventHandler->mouseEntered(theEvent);
 }
 
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index aa65920..c0021b1 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -148,26 +148,52 @@ using namespace std;
 - (BOOL)receivedUnhandledCommand;
 @end
 
-static IMP oldSetCursorIMP = NULL;
+// if YES, do the standard NSView hit test (which can't give the right result when HTML overlaps a view)
+static BOOL forceNSViewHitTest;
 
-#ifdef BUILDING_ON_TIGER
+// if YES, do the "top WebHTMLView" hit test (which we'd like to do all the time but can't because of Java requirements [see bug 4349721])
+static BOOL forceWebHTMLViewHitTest;
+
+static WebHTMLView *lastHitView;
+
+static bool needsCursorRectsSupportAtPoint(NSWindow* window, NSPoint point)
+{
+    forceNSViewHitTest = YES;
+    NSView* view = [[window _web_borderView] hitTest:point];
+    forceNSViewHitTest = NO;
+
+    // WebHTMLView doesn't use cursor rects.
+    if ([view isKindOfClass:[WebHTMLView class]])
+        return false;
+
+    // Neither do NPAPI plug-ins.
+    if ([view isKindOfClass:[WebBaseNetscapePluginView class]])
+        return false;
+
+    // Non-Web content, WebPDFView, and WebKit plug-ins use normal cursor handling.
+    return true;
+}
 
-static IMP oldResetCursorRectsIMP = NULL;
+#ifndef BUILDING_ON_TIGER
+
+static IMP oldSetCursorForMouseLocationIMP;
+
+// Overriding an internal method is a hack; <rdar://problem/7662987> tracks finding a better solution.
+static void setCursor(NSWindow* self, SEL cmd, NSPoint point)
+{
+    if (needsCursorRectsSupportAtPoint(self, point))
+        oldSetCursorForMouseLocationIMP(self, cmd, point);
+}
+
+#else
+
+static IMP oldResetCursorRectsIMP;
+static IMP oldSetCursorIMP;
 static BOOL canSetCursor = YES;
 
 static void resetCursorRects(NSWindow* self, SEL cmd)
 {
-    NSPoint point = [self mouseLocationOutsideOfEventStream];
-    NSView* view = [[self _web_borderView] hitTest:point];
-    if ([view isKindOfClass:[WebHTMLView class]]) {
-        WebHTMLView *htmlView = (WebHTMLView*)view;
-        NSPoint localPoint = [htmlView convertPoint:point fromView:nil];
-        NSDictionary *dict = [htmlView elementAtPoint:localPoint allowShadowContent:NO];
-        DOMElement *element = [dict objectForKey:WebElementDOMNodeKey];
-        if (![element isKindOfClass:[DOMHTMLAppletElement class]] && ![element isKindOfClass:[DOMHTMLObjectElement class]] &&
-            ![element isKindOfClass:[DOMHTMLEmbedElement class]])
-            canSetCursor = NO;
-    }
+    canSetCursor = needsCursorRectsSupportAtPoint(self, [self mouseLocationOutsideOfEventStream]);
     oldResetCursorRectsIMP(self, cmd);
     canSetCursor = YES;
 }
@@ -178,23 +204,6 @@ static void setCursor(NSCursor* self, SEL cmd)
         oldSetCursorIMP(self, cmd);
 }
 
-#else
-
-static void setCursor(NSWindow* self, SEL cmd, NSPoint point)
-{
-    NSView* view = [[self _web_borderView] hitTest:point];
-    if ([view isKindOfClass:[WebHTMLView class]]) {
-        WebHTMLView *htmlView = (WebHTMLView*)view;
-        NSPoint localPoint = [htmlView convertPoint:point fromView:nil];
-        NSDictionary *dict = [htmlView elementAtPoint:localPoint allowShadowContent:NO];
-        DOMElement *element = [dict objectForKey:WebElementDOMNodeKey];
-        if (![element isKindOfClass:[DOMHTMLAppletElement class]] && ![element isKindOfClass:[DOMHTMLObjectElement class]] &&
-            ![element isKindOfClass:[DOMHTMLEmbedElement class]])
-            return;
-    }
-    oldSetCursorIMP(self, cmd, point);
-}
-
 #endif
 
 extern "C" {
@@ -294,14 +303,6 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
 @implementation WebCoreScrollView
 @end
 
-// if YES, do the standard NSView hit test (which can't give the right result when HTML overlaps a view)
-static BOOL forceNSViewHitTest;
-
-// if YES, do the "top WebHTMLView" hit test (which we'd like to do all the time but can't because of Java requirements [see bug 4349721])
-static BOOL forceWebHTMLViewHitTest;
-
-static WebHTMLView *lastHitView;
-
 // We need this to be able to safely reference the CachedImage for the promised drag data
 static CachedResourceClient* promisedDataClient()
 {
@@ -490,20 +491,21 @@ static NSCellStateValue kit(TriState state)
 #ifndef BUILDING_ON_TIGER
     WebCoreObjCFinalizeOnMainThread(self);
 #endif
-
+    
+#ifndef BUILDING_ON_TIGER
+    if (!oldSetCursorForMouseLocationIMP) {
+        Method setCursorMethod = class_getInstanceMethod([NSWindow class], @selector(_setCursorForMouseLocation:));
+        ASSERT(setCursorMethod);
+        oldSetCursorForMouseLocationIMP = method_setImplementation(setCursorMethod, (IMP)setCursor);
+        ASSERT(oldSetCursorForMouseLocationIMP);
+    }
+#else
     if (!oldSetCursorIMP) {
-#ifdef BUILDING_ON_TIGER
         Method setCursorMethod = class_getInstanceMethod([NSCursor class], @selector(set));
-#else
-        Method setCursorMethod = class_getInstanceMethod([NSWindow class], @selector(_setCursorForMouseLocation:));
-#endif
         ASSERT(setCursorMethod);
-
         oldSetCursorIMP = method_setImplementation(setCursorMethod, (IMP)setCursor);
         ASSERT(oldSetCursorIMP);
     }
-    
-#ifdef BUILDING_ON_TIGER
     if (!oldResetCursorRectsIMP) {
         Method resetCursorRectsMethod = class_getInstanceMethod([NSWindow class], @selector(resetCursorRects));
         ASSERT(resetCursorRectsMethod);
@@ -1421,6 +1423,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     else if (forceWebHTMLViewHitTest)
         captureHitsOnSubviews = YES;
     else {
+        // FIXME: Why doesn't this include mouse entered/exited events, or other mouse button events?
         NSEvent *event = [[self window] currentEvent];
         captureHitsOnSubviews = !([event type] == NSMouseMoved
             || [event type] == NSRightMouseDown

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list