<!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>[177104] 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/177104">177104</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2014-12-10 15:00:13 -0800 (Wed, 10 Dec 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Provide SPI to asynchronously move a WKView into a window and know when it has painted
https://bugs.webkit.org/show_bug.cgi?id=139460
&lt;rdar://problem/19135389&gt;

Reviewed by Anders Carlsson.

* UIProcess/API/Cocoa/WKViewPrivate.h:
Add _prepareForMoveToWindow:withCompletionHandler:, which internally
goes through the motions of being parented in that window and calls
the completion handler once painting is done and the view is ready
to be displayed (upon which we expect the view to actually move into the window).

* UIProcess/API/mac/WKView.mm:
(-[WKView viewWillMoveToWindow:]):
If we currently have a _targetWindowForMovePreparation (and are
pretending to be in that window), avoid performing viewWillMoveToWindow:
for a different window.

(-[WKView viewDidMoveToWindow]):
(-[WKView doWindowDidChangeScreen]):
(-[WKView _intrinsicDeviceScaleFactor]):
(-[WKView _colorSpace]):
(-[WKView _targetWindowForMovePreparation]):
If we have a _targetWindowForMovePreparation, use its properties instead
of self.window's.

(-[WKView _prepareForMoveToWindow:withCompletionHandler:]):
Simulate a move into the target window, but defer sending the view state update.
Then, send the view state update after registering the completion handler.

* UIProcess/API/mac/WKViewInternal.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
Rename m_viewStateChangeWantsReply to m_viewStateChangeWantsSynchronousReply.

(WebKit::WebPageProxy::installViewStateChangeCompletionHandler):
Added. Allow installing a block that will be called the next time
we get a didUpdateViewState back from the WebProcess after pushing the
current view state changes.

(WebKit::WebPageProxy::viewStateDidChange):
Adapt to the aforementioned rename.

(WebKit::WebPageProxy::dispatchViewStateChange):
Adapt to the aforementioned rename.
Send the view state change callback IDs along with SetViewState.

(WebKit::WebPageProxy::updateViewState):
Adapt to the aforementioned rename.

* UIProcess/WebPageProxy.h:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::activeWindow):
(WebKit::PageClientImpl::isViewWindowActive):
(WebKit::PageClientImpl::isViewVisible):
(WebKit::PageClientImpl::isViewVisibleOrOccluded):
(WebKit::PageClientImpl::isViewInWindow):
(WebKit::PageClientImpl::viewLayerHostingMode):
If we have a _targetWindowForMovePreparation, use its properties instead
of the WKView's window's.

* WebProcess/WebPage/DrawingArea.h:
(WebKit::DrawingArea::viewStateDidChange):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::reinitializeWebPage):
(WebKit::WebPage::setViewState):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::viewStateDidChange):
Push the callback IDs to the WebProcess, and accumulate them in TiledCoreAnimationDrawingArea.

(WebKit::TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired):
Call all of the callbacks after one runloop cycle, just like DidUpdateViewState.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKViewPrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPImacWKViewmm">trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPImacWKViewInternalh">trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h</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="#trunkSourceWebKit2UIProcessmacPageClientImplh">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplmm">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageDrawingAreah">trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</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="#trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreah">trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreamm">trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacTiledCoreAnimationDrawingAreah">trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacTiledCoreAnimationDrawingAreamm">trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/ChangeLog        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -1,3 +1,85 @@
</span><ins>+2014-12-10  Timothy Horton  &lt;timothy_horton@apple.com&gt;
+
+        Provide SPI to asynchronously move a WKView into a window and know when it has painted
+        https://bugs.webkit.org/show_bug.cgi?id=139460
+        &lt;rdar://problem/19135389&gt;
+
+        Reviewed by Anders Carlsson.
+
+        * UIProcess/API/Cocoa/WKViewPrivate.h:
+        Add _prepareForMoveToWindow:withCompletionHandler:, which internally
+        goes through the motions of being parented in that window and calls
+        the completion handler once painting is done and the view is ready
+        to be displayed (upon which we expect the view to actually move into the window).
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView viewWillMoveToWindow:]):
+        If we currently have a _targetWindowForMovePreparation (and are
+        pretending to be in that window), avoid performing viewWillMoveToWindow:
+        for a different window.
+
+        (-[WKView viewDidMoveToWindow]):
+        (-[WKView doWindowDidChangeScreen]):
+        (-[WKView _intrinsicDeviceScaleFactor]):
+        (-[WKView _colorSpace]):
+        (-[WKView _targetWindowForMovePreparation]):
+        If we have a _targetWindowForMovePreparation, use its properties instead
+        of self.window's.
+
+        (-[WKView _prepareForMoveToWindow:withCompletionHandler:]):
+        Simulate a move into the target window, but defer sending the view state update.
+        Then, send the view state update after registering the completion handler.
+
+        * UIProcess/API/mac/WKViewInternal.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        Rename m_viewStateChangeWantsReply to m_viewStateChangeWantsSynchronousReply.
+
+        (WebKit::WebPageProxy::installViewStateChangeCompletionHandler):
+        Added. Allow installing a block that will be called the next time
+        we get a didUpdateViewState back from the WebProcess after pushing the
+        current view state changes.
+
+        (WebKit::WebPageProxy::viewStateDidChange):
+        Adapt to the aforementioned rename.
+
+        (WebKit::WebPageProxy::dispatchViewStateChange):
+        Adapt to the aforementioned rename.
+        Send the view state change callback IDs along with SetViewState.
+
+        (WebKit::WebPageProxy::updateViewState):
+        Adapt to the aforementioned rename.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::activeWindow):
+        (WebKit::PageClientImpl::isViewWindowActive):
+        (WebKit::PageClientImpl::isViewVisible):
+        (WebKit::PageClientImpl::isViewVisibleOrOccluded):
+        (WebKit::PageClientImpl::isViewInWindow):
+        (WebKit::PageClientImpl::viewLayerHostingMode):
+        If we have a _targetWindowForMovePreparation, use its properties instead
+        of the WKView's window's.
+
+        * WebProcess/WebPage/DrawingArea.h:
+        (WebKit::DrawingArea::viewStateDidChange):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::reinitializeWebPage):
+        (WebKit::WebPage::setViewState):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+        (WebKit::TiledCoreAnimationDrawingArea::viewStateDidChange):
+        Push the callback IDs to the WebProcess, and accumulate them in TiledCoreAnimationDrawingArea.
+
+        (WebKit::TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired):
+        Call all of the callbacks after one runloop cycle, just like DidUpdateViewState.
+
</ins><span class="cx"> 2014-12-10  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add session storage handling to StorageNamespaceProvider
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKViewPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -100,6 +100,7 @@
</span><span class="cx"> - (void)endDeferringViewInWindowChanges;
</span><span class="cx"> - (void)endDeferringViewInWindowChangesSync;
</span><span class="cx"> - (BOOL)isDeferringViewInWindowChanges;
</span><ins>+- (void)_prepareForMoveToWindow:(NSWindow *)targetWindow withCompletionHandler:(void(^)(void))completionHandler;
</ins><span class="cx"> 
</span><span class="cx"> - (BOOL)windowOcclusionDetectionEnabled;
</span><span class="cx"> - (void)setWindowOcclusionDetectionEnabled:(BOOL)flag;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -227,6 +227,7 @@
</span><span class="cx">     
</span><span class="cx">     unsigned _frameSizeUpdatesDisabledCount;
</span><span class="cx">     BOOL _shouldDeferViewInWindowChanges;
</span><ins>+    NSWindow *_targetWindowForMovePreparation;
</ins><span class="cx"> 
</span><span class="cx">     BOOL _viewInWindowChangeWasDeferred;
</span><span class="cx"> 
</span><span class="lines">@@ -2497,7 +2498,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)removeWindowObservers
</span><span class="cx"> {
</span><del>-    NSWindow *window = [self window];
</del><ins>+    NSWindow *window = _data-&gt;_targetWindowForMovePreparation ? _data-&gt;_targetWindowForMovePreparation : [self window];
</ins><span class="cx">     if (!window)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -2524,6 +2525,9 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)viewWillMoveToWindow:(NSWindow *)window
</span><span class="cx"> {
</span><ins>+    // If we're in the middle of preparing to move to a window, we should only be moved to that window.
+    ASSERT(!_data-&gt;_targetWindowForMovePreparation || (_data-&gt;_targetWindowForMovePreparation == window));
+
</ins><span class="cx">     NSWindow *currentWindow = [self window];
</span><span class="cx">     if (window == currentWindow)
</span><span class="cx">         return;
</span><span class="lines">@@ -2536,7 +2540,9 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)viewDidMoveToWindow
</span><span class="cx"> {
</span><del>-    if ([self window]) {
</del><ins>+    NSWindow *window = _data-&gt;_targetWindowForMovePreparation ? _data-&gt;_targetWindowForMovePreparation : self.window;
+
+    if (window) {
</ins><span class="cx">         [self doWindowDidChangeScreen];
</span><span class="cx"> 
</span><span class="cx">         ViewState::Flags viewStateChanges = ViewState::WindowIsActive | ViewState::IsVisible;
</span><span class="lines">@@ -2580,7 +2586,8 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)doWindowDidChangeScreen
</span><span class="cx"> {
</span><del>-    _data-&gt;_page-&gt;windowScreenDidChange((PlatformDisplayID)[[[[[self window] screen] deviceDescription] objectForKey:@&quot;NSScreenNumber&quot;] intValue]);
</del><ins>+    NSWindow *window = _data-&gt;_targetWindowForMovePreparation ? _data-&gt;_targetWindowForMovePreparation : self.window;
+    _data-&gt;_page-&gt;windowScreenDidChange((PlatformDisplayID)[[[[window screen] deviceDescription] objectForKey:@&quot;NSScreenNumber&quot;] intValue]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_windowDidBecomeKey:(NSNotification *)notification
</span><span class="lines">@@ -2817,8 +2824,9 @@
</span><span class="cx"> 
</span><span class="cx"> - (float)_intrinsicDeviceScaleFactor
</span><span class="cx"> {
</span><del>-    NSWindow *window = [self window];
-    if (window)
</del><ins>+    if (_data-&gt;_targetWindowForMovePreparation)
+        return [_data-&gt;_targetWindowForMovePreparation backingScaleFactor];
+    if (NSWindow *window = [self window])
</ins><span class="cx">         return [window backingScaleFactor];
</span><span class="cx">     return [[NSScreen mainScreen] backingScaleFactor];
</span><span class="cx"> }
</span><span class="lines">@@ -2863,8 +2871,10 @@
</span><span class="cx"> - (WebKit::ColorSpaceData)_colorSpace
</span><span class="cx"> {
</span><span class="cx">     if (!_data-&gt;_colorSpace) {
</span><del>-        if ([self window])
-            _data-&gt;_colorSpace = [[self window] colorSpace];
</del><ins>+        if (_data-&gt;_targetWindowForMovePreparation)
+            _data-&gt;_colorSpace = [_data-&gt;_targetWindowForMovePreparation colorSpace];
+        else if (NSWindow *window = [self window])
+            _data-&gt;_colorSpace = [window colorSpace];
</ins><span class="cx">         else
</span><span class="cx">             _data-&gt;_colorSpace = [[NSScreen mainScreen] colorSpace];
</span><span class="cx">     }
</span><span class="lines">@@ -4005,6 +4015,31 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_prepareForMoveToWindow:(NSWindow *)targetWindow withCompletionHandler:(void(^)(void))completionHandler
+{
+    _data-&gt;_shouldDeferViewInWindowChanges = YES;
+    [self viewWillMoveToWindow:targetWindow];
+    _data-&gt;_targetWindowForMovePreparation = targetWindow;
+    [self viewDidMoveToWindow];
+
+    _data-&gt;_shouldDeferViewInWindowChanges = NO;
+
+    _data-&gt;_page-&gt;installViewStateChangeCompletionHandler(^() {
+        completionHandler();
+        ASSERT(self.window == _data-&gt;_targetWindowForMovePreparation);
+        _data-&gt;_targetWindowForMovePreparation = nil;
+    });
+
+    [self _dispatchSetTopContentInset];
+    _data-&gt;_page-&gt;viewStateDidChange(ViewState::IsInWindow, false, WebPageProxy::ViewStateChangeDispatchMode::Immediate);
+    _data-&gt;_viewInWindowChangeWasDeferred = NO;
+}
+
+- (NSWindow *)_targetWindowForMovePreparation
+{
+    return _data-&gt;_targetWindowForMovePreparation;
+}
+
</ins><span class="cx"> - (BOOL)isDeferringViewInWindowChanges
</span><span class="cx"> {
</span><span class="cx">     return _data-&gt;_shouldDeferViewInWindowChanges;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -132,4 +132,6 @@
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, retain, setter=_setPrimaryTrackingArea:) NSTrackingArea *_primaryTrackingArea;
</span><span class="cx"> 
</span><ins>+@property (readonly) NSWindow *_targetWindowForMovePreparation;
+
</ins><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -375,7 +375,7 @@
</span><span class="cx">     , m_navigationID(0)
</span><span class="cx">     , m_configurationPreferenceValues(configuration.preferenceValues)
</span><span class="cx">     , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
</span><del>-    , m_viewStateChangeWantsReply(false)
</del><ins>+    , m_viewStateChangeWantsSynchronousReply(false)
</ins><span class="cx">     , m_isPlayingAudio(false)
</span><span class="cx"> {
</span><span class="cx">     m_websiteDataStore-&gt;addWebPage(*this);
</span><span class="lines">@@ -1174,10 +1174,26 @@
</span><span class="cx">         m_viewState |= ViewState::IsVisuallyIdle;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsReply, ViewStateChangeDispatchMode dispatchMode)
</del><ins>+void WebPageProxy::installViewStateChangeCompletionHandler(void (^completionHandler)())
</ins><span class="cx"> {
</span><ins>+    if (!isValid()) {
+        completionHandler();
+        return;
+    }
+
+    auto copiedCompletionHandler = Block_copy(completionHandler);
+    RefPtr&lt;VoidCallback&gt; voidCallback = VoidCallback::create([copiedCompletionHandler] (CallbackBase::Error) {
+        copiedCompletionHandler();
+        Block_release(copiedCompletionHandler);
+    }, std::make_unique&lt;ProcessThrottler::BackgroundActivityToken&gt;(m_process-&gt;throttler()));
+    uint64_t callbackID = m_callbacks.put(voidCallback.release());
+    m_nextViewStateChangeCallbacks.append(callbackID);
+}
+
+void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
+{
</ins><span class="cx">     m_potentiallyChangedViewStateFlags |= mayHaveChanged;
</span><del>-    m_viewStateChangeWantsReply = m_viewStateChangeWantsReply || wantsReply;
</del><ins>+    m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     bool isNewlyInWindow = !isInWindow() &amp;&amp; (mayHaveChanged &amp; ViewState::IsInWindow) &amp;&amp; m_pageClient.isViewInWindow();
</span><span class="lines">@@ -1236,11 +1252,13 @@
</span><span class="cx"> 
</span><span class="cx">     // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
</span><span class="cx">     if (m_viewWasEverInWindow &amp;&amp; (changed &amp; ViewState::IsInWindow) &amp;&amp; isInWindow())
</span><del>-        m_viewStateChangeWantsReply = true;
</del><ins>+        m_viewStateChangeWantsSynchronousReply = true;
</ins><span class="cx"> 
</span><del>-    if (changed || m_viewStateChangeWantsReply)
-        m_process-&gt;send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply), m_pageID);
</del><ins>+    if (changed || m_viewStateChangeWantsSynchronousReply)
+        m_process-&gt;send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
</ins><span class="cx"> 
</span><ins>+    m_nextViewStateChangeCallbacks.clear();
+
</ins><span class="cx">     // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
</span><span class="cx">     updateActivityToken();
</span><span class="cx"> 
</span><span class="lines">@@ -1262,11 +1280,11 @@
</span><span class="cx"> 
</span><span class="cx">     updateBackingStoreDiscardableState();
</span><span class="cx"> 
</span><del>-    if (m_viewStateChangeWantsReply)
</del><ins>+    if (m_viewStateChangeWantsSynchronousReply)
</ins><span class="cx">         waitForDidUpdateViewState();
</span><span class="cx"> 
</span><span class="cx">     m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
</span><del>-    m_viewStateChangeWantsReply = false;
</del><ins>+    m_viewStateChangeWantsSynchronousReply = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::updateActivityToken()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -371,7 +371,8 @@
</span><span class="cx">     bool delegatesScrolling() const { return m_delegatesScrolling; }
</span><span class="cx"> 
</span><span class="cx">     enum class ViewStateChangeDispatchMode { Deferrable, Immediate };
</span><del>-    void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, bool wantsReply = false, ViewStateChangeDispatchMode = ViewStateChangeDispatchMode::Deferrable);
</del><ins>+    void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, bool wantsSynchronousReply = false, ViewStateChangeDispatchMode = ViewStateChangeDispatchMode::Deferrable);
+    void installViewStateChangeCompletionHandler(void(^completionHandler)());
</ins><span class="cx">     bool isInWindow() const { return m_viewState &amp; WebCore::ViewState::IsInWindow; }
</span><span class="cx">     void waitForDidUpdateViewState();
</span><span class="cx">     void didUpdateViewState() { m_waitingForDidUpdateViewState = false; }
</span><span class="lines">@@ -1585,7 +1586,8 @@
</span><span class="cx"> 
</span><span class="cx">     WebPreferencesStore::ValueMap m_configurationPreferenceValues;
</span><span class="cx">     WebCore::ViewState::Flags m_potentiallyChangedViewStateFlags;
</span><del>-    bool m_viewStateChangeWantsReply;
</del><ins>+    bool m_viewStateChangeWantsSynchronousReply;
+    Vector&lt;uint64_t&gt; m_nextViewStateChangeCallbacks;
</ins><span class="cx"> 
</span><span class="cx">     bool m_isPlayingAudio;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -183,6 +183,7 @@
</span><span class="cx">     virtual void willRecordNavigationSnapshot(WebBackForwardListItem&amp;) override;
</span><span class="cx"> 
</span><span class="cx">     NSView *activeView() const;
</span><ins>+    NSWindow *activeWindow() const;
</ins><span class="cx"> 
</span><span class="cx">     virtual void didFirstVisuallyNonEmptyLayoutForMainFrame() override;
</span><span class="cx">     virtual void didFinishLoadForMainFrame() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -196,9 +196,20 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+NSWindow *PageClientImpl::activeWindow() const
+{
+#if WK_API_ENABLED
+    if (m_wkView._thumbnailView)
+        return m_wkView._thumbnailView.window;
+#endif
+    if (m_wkView._targetWindowForMovePreparation)
+        return m_wkView._targetWindowForMovePreparation;
+    return m_wkView.window;
+}
+
</ins><span class="cx"> bool PageClientImpl::isViewWindowActive()
</span><span class="cx"> {
</span><del>-    NSWindow *activeViewWindow = activeView().window;
</del><ins>+    NSWindow *activeViewWindow = activeWindow();
</ins><span class="cx">     return activeViewWindow.isKeyWindow || [NSApp keyWindow] == activeViewWindow;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -215,7 +226,7 @@
</span><span class="cx"> bool PageClientImpl::isViewVisible()
</span><span class="cx"> {
</span><span class="cx">     NSView *activeView = this-&gt;activeView();
</span><del>-    NSWindow *activeViewWindow = activeView.window;
</del><ins>+    NSWindow *activeViewWindow = activeWindow();
</ins><span class="cx"> 
</span><span class="cx">     if (!activeViewWindow)
</span><span class="cx">         return false;
</span><span class="lines">@@ -243,12 +254,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool PageClientImpl::isViewVisibleOrOccluded()
</span><span class="cx"> {
</span><del>-    return activeView().window.isVisible;
</del><ins>+    return activeWindow().isVisible;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool PageClientImpl::isViewInWindow()
</span><span class="cx"> {
</span><del>-    return activeView().window;
</del><ins>+    return activeWindow();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool PageClientImpl::isVisuallyIdle()
</span><span class="lines">@@ -259,7 +270,7 @@
</span><span class="cx"> LayerHostingMode PageClientImpl::viewLayerHostingMode()
</span><span class="cx"> {
</span><span class="cx"> #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
</span><del>-    if ([activeView().window _hostsLayersInWindowServer])
</del><ins>+    if ([activeWindow() _hostsLayersInWindowServer])
</ins><span class="cx">         return LayerHostingMode::OutOfProcess;
</span><span class="cx"> #endif
</span><span class="cx">     return LayerHostingMode::InProcess;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageDrawingAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -115,7 +115,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void dispatchAfterEnsuringUpdatedScrollPosition(std::function&lt;void ()&gt;);
</span><span class="cx"> 
</span><del>-    virtual void viewStateDidChange(WebCore::ViewState::Flags, bool /*wantsDidUpdateViewState*/) { }
</del><ins>+    virtual void viewStateDidChange(WebCore::ViewState::Flags, bool /* wantsDidUpdateViewState */, const Vector&lt;uint64_t&gt;&amp; /* callbackIDs */) { }
</ins><span class="cx">     virtual void setLayerHostingMode(LayerHostingMode) { }
</span><span class="cx"> 
</span><span class="cx">     virtual bool markLayersVolatileImmediatelyIfPossible() { return true; }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -504,7 +504,7 @@
</span><span class="cx"> void WebPage::reinitializeWebPage(const WebPageCreationParameters&amp; parameters)
</span><span class="cx"> {
</span><span class="cx">     if (m_viewState != parameters.viewState)
</span><del>-        setViewState(parameters.viewState);
</del><ins>+        setViewState(parameters.viewState, false, Vector&lt;uint64_t&gt;());
</ins><span class="cx">     if (m_layerHostingMode != parameters.layerHostingMode)
</span><span class="cx">         setLayerHostingMode(static_cast&lt;unsigned&gt;(parameters.layerHostingMode));
</span><span class="cx"> }
</span><span class="lines">@@ -2311,7 +2311,7 @@
</span><span class="cx">         layoutIfNeeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState)
</del><ins>+void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp; callbackIDs)
</ins><span class="cx"> {
</span><span class="cx">     ViewState::Flags changed = m_viewState ^ viewState;
</span><span class="cx">     m_viewState = viewState;
</span><span class="lines">@@ -2320,7 +2320,7 @@
</span><span class="cx">     for (auto* pluginView : m_pluginViews)
</span><span class="cx">         pluginView-&gt;viewStateDidChange(changed);
</span><span class="cx"> 
</span><del>-    m_drawingArea-&gt;viewStateDidChange(changed, wantsDidUpdateViewState);
</del><ins>+    m_drawingArea-&gt;viewStateDidChange(changed, wantsDidUpdateViewState, callbackIDs);
</ins><span class="cx"> 
</span><span class="cx">     if (changed &amp; ViewState::IsInWindow)
</span><span class="cx">         updateIsInWindow();
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -925,7 +925,7 @@
</span><span class="cx">     void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&amp;);
</span><span class="cx">     void setWindowResizerSize(const WebCore::IntSize&amp;);
</span><span class="cx">     void updateIsInWindow(bool isInitialState = false);
</span><del>-    void setViewState(WebCore::ViewState::Flags, bool wantsDidUpdateViewState = false);
</del><ins>+    void setViewState(WebCore::ViewState::Flags, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp; callbackIDs);
</ins><span class="cx">     void validateCommand(const String&amp;, uint64_t);
</span><span class="cx">     void executeEditCommand(const String&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -22,7 +22,7 @@
</span><span class="cx"> 
</span><span class="cx"> messages -&gt; WebPage LegacyReceiver {
</span><span class="cx">     SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event)
</span><del>-    SetViewState(unsigned viewState, bool wantsDidUpdateViewState)
</del><ins>+    SetViewState(unsigned viewState, bool wantsDidUpdateViewState, Vector&lt;uint64_t&gt; callbackIDs)
</ins><span class="cx">     SetLayerHostingMode(unsigned layerHostingMode)
</span><span class="cx"> 
</span><span class="cx">     SetSessionID(WebCore::SessionID sessionID)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void mainFrameContentSizeChanged(const WebCore::IntSize&amp;) override;
</span><span class="cx"> 
</span><del>-    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState) override;
</del><ins>+    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp; callbackIDs) override;
</ins><span class="cx"> 
</span><span class="cx">     virtual bool adjustLayerFlushThrottling(WebCore::LayerFlushThrottleState::Flags) override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -467,7 +467,7 @@
</span><span class="cx">     m_connection-&gt;sendMessage(WTF::move(m_commitEncoder));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RemoteLayerTreeDrawingArea::viewStateDidChange(ViewState::Flags, bool wantsDidUpdateViewState)
</del><ins>+void RemoteLayerTreeDrawingArea::viewStateDidChange(ViewState::Flags, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp;)
</ins><span class="cx"> {
</span><span class="cx">     // FIXME: Should we suspend painting while not visible, like TiledCoreAnimationDrawingArea? Probably.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacTiledCoreAnimationDrawingAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool shouldUseTiledBackingForFrameView(const WebCore::FrameView*) override;
</span><span class="cx"> 
</span><del>-    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState) override;
</del><ins>+    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp;) override;
</ins><span class="cx">     void didUpdateViewStateTimerFired();
</span><span class="cx"> 
</span><span class="cx">     virtual void attachViewOverlayGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) override;
</span><span class="lines">@@ -141,6 +141,8 @@
</span><span class="cx">     WebCore::TransformationMatrix m_transform;
</span><span class="cx"> 
</span><span class="cx">     RunLoop::Timer&lt;TiledCoreAnimationDrawingArea&gt; m_sendDidUpdateViewStateTimer;
</span><ins>+    Vector&lt;uint64_t&gt; m_nextViewStateChangeCallbackIDs;
+    bool m_wantsDidUpdateViewState;
</ins><span class="cx"> 
</span><span class="cx">     WebCore::GraphicsLayer* m_viewOverlayRootLayer;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacTiledCoreAnimationDrawingAreamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm (177103 => 177104)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm        2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm        2014-12-10 23:00:13 UTC (rev 177104)
</span><span class="lines">@@ -78,6 +78,7 @@
</span><span class="cx">     , m_scrolledExposedRect(FloatRect::infiniteRect())
</span><span class="cx">     , m_transientZoomScale(1)
</span><span class="cx">     , m_sendDidUpdateViewStateTimer(RunLoop::main(), this, &amp;TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired)
</span><ins>+    , m_wantsDidUpdateViewState(false)
</ins><span class="cx">     , m_viewOverlayRootLayer(nullptr)
</span><span class="cx"> {
</span><span class="cx">     m_webPage.corePage()-&gt;settings().setForceCompositingMode(true);
</span><span class="lines">@@ -327,8 +328,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TiledCoreAnimationDrawingArea::viewStateDidChange(ViewState::Flags changed, bool wantsDidUpdateViewState)
</del><ins>+void TiledCoreAnimationDrawingArea::viewStateDidChange(ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector&lt;uint64_t&gt;&amp; nextViewStateChangeCallbackIDs)
</ins><span class="cx"> {
</span><ins>+    m_nextViewStateChangeCallbackIDs.appendVector(nextViewStateChangeCallbackIDs);
+    m_wantsDidUpdateViewState |= wantsDidUpdateViewState;
+
</ins><span class="cx">     if (changed &amp; ViewState::IsVisible) {
</span><span class="cx">         if (m_webPage.isVisible())
</span><span class="cx">             resumePainting();
</span><span class="lines">@@ -336,14 +340,22 @@
</span><span class="cx">             suspendPainting();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (wantsDidUpdateViewState)
</del><ins>+    if (m_wantsDidUpdateViewState || !m_nextViewStateChangeCallbackIDs.isEmpty())
</ins><span class="cx">         m_sendDidUpdateViewStateTimer.startOneShot(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired()
</span><span class="cx"> {
</span><span class="cx">     [CATransaction flush];
</span><del>-    m_webPage.send(Messages::WebPageProxy::DidUpdateViewState());
</del><ins>+
+    if (m_wantsDidUpdateViewState)
+        m_webPage.send(Messages::WebPageProxy::DidUpdateViewState());
+
+    for (uint64_t callbackID : m_nextViewStateChangeCallbackIDs)
+        m_webPage.send(Messages::WebPageProxy::VoidCallback(callbackID));
+
+    m_nextViewStateChangeCallbackIDs.clear();
+    m_wantsDidUpdateViewState = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TiledCoreAnimationDrawingArea::suspendPainting()
</span></span></pre>
</div>
</div>

</body>
</html>