<!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>[196253] trunk/Source</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/196253">196253</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-02-08 08:59:39 -0800 (Mon, 08 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GTK] WebKitWebView should send crossing events to the WebProcess
https://bugs.webkit.org/show_bug.cgi?id=153740

Reviewed by Michael Catanzaro.

Source/WebCore:

Update the target element under the mouse also when only updating
scrollbars, so that if the mouse enters the page when the window
is not active, the scroll animator is notified that the mouse
entered the scrollable area.

* page/EventHandler.cpp:
(WebCore::EventHandler::handleMouseMoveEvent): Call
updateMouseEventTargetNode() before early returning in case of
only updating scrollbars.

Source/WebKit2:

We don't currently handle crossing events in the web view
(enter/leave). That's why if you hover a scrollbar and leave the
window, the scrollbar is still rendered as hovered.

* Shared/gtk/WebEventFactory.cpp:
(WebKit::buttonForEvent): Handle the case of GDK_ENTER_NOTIFY and
GDK_LEAVE_NOTIFY events.
(WebKit::WebEventFactory::createWebMouseEvent): Ditto.
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseRealize): Add GDK_ENTER_NOTIFY_MASK and
GDK_LEAVE_NOTIFY_MASK flags to the web view event mask.
(webkitWebViewBaseCrossingNotifyEvent): Handle enter/leave notify
events by generating a mouse move event, ensuring the double to
int conversion will not cause any problem.
(webkit_web_view_base_class_init): Add an implementation for
enter_notify_event and leave_notify_event.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageEventHandlercpp">trunk/Source/WebCore/page/EventHandler.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedgtkWebEventFactorycpp">trunk/Source/WebKit2/Shared/gtk/WebEventFactory.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp">trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196252 => 196253)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-08 16:46:12 UTC (rev 196252)
+++ trunk/Source/WebCore/ChangeLog        2016-02-08 16:59:39 UTC (rev 196253)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-02-08  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] WebKitWebView should send crossing events to the WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=153740
+
+        Reviewed by Michael Catanzaro.
+
+        Update the target element under the mouse also when only updating
+        scrollbars, so that if the mouse enters the page when the window
+        is not active, the scroll animator is notified that the mouse
+        entered the scrollable area.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleMouseMoveEvent): Call
+        updateMouseEventTargetNode() before early returning in case of
+        only updating scrollbars.
+
</ins><span class="cx"> 2016-02-08  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WebVideoFullscreenInterface should handle video resizing.
</span></span></pre></div>
<a id="trunkSourceWebCorepageEventHandlercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EventHandler.cpp (196252 => 196253)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EventHandler.cpp        2016-02-08 16:46:12 UTC (rev 196252)
+++ trunk/Source/WebCore/page/EventHandler.cpp        2016-02-08 16:59:39 UTC (rev 196253)
</span><span class="lines">@@ -1882,8 +1882,10 @@
</span><span class="cx">         if (!m_mousePressed &amp;&amp; scrollbar)
</span><span class="cx">             scrollbar-&gt;mouseMoved(platformMouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
</span><span class="cx"> #endif
</span><del>-        if (onlyUpdateScrollbars)
</del><ins>+        if (onlyUpdateScrollbars) {
+            updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
</ins><span class="cx">             return true;
</span><ins>+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool swallowEvent = false;
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (196252 => 196253)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-02-08 16:46:12 UTC (rev 196252)
+++ trunk/Source/WebKit2/ChangeLog        2016-02-08 16:59:39 UTC (rev 196253)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-02-08  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] WebKitWebView should send crossing events to the WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=153740
+
+        Reviewed by Michael Catanzaro.
+
+        We don't currently handle crossing events in the web view
+        (enter/leave). That's why if you hover a scrollbar and leave the
+        window, the scrollbar is still rendered as hovered.
+
+        * Shared/gtk/WebEventFactory.cpp:
+        (WebKit::buttonForEvent): Handle the case of GDK_ENTER_NOTIFY and
+        GDK_LEAVE_NOTIFY events.
+        (WebKit::WebEventFactory::createWebMouseEvent): Ditto.
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseRealize): Add GDK_ENTER_NOTIFY_MASK and
+        GDK_LEAVE_NOTIFY_MASK flags to the web view event mask.
+        (webkitWebViewBaseCrossingNotifyEvent): Handle enter/leave notify
+        events by generating a mouse move event, ensuring the double to
+        int conversion will not cause any problem.
+        (webkit_web_view_base_class_init): Add an implementation for
+        enter_notify_event and leave_notify_event.
+
</ins><span class="cx"> 2016-02-06  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Call CFRelease() on SecRequirementRef when no longer needed
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedgtkWebEventFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/gtk/WebEventFactory.cpp (196252 => 196253)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/gtk/WebEventFactory.cpp        2016-02-08 16:46:12 UTC (rev 196252)
+++ trunk/Source/WebKit2/Shared/gtk/WebEventFactory.cpp        2016-02-08 16:59:39 UTC (rev 196253)
</span><span class="lines">@@ -72,15 +72,20 @@
</span><span class="cx">     unsigned button = 0;
</span><span class="cx"> 
</span><span class="cx">     switch (event-&gt;type) {
</span><del>-    case GDK_MOTION_NOTIFY:
</del><ins>+    case GDK_ENTER_NOTIFY:
+    case GDK_LEAVE_NOTIFY:
+    case GDK_MOTION_NOTIFY: {
</ins><span class="cx">         button = WebMouseEvent::NoButton;
</span><del>-        if (event-&gt;motion.state &amp; GDK_BUTTON1_MASK)
</del><ins>+        GdkModifierType state;
+        gdk_event_get_state(event, &amp;state);
+        if (state &amp; GDK_BUTTON1_MASK)
</ins><span class="cx">             button = WebMouseEvent::LeftButton;
</span><del>-        else if (event-&gt;motion.state &amp; GDK_BUTTON2_MASK)
</del><ins>+        else if (state &amp; GDK_BUTTON2_MASK)
</ins><span class="cx">             button = WebMouseEvent::MiddleButton;
</span><del>-        else if (event-&gt;motion.state &amp; GDK_BUTTON3_MASK)
</del><ins>+        else if (state &amp; GDK_BUTTON3_MASK)
</ins><span class="cx">             button = WebMouseEvent::RightButton;
</span><span class="cx">         break;
</span><ins>+    }
</ins><span class="cx">     case GDK_BUTTON_PRESS:
</span><span class="cx">     case GDK_2BUTTON_PRESS:
</span><span class="cx">     case GDK_3BUTTON_PRESS:
</span><span class="lines">@@ -108,6 +113,8 @@
</span><span class="cx">     WebEvent::Type type = static_cast&lt;WebEvent::Type&gt;(0);
</span><span class="cx">     switch (event-&gt;type) {
</span><span class="cx">     case GDK_MOTION_NOTIFY:
</span><ins>+    case GDK_ENTER_NOTIFY:
+    case GDK_LEAVE_NOTIFY:
</ins><span class="cx">         type = WebEvent::MouseMove;
</span><span class="cx">         break;
</span><span class="cx">     case GDK_BUTTON_PRESS:
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (196252 => 196253)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-02-08 16:46:12 UTC (rev 196252)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-02-08 16:59:39 UTC (rev 196253)
</span><span class="lines">@@ -358,6 +358,8 @@
</span><span class="cx">         | GDK_SCROLL_MASK
</span><span class="cx">         | GDK_SMOOTH_SCROLL_MASK
</span><span class="cx">         | GDK_POINTER_MOTION_MASK
</span><ins>+        | GDK_ENTER_NOTIFY_MASK
+        | GDK_LEAVE_NOTIFY_MASK
</ins><span class="cx">         | GDK_KEY_PRESS_MASK
</span><span class="cx">         | GDK_KEY_RELEASE_MASK
</span><span class="cx">         | GDK_BUTTON_MOTION_MASK
</span><span class="lines">@@ -834,6 +836,47 @@
</span><span class="cx">     return FALSE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static gboolean webkitWebViewBaseCrossingNotifyEvent(GtkWidget* widget, GdkEventCrossing* crosssingEvent)
+{
+    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
+    WebKitWebViewBasePrivate* priv = webViewBase-&gt;priv;
+
+    if (priv-&gt;authenticationDialog)
+        return FALSE;
+
+    // In the case of crossing events, it's very important the actual coordinates the WebProcess receives, because once the mouse leaves
+    // the web view, the WebProcess won't receive more events until the mouse enters again in the web view. So, if the coordinates of the leave
+    // event are not accurate, the WebProcess might not know the mouse left the view. This can happen because of double to integer conversion,
+    // if the coordinates of the leave event are for example (25.2, -0.9), the WebProcess will receive (25, 0) and any hit test will succeed
+    // because those coordinates are inside the web view.
+    GtkAllocation allocation;
+    gtk_widget_get_allocation(widget, &amp;allocation);
+    double width = allocation.width;
+    double height = allocation.height;
+    double x = crosssingEvent-&gt;x;
+    double y = crosssingEvent-&gt;y;
+    if (x &lt; 0 &amp;&amp; x &gt; -1)
+        x = -1;
+    else if (x &gt;= width &amp;&amp; x &lt; width + 1)
+        x = width + 1;
+    if (y &lt; 0 &amp;&amp; y &gt; -1)
+        y = -1;
+    else if (y &gt;= height &amp;&amp; y &lt; height + 1)
+        y = height + 1;
+
+    GdkEvent* event = reinterpret_cast&lt;GdkEvent*&gt;(crosssingEvent);
+    GUniquePtr&lt;GdkEvent&gt; copiedEvent;
+    if (x != crosssingEvent-&gt;x || y != crosssingEvent-&gt;y) {
+        copiedEvent.reset(gdk_event_copy(event));
+        copiedEvent-&gt;crossing.x = x;
+        copiedEvent-&gt;crossing.y = y;
+    }
+
+    priv-&gt;pageProxy-&gt;handleMouseEvent(NativeWebMouseEvent(copiedEvent ? copiedEvent.get() : event, 0 /* currentClickCount */));
+
+    return FALSE;
+}
+
</ins><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx"> static void appendTouchEvent(Vector&lt;WebPlatformTouchPoint&gt;&amp; touchPoints, const GdkEvent* event, WebPlatformTouchPoint::TouchPointState state)
</span><span class="cx"> {
</span><span class="lines">@@ -1078,6 +1121,8 @@
</span><span class="cx">     widgetClass-&gt;button_release_event = webkitWebViewBaseButtonReleaseEvent;
</span><span class="cx">     widgetClass-&gt;scroll_event = webkitWebViewBaseScrollEvent;
</span><span class="cx">     widgetClass-&gt;motion_notify_event = webkitWebViewBaseMotionNotifyEvent;
</span><ins>+    widgetClass-&gt;enter_notify_event = webkitWebViewBaseCrossingNotifyEvent;
+    widgetClass-&gt;leave_notify_event = webkitWebViewBaseCrossingNotifyEvent;
</ins><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx">     widgetClass-&gt;touch_event = webkitWebViewBaseTouchEvent;
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>