<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[182338] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/182338">182338</a></dd>
<dt>Author</dt> <dd>bdakin@apple.com</dd>
<dt>Date</dt> <dd>2015-04-03 16:52:27 -0700 (Fri, 03 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>https://bugs.webkit.org/show_bug.cgi?id=143387
Improvements to webkitmouseforce web API
-and corresponding-
rdar://problem/20281808
rdar://problem/20281853

Reviewed by Darin Adler.

This patch:
1. Dispatches webkitmouseforceup and webkitmouseforceclick at the right time.
2. Dispatches webkitmouseforcechanged from mousedown all the way through through 
mouseup.
3. Uses force values from pressureChangeWithEvent instead of the immediate action 
gesture recognizer.

Listen for this NSResponder method, and pass the relevant info to WebPageProxy to 
dispatch to the web process.
* UIProcess/API/mac/WKView.mm:
(-[WKView pressureChangeWithEvent:]):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::inputDeviceForceDidChange):
(WebKit::WebPageProxy::immediateActionDidUpdate):
* UIProcess/WebPageProxy.h:

The web process still needs to know when the immediate action gesture recognizer 
is updating, but it doesn’t need the force information. That will come from 
pressureChangeWithEvent.
* UIProcess/mac/WKImmediateActionController.mm:
(-[WKImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):

Cache m_lastForceStage so that we can determine if we are 
transitioning to a new stage.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
* WebProcess/WebPage/WebPage.h:

New message for InputDeviceForceDidChange and modified message for 
ImmediateActionDidUpdate
* WebProcess/WebPage/WebPage.messages.in:

inputDeviceForceDidChange now takes care of dispatching mouseforcechanged, 
mouseforcedown, mouseforceup, and mouseforceclick.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::inputDeviceForceDidChange):

We still need to keep track of the ImmediateActionStages in WebCore::EventHandler 
so that we can have the right default behavior on mouseup based on whether or not 
that action began and was completed. (In other words, to ensure we don’t navigate 
to a link after force clicking it.)
(WebKit::WebPage::immediateActionDidUpdate):
(WebKit::WebPage::immediateActionDidComplete):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPImacWKViewmm">trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWKImmediateActionControllermm">trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/ChangeLog        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2015-04-03  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        https://bugs.webkit.org/show_bug.cgi?id=143387
+        Improvements to webkitmouseforce web API
+        -and corresponding-
+        rdar://problem/20281808
+        rdar://problem/20281853
+
+        Reviewed by Darin Adler.
+
+        This patch:
+        1. Dispatches webkitmouseforceup and webkitmouseforceclick at the right time.
+        2. Dispatches webkitmouseforcechanged from mousedown all the way through through 
+        mouseup.
+        3. Uses force values from pressureChangeWithEvent instead of the immediate action 
+        gesture recognizer.
+
+        Listen for this NSResponder method, and pass the relevant info to WebPageProxy to 
+        dispatch to the web process.
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView pressureChangeWithEvent:]):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::inputDeviceForceDidChange):
+        (WebKit::WebPageProxy::immediateActionDidUpdate):
+        * UIProcess/WebPageProxy.h:
+
+        The web process still needs to know when the immediate action gesture recognizer 
+        is updating, but it doesn’t need the force information. That will come from 
+        pressureChangeWithEvent.
+        * UIProcess/mac/WKImmediateActionController.mm:
+        (-[WKImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):
+
+        Cache m_lastForceStage so that we can determine if we are 
+        transitioning to a new stage.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        * WebProcess/WebPage/WebPage.h:
+
+        New message for InputDeviceForceDidChange and modified message for 
+        ImmediateActionDidUpdate
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        inputDeviceForceDidChange now takes care of dispatching mouseforcechanged, 
+        mouseforcedown, mouseforceup, and mouseforceclick.
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::inputDeviceForceDidChange):
+
+        We still need to keep track of the ImmediateActionStages in WebCore::EventHandler 
+        so that we can have the right default behavior on mouseup based on whether or not 
+        that action began and was completed. (In other words, to ensure we don’t navigate 
+        to a link after force clicking it.)
+        (WebKit::WebPage::immediateActionDidUpdate):
+        (WebKit::WebPage::immediateActionDidComplete):
+
</ins><span class="cx"> 2015-04-03  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         InjectedBundleNodeHandle::renderedImage() needs to be exposed from the Cocoa WebAPI layer.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -1392,6 +1392,13 @@
</span><span class="cx">     [self mouseDraggedInternal:event];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
+- (void)pressureChangeWithEvent:(NSEvent *)event
+{
+    _data-&gt;_page-&gt;inputDeviceForceDidChange(event.pressure, event.stage);
+}
+#endif
+
</ins><span class="cx"> - (BOOL)acceptsFirstMouse:(NSEvent *)event
</span><span class="cx"> {
</span><span class="cx">     // There's a chance that responding to this event will run a nested event loop, and
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -5625,11 +5625,16 @@
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::FocusAndSelectLastActionMenuHitTestResult(), m_pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::immediateActionDidUpdate(float force)
</del><ins>+void WebPageProxy::inputDeviceForceDidChange(float force, int stage)
</ins><span class="cx"> {
</span><del>-    m_process-&gt;send(Messages::WebPage::ImmediateActionDidUpdate(force), m_pageID);
</del><ins>+    m_process-&gt;send(Messages::WebPage::InputDeviceForceDidChange(force, stage), m_pageID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::immediateActionDidUpdate()
+{
+    m_process-&gt;send(Messages::WebPage::ImmediateActionDidUpdate(), m_pageID);
+}
+
</ins><span class="cx"> void WebPageProxy::immediateActionDidCancel()
</span><span class="cx"> {
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::ImmediateActionDidCancel(), m_pageID);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -992,7 +992,8 @@
</span><span class="cx">     void selectLastActionMenuRange();
</span><span class="cx">     void focusAndSelectLastActionMenuHitTestResult();
</span><span class="cx"> 
</span><del>-    void immediateActionDidUpdate(float force);
</del><ins>+    void inputDeviceForceDidChange(float force, int stage);
+    void immediateActionDidUpdate();
</ins><span class="cx">     void immediateActionDidCancel();
</span><span class="cx">     void immediateActionDidComplete();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWKImmediateActionControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx">     if (immediateActionRecognizer != _immediateActionRecognizer)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    _page-&gt;immediateActionDidUpdate([immediateActionRecognizer animationProgress]);
</del><ins>+    _page-&gt;immediateActionDidUpdate();
</ins><span class="cx">     if (_hitTestResult.contentPreventsDefault)
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -1088,7 +1088,8 @@
</span><span class="cx">     PassRefPtr&lt;WebCore::Range&gt; lookupTextAtLocation(WebCore::FloatPoint, NSDictionary **options);
</span><span class="cx">     void selectLastActionMenuRange();
</span><span class="cx">     void focusAndSelectLastActionMenuHitTestResult();
</span><del>-    void immediateActionDidUpdate(float force);
</del><ins>+    void inputDeviceForceDidChange(float force, int stage);
+    void immediateActionDidUpdate();
</ins><span class="cx">     void immediateActionDidCancel();
</span><span class="cx">     void immediateActionDidComplete();
</span><span class="cx">     void setFont(const String&amp; fontFamily, double fontSize, uint64_t fontTraits);
</span><span class="lines">@@ -1347,6 +1348,7 @@
</span><span class="cx">     WebCore::HitTestResult m_lastActionMenuHitTestResult;
</span><span class="cx">     RefPtr&lt;WebPageOverlay&gt; m_lastActionMenuHitPageOverlay;
</span><span class="cx">     bool m_lastActionMenuHitTestPreventsDefault;
</span><ins>+    int m_lastForceStage { 0 };
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool m_mainFrameProgressCompleted;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -406,7 +406,8 @@
</span><span class="cx">     PerformActionMenuHitTestAtLocation(WebCore::FloatPoint location, bool forImmediateAction)
</span><span class="cx">     SelectLastActionMenuRange()
</span><span class="cx">     FocusAndSelectLastActionMenuHitTestResult()
</span><del>-    ImmediateActionDidUpdate(float force)
</del><ins>+    InputDeviceForceDidChange(float force, int stage)
+    ImmediateActionDidUpdate()
</ins><span class="cx">     ImmediateActionDidCancel()
</span><span class="cx">     ImmediateActionDidComplete()
</span><span class="cx">     DataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (182337 => 182338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-04-03 22:52:00 UTC (rev 182337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-04-03 23:52:27 UTC (rev 182338)
</span><span class="lines">@@ -1156,10 +1156,8 @@
</span><span class="cx">     frame-&gt;selection().setSelection(position);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::immediateActionDidUpdate(float force)
</del><ins>+void WebPage::inputDeviceForceDidChange(float force, int stage)
</ins><span class="cx"> {
</span><del>-    m_page-&gt;mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionUpdated);
-
</del><span class="cx">     Element* element = m_lastActionMenuHitTestResult.innerElement();
</span><span class="cx">     if (!element)
</span><span class="cx">         return;
</span><span class="lines">@@ -1167,9 +1165,24 @@
</span><span class="cx">     if (!m_lastActionMenuHitTestPreventsDefault)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    element-&gt;dispatchMouseForceChanged(force, m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
</del><ins>+    float overallForce = stage &lt; 1 ? force : force + stage - 1;
+    element-&gt;dispatchMouseForceChanged(overallForce, m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
+
+    if (m_lastForceStage == 1 &amp;&amp; stage == 2)
+        element-&gt;dispatchMouseForceDown(m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
+    else if (m_lastForceStage == 2 &amp;&amp; stage == 1) {
+        element-&gt;dispatchMouseForceUp(m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
+        element-&gt;dispatchMouseForceClick(m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
+    }
+
+    m_lastForceStage = stage;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::immediateActionDidUpdate()
+{
+    m_page-&gt;mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionUpdated);
+}
+
</ins><span class="cx"> void WebPage::immediateActionDidCancel()
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCancelled);
</span><span class="lines">@@ -1187,15 +1200,6 @@
</span><span class="cx"> void WebPage::immediateActionDidComplete()
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCompleted);
</span><del>-
-    Element* element = m_lastActionMenuHitTestResult.innerElement();
-    if (!element)
-        return;
-
-    if (!m_lastActionMenuHitTestPreventsDefault)
-        return;
-
-    element-&gt;dispatchMouseForceDown(m_page-&gt;mainFrame().eventHandler().lastMouseDownEvent());
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::dataDetectorsDidPresentUI(PageOverlay::PageOverlayID overlayID)
</span></span></pre>
</div>
</div>

</body>
</html>