Title: [197063] releases/WebKitGTK/webkit-2.10/Source/WebKit2
Revision
197063
Author
carlo...@webkit.org
Date
2016-02-24 23:43:49 -0800 (Wed, 24 Feb 2016)

Log Message

Merge r196062 - [GTK] Reduce IPC traffic due to view state changes
https://bugs.webkit.org/show_bug.cgi?id=153745

Reviewed by Sergio Villar Senin.

Very often view state changes happen one after another in a very
short period of time, even in the same run loop iteration. For
example, when you switch to the web view window, the view is
focused and the active window flag changes as well. In that case
we are sending two messages to the web process and the page
updates its status according to the new flags in two steps. So, we
could group all state changes happening in the same run loop
iteration and notify about them all in the next iteration. This
also prevents unnecessary changes of state when we quickly go back
to a previous state, for example in focus follows mouse
configurations if you move the mouse outside the window and then
inside the window again quickly.

* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(_WebKitWebViewBasePrivate::_WebKitWebViewBasePrivate): Use
VirewState::Flags to keep the web view state instead of
boolean, and also to keep the flags that need to be updated. Use a
timer to update web view state flags.
(_WebKitWebViewBasePrivate::updateViewStateTimerFired): Call
WebPageProxy::viewStateDidChange() and reset the flags that need
to be updated.
(webkitWebViewBaseScheduleUpdateViewState): Update the flags that
need to be updated and schedule the timer if it's not active.
(toplevelWindowFocusInEvent): Use the flags and schedule an update.
(toplevelWindowFocusOutEvent): Ditto.
(toplevelWindowStateEvent): Also mark the view as hidden when minimized.
(webkitWebViewBaseSetToplevelOnScreenWindow): Connect to
window-state-event instead of deprecated visibility-notify-event.
(webkitWebViewBaseMap): Use the flags and schedule an update.
(webkitWebViewBaseUnmap): Ditto.
(webkitWebViewBaseSetFocus): Ditto.
(webkitWebViewBaseIsInWindowActive): Use the flags.
(webkitWebViewBaseIsFocused): Ditto
(webkitWebViewBaseIsVisible): Ditto.
(webkitWebViewBaseIsInWindow): Removed this since it was unused.
* UIProcess/API/gtk/WebKitWebViewBasePrivate.h:

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.10/Source/WebKit2/ChangeLog (197062 => 197063)


--- releases/WebKitGTK/webkit-2.10/Source/WebKit2/ChangeLog	2016-02-25 07:37:40 UTC (rev 197062)
+++ releases/WebKitGTK/webkit-2.10/Source/WebKit2/ChangeLog	2016-02-25 07:43:49 UTC (rev 197063)
@@ -1,3 +1,47 @@
+2016-02-03  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [GTK] Reduce IPC traffic due to view state changes
+        https://bugs.webkit.org/show_bug.cgi?id=153745
+
+        Reviewed by Sergio Villar Senin.
+
+        Very often view state changes happen one after another in a very
+        short period of time, even in the same run loop iteration. For
+        example, when you switch to the web view window, the view is
+        focused and the active window flag changes as well. In that case
+        we are sending two messages to the web process and the page
+        updates its status according to the new flags in two steps. So, we
+        could group all state changes happening in the same run loop
+        iteration and notify about them all in the next iteration. This
+        also prevents unnecessary changes of state when we quickly go back
+        to a previous state, for example in focus follows mouse
+        configurations if you move the mouse outside the window and then
+        inside the window again quickly.
+
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (_WebKitWebViewBasePrivate::_WebKitWebViewBasePrivate): Use
+        VirewState::Flags to keep the web view state instead of
+        boolean, and also to keep the flags that need to be updated. Use a
+        timer to update web view state flags.
+        (_WebKitWebViewBasePrivate::updateViewStateTimerFired): Call
+        WebPageProxy::viewStateDidChange() and reset the flags that need
+        to be updated.
+        (webkitWebViewBaseScheduleUpdateViewState): Update the flags that
+        need to be updated and schedule the timer if it's not active.
+        (toplevelWindowFocusInEvent): Use the flags and schedule an update.
+        (toplevelWindowFocusOutEvent): Ditto.
+        (toplevelWindowStateEvent): Also mark the view as hidden when minimized.
+        (webkitWebViewBaseSetToplevelOnScreenWindow): Connect to
+        window-state-event instead of deprecated visibility-notify-event.
+        (webkitWebViewBaseMap): Use the flags and schedule an update.
+        (webkitWebViewBaseUnmap): Ditto.
+        (webkitWebViewBaseSetFocus): Ditto.
+        (webkitWebViewBaseIsInWindowActive): Use the flags.
+        (webkitWebViewBaseIsFocused): Ditto
+        (webkitWebViewBaseIsVisible): Ditto.
+        (webkitWebViewBaseIsInWindow): Removed this since it was unused.
+        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+
 2016-02-18  Gwang Yoon Hwang  <y...@igalia.com>
 
         [GTK] Limit the number of tiles according to the visible area

Modified: releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (197062 => 197063)


--- releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2016-02-25 07:37:40 UTC (rev 197062)
+++ releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2016-02-25 07:43:49 UTC (rev 197063)
@@ -149,6 +149,19 @@
 typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap;
 
 struct _WebKitWebViewBasePrivate {
+    _WebKitWebViewBasePrivate()
+        : updateViewStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateViewStateTimerFired)
+    {
+    }
+
+    void updateViewStateTimerFired()
+    {
+        if (!pageProxy)
+            return;
+        pageProxy->viewStateDidChange(viewStateFlagsToUpdate);
+        viewStateFlagsToUpdate = ViewState::NoFlags;
+    }
+
     WebKitWebViewChildrenMap children;
     std::unique_ptr<PageClientImpl> pageClient;
     RefPtr<WebPageProxy> pageProxy;
@@ -170,13 +183,12 @@
     GtkWindow* toplevelOnScreenWindow;
     unsigned long toplevelFocusInEventID;
     unsigned long toplevelFocusOutEventID;
-    unsigned long toplevelVisibilityEventID;
+    unsigned long toplevelWindowStateEventID;
 
     // View State.
-    bool isInWindowActive : 1;
-    bool isFocused : 1;
-    bool isVisible : 1;
-    bool isWindowVisible : 1;
+    ViewState::Flags viewState;
+    ViewState::Flags viewStateFlagsToUpdate;
+    RunLoop::Timer<WebKitWebViewBasePrivate> updateViewStateTimer;
 
     WebKitWebViewBaseDownloadRequestHandler downloadHandler;
 
@@ -204,37 +216,56 @@
 
 WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
 
+static void webkitWebViewBaseScheduleUpdateViewState(WebKitWebViewBase* webViewBase, ViewState::Flags flagsToUpdate)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    priv->viewStateFlagsToUpdate |= flagsToUpdate;
+    if (priv->updateViewStateTimer.isActive())
+        return;
+
+    priv->updateViewStateTimer.startOneShot(0);
+}
+
 static gboolean toplevelWindowFocusInEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (!priv->isInWindowActive) {
-        priv->isInWindowActive = true;
-        priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive);
-    }
+    if (priv->viewState & ViewState::WindowIsActive)
+        return FALSE;
 
+    priv->viewState |= ViewState::WindowIsActive;
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive);
+
     return FALSE;
 }
 
 static gboolean toplevelWindowFocusOutEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (priv->isInWindowActive) {
-        priv->isInWindowActive = false;
-        priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive);
-    }
+    if (!(priv->viewState & ViewState::WindowIsActive))
+        return FALSE;
 
+    priv->viewState &= ~ViewState::WindowIsActive;
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive);
+
     return FALSE;
 }
 
-static gboolean toplevelWindowVisibilityEvent(GtkWidget*, GdkEventVisibility* visibilityEvent, WebKitWebViewBase* webViewBase)
+static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    bool isWindowVisible = visibilityEvent->state != GDK_VISIBILITY_FULLY_OBSCURED;
-    if (priv->isWindowVisible != isWindowVisible) {
-        priv->isWindowVisible = isWindowVisible;
-        priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
-    }
+    if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED))
+        return FALSE;
 
+    bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED);
+    if ((visible && priv->viewState & ViewState::IsVisible) || (!visible && !(priv->viewState & ViewState::IsVisible)))
+        return FALSE;
+
+    if (visible)
+        priv->viewState |= ViewState::IsVisible;
+    else
+        priv->viewState &= ~ViewState::IsVisible;
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
+
     return FALSE;
 }
 
@@ -252,13 +283,16 @@
         g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusOutEventID);
         priv->toplevelFocusOutEventID = 0;
     }
-    if (priv->toplevelVisibilityEventID) {
-        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelVisibilityEventID);
-        priv->toplevelVisibilityEventID = 0;
+    if (priv->toplevelWindowStateEventID) {
+        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID);
+        priv->toplevelWindowStateEventID = 0;
     }
 
     priv->toplevelOnScreenWindow = window;
-    priv->pageProxy->viewStateDidChange(ViewState::IsInWindow);
+    if (!(priv->viewState & ViewState::IsInWindow)) {
+        priv->viewState |= ViewState::IsInWindow;
+        webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsInWindow);
+    }
     if (!priv->toplevelOnScreenWindow)
         return;
 
@@ -268,9 +302,8 @@
     priv->toplevelFocusOutEventID =
         g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event",
                          G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase);
-    priv->toplevelVisibilityEventID =
-        g_signal_connect(priv->toplevelOnScreenWindow, "visibility-notify-event",
-                         G_CALLBACK(toplevelWindowVisibilityEvent), webViewBase);
+    priv->toplevelWindowStateEventID =
+        g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase);
 }
 
 static void webkitWebViewBaseRealize(GtkWidget* widget)
@@ -626,21 +659,24 @@
 
     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (!priv->isVisible) {
-        priv->isVisible = true;
-        priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
-    }
+    if (priv->viewState & ViewState::IsVisible)
+        return;
+
+    priv->viewState |= ViewState::IsVisible;
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
 }
 
 static void webkitWebViewBaseUnmap(GtkWidget* widget)
 {
     GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget);
 
-    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    if (priv->isVisible) {
-        priv->isVisible = false;
-        priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
-    }
+    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (!(priv->viewState & ViewState::IsVisible))
+        return;
+
+    priv->viewState &= ~ViewState::IsVisible;
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
 }
 
 static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event)
@@ -1333,49 +1369,48 @@
 void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (priv->isFocused == focused)
+    if ((focused && priv->viewState & ViewState::IsFocused) || (!focused && !(priv->viewState & ViewState::IsFocused)))
         return;
 
-    unsigned viewStateFlags = ViewState::IsFocused;
-    priv->isFocused = focused;
+    ViewState::Flags flagsToUpdate = ViewState::IsFocused;
+    if (focused) {
+        priv->viewState |= ViewState::IsFocused;
 
-    // If the view has received the focus and the window is not active
-    // mark the current window as active now. This can happen if the
-    // toplevel window is a GTK_WINDOW_POPUP and the focus has been
-    // set programatically like WebKitTestRunner does, because POPUP
-    // can't be focused.
-    if (priv->isFocused && !priv->isInWindowActive) {
-        priv->isInWindowActive = true;
-        viewStateFlags |= ViewState::WindowIsActive;
-    }
-    priv->pageProxy->viewStateDidChange(viewStateFlags);
+        // If the view has received the focus and the window is not active
+        // mark the current window as active now. This can happen if the
+        // toplevel window is a GTK_WINDOW_POPUP and the focus has been
+        // set programatically like WebKitTestRunner does, because POPUP
+        // can't be focused.
+        if (!(priv->viewState & ViewState::WindowIsActive)) {
+            priv->viewState |= ViewState::WindowIsActive;
+            flagsToUpdate |= ViewState::WindowIsActive;
+        }
+    } else
+        priv->viewState &= ~ViewState::IsFocused;
+
+    webkitWebViewBaseScheduleUpdateViewState(webViewBase, flagsToUpdate);
 }
 
 bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase)
 {
-    return webViewBase->priv->isInWindowActive;
+    return webViewBase->priv->viewState & ViewState::WindowIsActive;
 }
 
 bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase)
 {
-    return webViewBase->priv->isFocused;
+    return webViewBase->priv->viewState & ViewState::IsFocused;
 }
 
 bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase)
 {
-    return webViewBase->priv->isVisible;
+    return webViewBase->priv->viewState & ViewState::IsVisible;
 }
 
 bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase)
 {
-    return webViewBase->priv->toplevelOnScreenWindow;
+    return webViewBase->priv->viewState & ViewState::IsInWindow;
 }
 
-bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase* webViewBase)
-{
-    return webViewBase->priv->isWindowVisible;
-}
-
 void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase* webViewBase, WebKitWebViewBaseDownloadRequestHandler downloadHandler)
 {
     webViewBase->priv->downloadHandler = downloadHandler;

Modified: releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h (197062 => 197063)


--- releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2016-02-25 07:37:40 UTC (rev 197062)
+++ releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2016-02-25 07:43:49 UTC (rev 197063)
@@ -59,7 +59,6 @@
 bool webkitWebViewBaseIsFocused(WebKitWebViewBase*);
 bool webkitWebViewBaseIsVisible(WebKitWebViewBase*);
 bool webkitWebViewBaseIsInWindow(WebKitWebViewBase*);
-bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase*);
 
 typedef void (*WebKitWebViewBaseDownloadRequestHandler) (WebKitWebViewBase*, WebKit::DownloadProxy*);
 void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase*, WebKitWebViewBaseDownloadRequestHandler);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to