⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 197063 in webkit


Ignore:
Timestamp:
Feb 24, 2016, 11:43:49 PM (11 years ago)
Author:
Carlos Garcia Campos
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:
Location:
releases/WebKitGTK/webkit-2.10/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.10/Source/WebKit2/ChangeLog

    r196932 r197063  
     12016-02-03  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Reduce IPC traffic due to view state changes
     4        https://bugs.webkit.org/show_bug.cgi?id=153745
     5
     6        Reviewed by Sergio Villar Senin.
     7
     8        Very often view state changes happen one after another in a very
     9        short period of time, even in the same run loop iteration. For
     10        example, when you switch to the web view window, the view is
     11        focused and the active window flag changes as well. In that case
     12        we are sending two messages to the web process and the page
     13        updates its status according to the new flags in two steps. So, we
     14        could group all state changes happening in the same run loop
     15        iteration and notify about them all in the next iteration. This
     16        also prevents unnecessary changes of state when we quickly go back
     17        to a previous state, for example in focus follows mouse
     18        configurations if you move the mouse outside the window and then
     19        inside the window again quickly.
     20
     21        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
     22        (_WebKitWebViewBasePrivate::_WebKitWebViewBasePrivate): Use
     23        VirewState::Flags to keep the web view state instead of
     24        boolean, and also to keep the flags that need to be updated. Use a
     25        timer to update web view state flags.
     26        (_WebKitWebViewBasePrivate::updateViewStateTimerFired): Call
     27        WebPageProxy::viewStateDidChange() and reset the flags that need
     28        to be updated.
     29        (webkitWebViewBaseScheduleUpdateViewState): Update the flags that
     30        need to be updated and schedule the timer if it's not active.
     31        (toplevelWindowFocusInEvent): Use the flags and schedule an update.
     32        (toplevelWindowFocusOutEvent): Ditto.
     33        (toplevelWindowStateEvent): Also mark the view as hidden when minimized.
     34        (webkitWebViewBaseSetToplevelOnScreenWindow): Connect to
     35        window-state-event instead of deprecated visibility-notify-event.
     36        (webkitWebViewBaseMap): Use the flags and schedule an update.
     37        (webkitWebViewBaseUnmap): Ditto.
     38        (webkitWebViewBaseSetFocus): Ditto.
     39        (webkitWebViewBaseIsInWindowActive): Use the flags.
     40        (webkitWebViewBaseIsFocused): Ditto
     41        (webkitWebViewBaseIsVisible): Ditto.
     42        (webkitWebViewBaseIsInWindow): Removed this since it was unused.
     43        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
     44
    1452016-02-18  Gwang Yoon Hwang  <yoon@igalia.com>
    246
  • releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp

    r196924 r197063  
    150150
    151151struct _WebKitWebViewBasePrivate {
     152    _WebKitWebViewBasePrivate()
     153        : updateViewStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateViewStateTimerFired)
     154    {
     155    }
     156
     157    void updateViewStateTimerFired()
     158    {
     159        if (!pageProxy)
     160            return;
     161        pageProxy->viewStateDidChange(viewStateFlagsToUpdate);
     162        viewStateFlagsToUpdate = ViewState::NoFlags;
     163    }
     164
    152165    WebKitWebViewChildrenMap children;
    153166    std::unique_ptr<PageClientImpl> pageClient;
    … …  
    171184    unsigned long toplevelFocusInEventID;
    172185    unsigned long toplevelFocusOutEventID;
    173     unsigned long toplevelVisibilityEventID;
     186    unsigned long toplevelWindowStateEventID;
    174187
    175188    // View State.
    176     bool isInWindowActive : 1;
    177     bool isFocused : 1;
    178     bool isVisible : 1;
    179     bool isWindowVisible : 1;
     189    ViewState::Flags viewState;
     190    ViewState::Flags viewStateFlagsToUpdate;
     191    RunLoop::Timer<WebKitWebViewBasePrivate> updateViewStateTimer;
    180192
    181193    WebKitWebViewBaseDownloadRequestHandler downloadHandler;
    … …  
    205217WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
    206218
     219static void webkitWebViewBaseScheduleUpdateViewState(WebKitWebViewBase* webViewBase, ViewState::Flags flagsToUpdate)
     220{
     221    WebKitWebViewBasePrivate* priv = webViewBase->priv;
     222    priv->viewStateFlagsToUpdate |= flagsToUpdate;
     223    if (priv->updateViewStateTimer.isActive())
     224        return;
     225
     226    priv->updateViewStateTimer.startOneShot(0);
     227}
     228
    207229static gboolean toplevelWindowFocusInEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase)
    208230{
    209231    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    210     if (!priv->isInWindowActive) {
    211         priv->isInWindowActive = true;
    212         priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive);
    213     }
     232    if (priv->viewState & ViewState::WindowIsActive)
     233        return FALSE;
     234
     235    priv->viewState |= ViewState::WindowIsActive;
     236    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive);
    214237
    215238    return FALSE;
    … …  
    219242{
    220243    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    221     if (priv->isInWindowActive) {
    222         priv->isInWindowActive = false;
    223         priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive);
    224     }
     244    if (!(priv->viewState & ViewState::WindowIsActive))
     245        return FALSE;
     246
     247    priv->viewState &= ~ViewState::WindowIsActive;
     248    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive);
    225249
    226250    return FALSE;
    227251}
    228252
    229 static gboolean toplevelWindowVisibilityEvent(GtkWidget*, GdkEventVisibility* visibilityEvent, WebKitWebViewBase* webViewBase)
    230 {
    231     WebKitWebViewBasePrivate* priv = webViewBase->priv;
    232     bool isWindowVisible = visibilityEvent->state != GDK_VISIBILITY_FULLY_OBSCURED;
    233     if (priv->isWindowVisible != isWindowVisible) {
    234         priv->isWindowVisible = isWindowVisible;
    235         priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
    236     }
     253static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase)
     254{
     255    WebKitWebViewBasePrivate* priv = webViewBase->priv;
     256    if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED))
     257        return FALSE;
     258
     259    bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED);
     260    if ((visible && priv->viewState & ViewState::IsVisible) || (!visible && !(priv->viewState & ViewState::IsVisible)))
     261        return FALSE;
     262
     263    if (visible)
     264        priv->viewState |= ViewState::IsVisible;
     265    else
     266        priv->viewState &= ~ViewState::IsVisible;
     267    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
    237268
    238269    return FALSE;
    … …  
    253284        priv->toplevelFocusOutEventID = 0;
    254285    }
    255     if (priv->toplevelVisibilityEventID) {
    256         g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelVisibilityEventID);
    257         priv->toplevelVisibilityEventID = 0;
     286    if (priv->toplevelWindowStateEventID) {
     287        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID);
     288        priv->toplevelWindowStateEventID = 0;
    258289    }
    259290
    260291    priv->toplevelOnScreenWindow = window;
    261     priv->pageProxy->viewStateDidChange(ViewState::IsInWindow);
     292    if (!(priv->viewState & ViewState::IsInWindow)) {
     293        priv->viewState |= ViewState::IsInWindow;
     294        webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsInWindow);
     295    }
    262296    if (!priv->toplevelOnScreenWindow)
    263297        return;
    … …  
    269303        g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event",
    270304                         G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase);
    271     priv->toplevelVisibilityEventID =
    272         g_signal_connect(priv->toplevelOnScreenWindow, "visibility-notify-event",
    273                          G_CALLBACK(toplevelWindowVisibilityEvent), webViewBase);
     305    priv->toplevelWindowStateEventID =
     306        g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase);
    274307}
    275308
    … …  
    627660    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    628661    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    629     if (!priv->isVisible) {
    630         priv->isVisible = true;
    631         priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
    632     }
     662    if (priv->viewState & ViewState::IsVisible)
     663        return;
     664
     665    priv->viewState |= ViewState::IsVisible;
     666    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
    633667}
    634668
    … …  
    637671    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget);
    638672
    639     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    640     if (priv->isVisible) {
    641         priv->isVisible = false;
    642         priv->pageProxy->viewStateDidChange(ViewState::IsVisible);
    643     }
     673    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     674    WebKitWebViewBasePrivate* priv = webViewBase->priv;
     675    if (!(priv->viewState & ViewState::IsVisible))
     676        return;
     677
     678    priv->viewState &= ~ViewState::IsVisible;
     679    webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible);
    644680}
    645681
    … …  
    13341370{
    13351371    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    1336     if (priv->isFocused == focused)
    1337         return;
    1338 
    1339     unsigned viewStateFlags = ViewState::IsFocused;
    1340     priv->isFocused = focused;
    1341 
    1342     // If the view has received the focus and the window is not active
    1343     // mark the current window as active now. This can happen if the
    1344     // toplevel window is a GTK_WINDOW_POPUP and the focus has been
    1345     // set programatically like WebKitTestRunner does, because POPUP
    1346     // can't be focused.
    1347     if (priv->isFocused && !priv->isInWindowActive) {
    1348         priv->isInWindowActive = true;
    1349         viewStateFlags |= ViewState::WindowIsActive;
    1350     }
    1351     priv->pageProxy->viewStateDidChange(viewStateFlags);
     1372    if ((focused && priv->viewState & ViewState::IsFocused) || (!focused && !(priv->viewState & ViewState::IsFocused)))
     1373        return;
     1374
     1375    ViewState::Flags flagsToUpdate = ViewState::IsFocused;
     1376    if (focused) {
     1377        priv->viewState |= ViewState::IsFocused;
     1378
     1379        // If the view has received the focus and the window is not active
     1380        // mark the current window as active now. This can happen if the
     1381        // toplevel window is a GTK_WINDOW_POPUP and the focus has been
     1382        // set programatically like WebKitTestRunner does, because POPUP
     1383        // can't be focused.
     1384        if (!(priv->viewState & ViewState::WindowIsActive)) {
     1385            priv->viewState |= ViewState::WindowIsActive;
     1386            flagsToUpdate |= ViewState::WindowIsActive;
     1387        }
     1388    } else
     1389        priv->viewState &= ~ViewState::IsFocused;
     1390
     1391    webkitWebViewBaseScheduleUpdateViewState(webViewBase, flagsToUpdate);
    13521392}
    13531393
    13541394bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase)
    13551395{
    1356     return webViewBase->priv->isInWindowActive;
     1396    return webViewBase->priv->viewState & ViewState::WindowIsActive;
    13571397}
    13581398
    13591399bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase)
    13601400{
    1361     return webViewBase->priv->isFocused;
     1401    return webViewBase->priv->viewState & ViewState::IsFocused;
    13621402}
    13631403
    13641404bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase)
    13651405{
    1366     return webViewBase->priv->isVisible;
     1406    return webViewBase->priv->viewState & ViewState::IsVisible;
    13671407}
    13681408
    13691409bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase)
    13701410{
    1371     return webViewBase->priv->toplevelOnScreenWindow;
    1372 }
    1373 
    1374 bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase* webViewBase)
    1375 {
    1376     return webViewBase->priv->isWindowVisible;
     1411    return webViewBase->priv->viewState & ViewState::IsInWindow;
    13771412}
    13781413
  • releases/WebKitGTK/webkit-2.10/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h

    r191554 r197063  
    6060bool webkitWebViewBaseIsVisible(WebKitWebViewBase*);
    6161bool webkitWebViewBaseIsInWindow(WebKitWebViewBase*);
    62 bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase*);
    6362
    6463typedef void (*WebKitWebViewBaseDownloadRequestHandler) (WebKitWebViewBase*, WebKit::DownloadProxy*);
Note: See TracChangeset for help on using the changeset viewer.