@@ -3789,15 +3789,42 @@ void WebPage::suspend(CompletionHandler<void(bool)>&& completionHandler)
37893789 if (!m_page)
37903790 return completionHandler (false );
37913791
3792+ m_isLifecycleSuspended = true ;
3793+
3794+ // Suspend all the documents, so they can send the freeze event to the apps.
3795+ m_page->forEachDocument ([] (Document& document) {
3796+ document.freeze ();
3797+ });
3798+
37923799 freezeLayerTree (LayerTreeFreezeReason::PageSuspended);
37933800
3801+ BackForwardCache::singleton ().setUsePageLifecycleEvents (true );
37943802 m_cachedPage = BackForwardCache::singleton ().suspendPage (*m_page);
3803+ BackForwardCache::singleton ().setUsePageLifecycleEvents (false );
37953804 ASSERT (m_cachedPage);
37963805 if (auto mainFrame = m_mainFrame->coreFrame ())
37973806 mainFrame->loader ().detachFromAllOpenedFrames ();
37983807 completionHandler (true );
37993808}
38003809
3810+ class ResumeEventNotifier : public RefCounted <ResumeEventNotifier> {
3811+ public:
3812+ ResumeEventNotifier () = default ;
3813+ virtual ~ResumeEventNotifier () = default ;
3814+
3815+ void setCompletionHandler (CompletionHandler<void ()>&& completionHandler) { m_completionHandler = WTFMove (completionHandler); };
3816+ void addDocument (Ref<Document> document) { m_documents.add (document); };
3817+ void removeDocument (Ref<Document> document) {
3818+ m_documents.remove (document);
3819+ if (m_documents.isEmpty ())
3820+ m_completionHandler ();
3821+ }
3822+
3823+ private:
3824+ CompletionHandler<void ()> m_completionHandler;
3825+ HashSet<Ref<Document>> m_documents;
3826+ };
3827+
38013828void WebPage::resume (CompletionHandler<void (bool )>&& completionHandler)
38023829{
38033830 WEBPAGE_RELEASE_LOG (Loading, " resume: m_page=%p" , m_page.get ());
@@ -3811,7 +3838,22 @@ void WebPage::resume(CompletionHandler<void(bool)>&& completionHandler)
38113838
38123839 cachedPage->restore (*m_page);
38133840 unfreezeLayerTree (LayerTreeFreezeReason::PageSuspended);
3814- completionHandler (true );
3841+
3842+ // Create a notifier that will call the completionHandler once all the documents
3843+ // have dispatched their resume event.
3844+ Ref<ResumeEventNotifier> notifier = adoptRef (*new ResumeEventNotifier ());
3845+ notifier->setCompletionHandler ([this , completionHandler = std::exchange (completionHandler, { })] () mutable {
3846+ m_isLifecycleSuspended = false ;
3847+ completionHandler (true );
3848+ });
3849+
3850+ // Resume all the documents.
3851+ m_page->forEachDocument ([notifier] (Document& document) {
3852+ notifier->addDocument (document);
3853+ document.resume ([protectedNotifier = Ref { notifier }] (Document& document) {
3854+ protectedNotifier->removeDocument (document);
3855+ });
3856+ });
38153857}
38163858
38173859IntPoint WebPage::screenToRootView (const IntPoint& point)
0 commit comments