diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 2f2136ca2d13..83c4398014d0 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -706,7 +706,8 @@ already_AddRefed CanonicalBrowsingContext::Print( } ErrorResult rv; - outerWindow->Print(aPrintSettings, listener, + outerWindow->Print(aPrintSettings, + /* aRemotePrintJob = */ nullptr, listener, /* aDocShellToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No, nsGlobalWindowOuter::IsForWindowDotPrint::No, diff --git a/docshell/base/nsIContentViewer.idl b/docshell/base/nsIContentViewer.idl index feb97f461f2f..1079864a0a04 100644 --- a/docshell/base/nsIContentViewer.idl +++ b/docshell/base/nsIContentViewer.idl @@ -24,6 +24,9 @@ class PresShell; namespace dom { class WindowGlobalChild; } // namespace dom +namespace layout { +class RemotePrintJobChild; +} // namespace layout } // namespace mozilla %} @@ -34,6 +37,7 @@ class WindowGlobalChild; [ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming); [ptr] native Encoding(const mozilla::Encoding); [ptr] native PresShellPtr(mozilla::PresShell); +[ptr] native RemotePrintJobChildPtr(mozilla::layout::RemotePrintJobChild); [ptr] native WindowGlobalChildPtr(mozilla::dom::WindowGlobalChild); [scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)] @@ -205,7 +209,8 @@ interface nsIContentViewer : nsISupports /** * Sets the print settings for print / print-previewing a subdocument. */ - [can_run_script] void setPrintSettingsForSubdocument(in nsIPrintSettings aPrintSettings); + [can_run_script] void setPrintSettingsForSubdocument(in nsIPrintSettings aPrintSettings, + in RemotePrintJobChildPtr aRemotePrintJob); /** * Get the history entry that this viewer will save itself into when diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 879816241b0b..1b903d04c6e6 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -3449,6 +3449,7 @@ already_AddRefed nsFrameLoader::PrintPreview( ErrorResult rv; sourceWindow->Print( aPrintSettings, + /* aRemotePrintJob = */ nullptr, /* aListener = */ nullptr, docShellToCloneInto, nsGlobalWindowOuter::IsPreview::Yes, nsGlobalWindowOuter::IsForWindowDotPrint::No, diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 573c60da29c0..bd7642329b4f 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -3866,12 +3866,14 @@ void nsGlobalWindowInner::Print(ErrorResult& aError) { Nullable nsGlobalWindowInner::PrintPreview( nsIPrintSettings* aSettings, nsIWebProgressListener* aListener, nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) { - FORWARD_TO_OUTER_OR_THROW(Print, - (aSettings, aListener, aDocShellToCloneInto, - nsGlobalWindowOuter::IsPreview::Yes, - nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, aError), - aError, nullptr); + FORWARD_TO_OUTER_OR_THROW( + Print, + (aSettings, + /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto, + nsGlobalWindowOuter::IsPreview::Yes, + nsGlobalWindowOuter::IsForWindowDotPrint::No, + /* aPrintPreviewCallback = */ nullptr, aError), + aError, nullptr); } void nsGlobalWindowInner::MoveTo(int32_t aXPos, int32_t aYPos, diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index ceaf5011caab..f4358664bb26 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -272,6 +272,7 @@ using namespace mozilla::dom::ipc; using mozilla::BasePrincipal; using mozilla::OriginAttributes; using mozilla::TimeStamp; +using mozilla::layout::RemotePrintJobChild; #define FORWARD_TO_INNER(method, args, err_rval) \ PR_BEGIN_MACRO \ @@ -5139,7 +5140,7 @@ void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) { }); const bool forPreview = !StaticPrefs::print_always_print_silent(); - Print(nullptr, nullptr, nullptr, IsPreview(forPreview), + Print(nullptr, nullptr, nullptr, nullptr, IsPreview(forPreview), IsForWindowDotPrint::Yes, nullptr, aError); #endif } @@ -5159,9 +5160,9 @@ class MOZ_RAII AutoModalState { }; Nullable nsGlobalWindowOuter::Print( - nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener, - nsIDocShell* aDocShellToCloneInto, IsPreview aIsPreview, - IsForWindowDotPrint aForWindowDotPrint, + nsIPrintSettings* aPrintSettings, RemotePrintJobChild* aRemotePrintJob, + nsIWebProgressListener* aListener, nsIDocShell* aDocShellToCloneInto, + IsPreview aIsPreview, IsForWindowDotPrint aForWindowDotPrint, PrintPreviewResolver&& aPrintPreviewCallback, ErrorResult& aError) { #ifdef NS_PRINTING nsCOMPtr printSettingsService = @@ -5318,7 +5319,7 @@ Nullable nsGlobalWindowOuter::Print( } } else { // Historically we've eaten this error. - webBrowserPrint->Print(ps, aListener); + webBrowserPrint->Print(ps, aRemotePrintJob, aListener); } } diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index ab3a63025e19..f4bd6b7e7c89 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -122,6 +122,9 @@ class CacheStorage; } // namespace cache class IDBFactory; } // namespace dom +namespace layout { +class RemotePrintJobChild; +} // namespace layout } // namespace mozilla extern already_AddRefed NS_CreateJSTimeoutHandler( @@ -588,8 +591,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, enum class IsPreview : bool { No, Yes }; enum class IsForWindowDotPrint : bool { No, Yes }; mozilla::dom::Nullable Print( - nsIPrintSettings*, nsIWebProgressListener*, nsIDocShell*, IsPreview, - IsForWindowDotPrint, PrintPreviewResolver&&, mozilla::ErrorResult&); + nsIPrintSettings*, mozilla::layout::RemotePrintJobChild* aRemotePrintJob, + nsIWebProgressListener*, nsIDocShell*, IsPreview, IsForWindowDotPrint, + PrintPreviewResolver&&, mozilla::ErrorResult&); mozilla::dom::Selection* GetSelectionOuter(); already_AddRefed GetSelection() override; nsScreen* GetScreen(); diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 31172c57730a..c0944a638592 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -36,6 +36,7 @@ #include "mozilla/EventListenerManager.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/IMEStateManager.h" +#include "mozilla/layout/RemotePrintJobChild.h" #include "mozilla/LookAndFeel.h" #include "mozilla/MouseEvents.h" #include "mozilla/NativeKeyBindingsType.h" @@ -1116,7 +1117,9 @@ nsresult BrowserChild::UpdateRemotePrintSettings( // BC tree, and our code above is simple enough and keeps strong refs to // everything. ([&]() MOZ_CAN_RUN_SCRIPT_BOUNDARY { - cv->SetPrintSettingsForSubdocument(printSettings); + cv->SetPrintSettingsForSubdocument( + printSettings, static_cast( + aPrintData.remotePrintJobChild())); }()); } else if (RefPtr remoteChild = BrowserBridgeChild::GetFrom(aBc->GetEmbedderElement())) { @@ -2468,6 +2471,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview( } sourceWindow->Print(printSettings, + /* aRemotePrintJob = */ nullptr, /* aListener = */ nullptr, docShellToCloneInto, nsGlobalWindowOuter::IsPreview::Yes, nsGlobalWindowOuter::IsForWindowDotPrint::No, @@ -2523,12 +2527,13 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrint( printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings); { IgnoredErrorResult rv; - outerWindow->Print(printSettings, - /* aListener = */ nullptr, - /* aWindowToCloneInto = */ nullptr, - nsGlobalWindowOuter::IsPreview::No, - nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, rv); + outerWindow->Print( + printSettings, + static_cast(aPrintData.remotePrintJobChild()), + /* aListener = */ nullptr, + /* aWindowToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No, + nsGlobalWindowOuter::IsForWindowDotPrint::No, + /* aPrintPreviewCallback = */ nullptr, rv); if (NS_WARN_IF(rv.Failed())) { return IPC_OK(); } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 510628b1d08a..dcce6205e960 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -141,6 +141,7 @@ class PrintPreviewResultInfo; using namespace mozilla; using namespace mozilla::dom; +using mozilla::layout::RemotePrintJobChild; using PrintPreviewResolver = std::function; @@ -2898,6 +2899,7 @@ nsresult nsDocViewerFocusListener::HandleEvent(Event* aEvent) { NS_IMETHODIMP nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings, + RemotePrintJobChild* aRemotePrintJob, nsIWebProgressListener* aWebProgressListener) { if (NS_WARN_IF(!mContainer)) { PR_PL(("Container was destroyed yet we are still trying to use it!")); @@ -2932,7 +2934,8 @@ nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings, } mPrintJob = printJob; - rv = printJob->Print(mDocument, aPrintSettings, aWebProgressListener); + rv = printJob->Print(mDocument, aPrintSettings, aRemotePrintJob, + aWebProgressListener); if (NS_WARN_IF(NS_FAILED(rv))) { OnDonePrinting(); } @@ -3394,7 +3397,7 @@ void nsDocumentViewer::OnDonePrinting() { } NS_IMETHODIMP nsDocumentViewer::SetPrintSettingsForSubdocument( - nsIPrintSettings* aPrintSettings) { + nsIPrintSettings* aPrintSettings, RemotePrintJobChild* aRemotePrintJob) { #ifdef NS_PRINTING { nsAutoScriptBlocker scriptBlocker; @@ -3414,7 +3417,8 @@ NS_IMETHODIMP nsDocumentViewer::SetPrintSettingsForSubdocument( return NS_ERROR_NOT_AVAILABLE; } - RefPtr devspec = new nsDeviceContextSpecProxy(); + RefPtr devspec = + new nsDeviceContextSpecProxy(aRemotePrintJob); nsresult rv = devspec->Init(nullptr, aPrintSettings, /* aIsPrintPreview = */ true); NS_ENSURE_SUCCESS(rv, rv); diff --git a/layout/printing/nsPrintJob.cpp b/layout/printing/nsPrintJob.cpp index fe343b2e53c4..47010769e53b 100644 --- a/layout/printing/nsPrintJob.cpp +++ b/layout/printing/nsPrintJob.cpp @@ -551,14 +551,10 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview, printSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv); NS_ENSURE_SUCCESS(rv, rv); printData->mPrintSettings->SetPrintSession(printSession); - } else { - RefPtr remotePrintJob = - printSession->GetRemotePrintJob(); - if (remotePrintJob) { - // If we have a RemotePrintJob add it to the print progress listeners, - // so it can forward to the parent. - printData->mPrintProgressListeners.AppendElement(remotePrintJob); - } + } else if (mRemotePrintJob) { + // If we have a RemotePrintJob add it to the print progress listeners, + // so it can forward to the parent. + printData->mPrintProgressListeners.AppendElement(mRemotePrintJob); } } @@ -566,7 +562,7 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview, XRE_IsContentProcess() && StaticPrefs::print_print_via_parent(); nsCOMPtr devspec; if (printingViaParent) { - devspec = new nsDeviceContextSpecProxy(); + devspec = new nsDeviceContextSpecProxy(mRemotePrintJob); } else { devspec = do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -601,7 +597,10 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview, //--------------------------------------------------------------------------------- nsresult nsPrintJob::Print(Document* aSourceDoc, nsIPrintSettings* aPrintSettings, + RemotePrintJobChild* aRemotePrintJob, nsIWebProgressListener* aWebProgressListener) { + mRemotePrintJob = aRemotePrintJob; + // If we have a print preview document, use that instead of the original // mDocument. That way animated images etc. get printed using the same state // as in print preview. @@ -2272,16 +2271,9 @@ nsresult nsPrintJob::StartPagePrintTimer(const UniquePtr& aPO) { mPagePrintTimer = new nsPagePrintTimer(this, mDocViewerPrint, doc, printPageDelay); - nsCOMPtr printSession; - nsresult rv = - mPrt->mPrintSettings->GetPrintSession(getter_AddRefs(printSession)); - if (NS_SUCCEEDED(rv) && printSession) { - RefPtr remotePrintJob = - printSession->GetRemotePrintJob(); - if (remotePrintJob) { - remotePrintJob->SetPagePrintTimer(mPagePrintTimer); - remotePrintJob->SetPrintJob(this); - } + if (mRemotePrintJob) { + mRemotePrintJob->SetPagePrintTimer(mPagePrintTimer); + mRemotePrintJob->SetPrintJob(this); } } diff --git a/layout/printing/nsPrintJob.h b/layout/printing/nsPrintJob.h index 461751aee84b..5416c4e53654 100644 --- a/layout/printing/nsPrintJob.h +++ b/layout/printing/nsPrintJob.h @@ -7,6 +7,7 @@ #define nsPrintJob_h #include "mozilla/Attributes.h" +#include "mozilla/layout/RemotePrintJobChild.h" #include "mozilla/UniquePtr.h" #include "nsCOMPtr.h" @@ -52,6 +53,7 @@ class nsPrintJob final : public nsIWebProgressListener, using Document = mozilla::dom::Document; using PrintPreviewResolver = std::function; + using RemotePrintJobChild = mozilla::layout::RemotePrintJobChild; public: nsPrintJob(); @@ -97,6 +99,7 @@ class nsPrintJob final : public nsIWebProgressListener, */ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult Print(Document* aSourceDoc, nsIPrintSettings* aPrintSettings, + RemotePrintJobChild* aRemotePrintJob, nsIWebProgressListener* aWebProgressListener); /** @@ -254,6 +257,9 @@ class nsPrintJob final : public nsIWebProgressListener, RefPtr mPagePrintTimer; + // Only set if this nsPrintJob was created for a real print. + RefPtr mRemotePrintJob; + // If the code that initiates a print preview passes a PrintPreviewResolver // (a std::function) to be notified of the final sheet/page counts (once // we've sufficiently laid out the document to know what those are), that diff --git a/toolkit/components/browser/nsIWebBrowserPrint.idl b/toolkit/components/browser/nsIWebBrowserPrint.idl index 605a8dfff757..7f4d7c1b0ca2 100644 --- a/toolkit/components/browser/nsIWebBrowserPrint.idl +++ b/toolkit/components/browser/nsIWebBrowserPrint.idl @@ -13,6 +13,9 @@ namespace mozilla { namespace dom { class PrintPreviewResultInfo; } // namespace dom +namespace layout { +class RemotePrintJobChild; +} // namespace layout } // namespace mozilla %} @@ -21,6 +24,7 @@ interface nsIPrintSettings; interface nsIWebProgressListener; native PrintPreviewResolver(std::function&&); +[ptr] native RemotePrintJobChildPtr(mozilla::layout::RemotePrintJobChild); /** * nsIWebBrowserPrint corresponds to the main interface @@ -101,6 +105,7 @@ interface nsIWebBrowserPrint : nsISupports * @note To cancel, close the window of the document that is being printed. */ [noscript] void print(in nsIPrintSettings aThePrintSettings, + in RemotePrintJobChildPtr aRemotePrintJob, in nsIWebProgressListener aWPListener); /** diff --git a/widget/nsDeviceContextSpecProxy.cpp b/widget/nsDeviceContextSpecProxy.cpp index ad33a59eb918..a7e92174c669 100644 --- a/widget/nsDeviceContextSpecProxy.cpp +++ b/widget/nsDeviceContextSpecProxy.cpp @@ -27,7 +27,9 @@ using namespace mozilla::gfx; NS_IMPL_ISUPPORTS(nsDeviceContextSpecProxy, nsIDeviceContextSpec) -nsDeviceContextSpecProxy::nsDeviceContextSpecProxy() = default; +nsDeviceContextSpecProxy::nsDeviceContextSpecProxy( + RemotePrintJobChild* aRemotePrintJob) + : mRemotePrintJob(aRemotePrintJob) {} nsDeviceContextSpecProxy::~nsDeviceContextSpecProxy() = default; NS_IMETHODIMP @@ -61,7 +63,6 @@ nsDeviceContextSpecProxy::Init(nsIWidget* aWidget, return NS_ERROR_FAILURE; } - mRemotePrintJob = mPrintSession->GetRemotePrintJob(); if (!mRemotePrintJob) { NS_WARNING("We can't print via the parent without a RemotePrintJobChild."); return NS_ERROR_FAILURE; diff --git a/widget/nsDeviceContextSpecProxy.h b/widget/nsDeviceContextSpecProxy.h index 1c4a4e19949b..2dfda0cc6131 100644 --- a/widget/nsDeviceContextSpecProxy.h +++ b/widget/nsDeviceContextSpecProxy.h @@ -24,6 +24,10 @@ class RemotePrintJobChild; class nsDeviceContextSpecProxy final : public nsIDeviceContextSpec { public: + using RemotePrintJobChild = mozilla::layout::RemotePrintJobChild; + + explicit nsDeviceContextSpecProxy(RemotePrintJobChild* aRemotePrintJob); + NS_DECL_ISUPPORTS NS_IMETHOD Init(nsIWidget* aWidget, nsIPrintSettings* aPrintSettings, @@ -52,15 +56,13 @@ class nsDeviceContextSpecProxy final : public nsIDeviceContextSpec { NS_IMETHOD EndPage() final; - nsDeviceContextSpecProxy(); - private: ~nsDeviceContextSpecProxy(); nsCOMPtr mPrintSettings; nsCOMPtr mPrintSession; nsCOMPtr mRealDeviceContextSpec; - RefPtr mRemotePrintJob; + RefPtr mRemotePrintJob; RefPtr mRecorder; };