PDFPlugin: Cursor should become an i-beam when over selectable text
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 05:30:36 +0000 (05:30 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 05:30:36 +0000 (05:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=115018
<rdar://problem/12645012>

Reviewed by Alexey Proskuryakov.

* WebProcess/Plugins/PDF/PDFPlugin.h:
Add updateCursor(), the UpdateCursorMode and HitTestResult enums, and
storage for the last PDF hit test result.
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::updateCursor):
Hit test the PDF. If there is a word under the cursor, use the I-beam cursor,
otherwise, use the default pointer cursor. This approximates PDFKit's behavior,
though does not match it precisely in the case of annotations.
Only send the cursor update to the UIProcess if it is a change, or if
we're explicitly asked to update.
(WebKit::PDFPlugin::handleMouseEvent):
If we're processing a mouse moved event, update the cursor if needed.
(WebKit::PDFPlugin::handleMouseEnterEvent):
If the cursor just moved over the PDFPlugin, force-update the cursor,
even if it matches the previously-set cursor (because something else
likely updated the cursor while it was not over the PDFPlugin).

* WebCore.exp.in: Export the I-beam and arrow cursors.

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

Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm

index 6251ad3..5289598 100644 (file)
@@ -1,3 +1,13 @@
+2013-04-24  Tim Horton  <timothy_horton@apple.com>
+
+        PDFPlugin: Cursor should become an i-beam when over selectable text
+        https://bugs.webkit.org/show_bug.cgi?id=115018
+        <rdar://problem/12645012>
+
+        Reviewed by Alexey Proskuryakov.
+
+        * WebCore.exp.in: Export the I-beam and arrow cursors.
+
 2013-04-24  Simon Fraser  <simon.fraser@apple.com>
 
         Garbage at the top of http://www.technologyreview.com after scrolling
index 9382d18..015c743 100644 (file)
@@ -179,6 +179,7 @@ __ZN7WebCore11PageConsole21shouldPrintExceptionsEv
 __ZN7WebCore11PageConsole24setShouldPrintExceptionsEb
 __ZN7WebCore11URLWithDataEP6NSDataP5NSURL
 __ZN7WebCore11memoryCacheEv
+__ZN7WebCore11iBeamCursorEv
 __ZN7WebCore11startOfWordERKNS_15VisiblePositionENS_9EWordSideE
 __ZN7WebCore11writeToFileEiPKci
 __ZN7WebCore12ChromeClient23paintCustomOverhangAreaEPNS_15GraphicsContextERKNS_7IntRectES5_S5_
@@ -264,6 +265,7 @@ __ZN7WebCore13KeyboardEventC1ERKNS_21PlatformKeyboardEventEPNS_9DOMWindowE
 __ZN7WebCore13NodeTraversal19nextAncestorSiblingEPKNS_4NodeE
 __ZN7WebCore13NodeTraversal8previousEPKNS_4NodeES3_
 __ZN7WebCore13QualifiedNameD1Ev
+__ZN7WebCore13pointerCursorEv
 __ZN7WebCore13ResourceErrorC1EP7NSError
 __ZN7WebCore13ResourceErrorC1EP9__CFError
 __ZN7WebCore13StyledElement22setInlineStylePropertyENS_13CSSPropertyIDERKN3WTF6StringEb
index 68eb4d5..95296de 100644 (file)
@@ -1,5 +1,30 @@
 2013-04-24  Tim Horton  <timothy_horton@apple.com>
 
+        PDFPlugin: Cursor should become an i-beam when over selectable text
+        https://bugs.webkit.org/show_bug.cgi?id=115018
+        <rdar://problem/12645012>
+
+        Reviewed by Alexey Proskuryakov.
+
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        Add updateCursor(), the UpdateCursorMode and HitTestResult enums, and
+        storage for the last PDF hit test result.
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::updateCursor):
+        Hit test the PDF. If there is a word under the cursor, use the I-beam cursor,
+        otherwise, use the default pointer cursor. This approximates PDFKit's behavior,
+        though does not match it precisely in the case of annotations.
+        Only send the cursor update to the UIProcess if it is a change, or if
+        we're explicitly asked to update.
+        (WebKit::PDFPlugin::handleMouseEvent):
+        If we're processing a mouse moved event, update the cursor if needed.
+        (WebKit::PDFPlugin::handleMouseEnterEvent):
+        If the cursor just moved over the PDFPlugin, force-update the cursor,
+        even if it matches the previously-set cursor (because something else
+        likely updated the cursor while it was not over the PDFPlugin).
+
+2013-04-24  Tim Horton  <timothy_horton@apple.com>
+
         Page Overlays shouldn't waste time flushing layers if we're not going to use it
         https://bugs.webkit.org/show_bug.cgi?id=115145
 
index 3283936..71b78dc 100644 (file)
@@ -105,6 +105,8 @@ private:
     virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) OVERRIDE;
     virtual void contentsScaleFactorChanged(float) OVERRIDE;
     virtual bool handleMouseEvent(const WebMouseEvent&) OVERRIDE;
+    virtual bool handleMouseEnterEvent(const WebMouseEvent&) OVERRIDE;
+    virtual bool handleMouseLeaveEvent(const WebMouseEvent&) OVERRIDE;
     virtual bool handleContextMenuEvent(const WebMouseEvent&) OVERRIDE;
     virtual bool handleKeyboardEvent(const WebKeyboardEvent&) OVERRIDE;
     virtual bool handleEditingCommand(const String& commandName, const String& argument) OVERRIDE;
@@ -140,6 +142,18 @@ private:
 
     WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
 
+    enum UpdateCursorMode {
+        UpdateIfNeeded,
+        ForceUpdate
+    };
+
+    enum HitTestResult {
+        None,
+        Text
+    };
+
+    void updateCursor(const WebMouseEvent&, UpdateCursorMode = UpdateIfNeeded);
+
     RetainPtr<CALayer> m_containerLayer;
     RetainPtr<CALayer> m_contentLayer;
     RetainPtr<CALayer> m_horizontalScrollbarLayer;
@@ -158,6 +172,8 @@ private:
     String m_temporaryPDFUUID;
 
     String m_lastFoundString;
+
+    HitTestResult m_lastHitTestResult;
     
     RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate;
 };
index 2aac55a..0a0fe22 100644 (file)
@@ -39,6 +39,7 @@
 #import "PDFPluginPasswordField.h"
 #import "PluginView.h"
 #import "WebContextMessages.h"
+#import "WebCoreArgumentCoders.h"
 #import "WebEvent.h"
 #import "WebEventConversion.h"
 #import "WebPage.h"
@@ -46,6 +47,7 @@
 #import "WebProcess.h"
 #import <PDFKit/PDFKit.h>
 #import <QuartzCore/QuartzCore.h>
+#import <WebCore/Cursor.h>
 #import <WebCore/FocusController.h>
 #import <WebCore/FormState.h>
 #import <WebCore/Frame.h>
@@ -570,6 +572,21 @@ NSEvent *PDFPlugin::nsEventForWebMouseEvent(const WebMouseEvent& event)
     return [NSEvent mouseEventWithType:eventType location:positionInPDFViewCoordinates modifierFlags:modifierFlags timestamp:0 windowNumber:0 context:nil eventNumber:0 clickCount:event.clickCount() pressure:0];
 }
 
+void PDFPlugin::updateCursor(const WebMouseEvent& event, UpdateCursorMode mode)
+{
+    HitTestResult hitTestResult = None;
+
+    PDFSelection *selectionUnderMouse = [m_pdfLayerController.get() getSelectionForWordAtPoint:convertFromPluginToPDFView(event.position())];
+    if (selectionUnderMouse && [[selectionUnderMouse string] length])
+        hitTestResult = Text;
+
+    if (hitTestResult == m_lastHitTestResult && mode == UpdateIfNeeded)
+        return;
+
+    webFrame()->page()->send(Messages::WebPageProxy::SetCursor(hitTestResult == Text ? iBeamCursor() : pointerCursor()));
+    m_lastHitTestResult = hitTestResult;
+}
+
 bool PDFPlugin::handleMouseEvent(const WebMouseEvent& event)
 {
     PlatformMouseEvent platformEvent = platform(event);
@@ -611,6 +628,7 @@ bool PDFPlugin::handleMouseEvent(const WebMouseEvent& event)
     switch (event.type()) {
     case WebEvent::MouseMove:
         mouseMovedInContentArea();
+        updateCursor(event);
 
         if (targetScrollbar) {
             if (!targetScrollbarForLastMousePosition) {
@@ -668,6 +686,19 @@ bool PDFPlugin::handleMouseEvent(const WebMouseEvent& event)
 
     return false;
 }
+
+bool PDFPlugin::handleMouseEnterEvent(const WebMouseEvent& event)
+{
+    mouseEnteredContentArea();
+    updateCursor(event, ForceUpdate);
+    return false;
+}
+
+bool PDFPlugin::handleMouseLeaveEvent(const WebMouseEvent&)
+{
+    mouseExitedContentArea();
+    return false;
+}
     
 bool PDFPlugin::handleContextMenuEvent(const WebMouseEvent& event)
 {