mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1785046 - Part 4: Use async move on printing to file on Windows. r=nika,emilio
Differential Revision: https://phabricator.services.mozilla.com/D163509
This commit is contained in:
parent
aab93348e9
commit
9b9c76aa00
@ -6,8 +6,14 @@
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
|
||||
#include "gfxPoint.h"
|
||||
#include "mozilla/gfx/PrintPromise.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
|
||||
using mozilla::MakeRefPtr;
|
||||
using mozilla::gfx::PrintEndDocumentPromise;
|
||||
|
||||
// We have some platform specific code here rather than in the appropriate
|
||||
@ -58,3 +64,24 @@ nsIDeviceContextSpec::EndDocumentPromiseFromResult(nsresult aResult,
|
||||
? PrintEndDocumentPromise::CreateAndResolve(true, aSite)
|
||||
: PrintEndDocumentPromise::CreateAndReject(aResult, aSite);
|
||||
}
|
||||
|
||||
RefPtr<PrintEndDocumentPromise> nsIDeviceContextSpec::EndDocumentAsync(
|
||||
const char* aCallSite, AsyncEndDocumentFunction aFunction) {
|
||||
auto promise =
|
||||
MakeRefPtr<PrintEndDocumentPromise::Private>("PrintEndDocumentPromise");
|
||||
|
||||
NS_DispatchBackgroundTask(
|
||||
NS_NewRunnableFunction(
|
||||
"EndDocumentAsync",
|
||||
[promise, function = std::move(aFunction)]() mutable {
|
||||
const auto result = function();
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
promise->Resolve(true, __func__);
|
||||
} else {
|
||||
promise->Reject(result, __func__);
|
||||
}
|
||||
}),
|
||||
NS_DISPATCH_EVENT_MAY_BLOCK);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsISupports.h"
|
||||
#include "mozilla/StaticPrefs_print.h"
|
||||
#include "mozilla/gfx/PrintPromise.h"
|
||||
#include "mozilla/MoveOnlyFunction.h"
|
||||
|
||||
class nsIWidget;
|
||||
class nsIPrintSettings;
|
||||
@ -82,6 +83,10 @@ class nsIDeviceContextSpec : public nsISupports {
|
||||
NS_IMETHOD EndPage() = 0;
|
||||
|
||||
protected:
|
||||
using AsyncEndDocumentFunction = mozilla::MoveOnlyFunction<nsresult()>;
|
||||
static RefPtr<mozilla::gfx::PrintEndDocumentPromise> EndDocumentAsync(
|
||||
const char* aCallSite, AsyncEndDocumentFunction aFunction);
|
||||
|
||||
static RefPtr<mozilla::gfx::PrintEndDocumentPromise>
|
||||
EndDocumentPromiseFromResult(nsresult aResult, const char* aSite);
|
||||
|
||||
|
@ -333,20 +333,15 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget() {
|
||||
}
|
||||
|
||||
RefPtr<PrintEndDocumentPromise> nsDeviceContextSpecWin::EndDocument() {
|
||||
return nsIDeviceContextSpec::EndDocumentPromiseFromResult(DoEndDocument(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextSpecWin::DoEndDocument() {
|
||||
if (mPrintSettings->GetOutputDestination() !=
|
||||
nsIPrintSettings::kOutputDestinationFile ||
|
||||
mOutputFormat != nsIPrintSettings::kOutputFormatPDF) {
|
||||
return NS_OK;
|
||||
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_SKIA_PDF
|
||||
if (mPrintViaSkPDF) {
|
||||
return NS_OK;
|
||||
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -356,25 +351,32 @@ nsresult nsDeviceContextSpecWin::DoEndDocument() {
|
||||
mPrintSettings->GetToFileName(targetPath);
|
||||
|
||||
if (targetPath.IsEmpty()) {
|
||||
return NS_OK;
|
||||
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
// We still need to move the file to its actual destination.
|
||||
nsCOMPtr<nsIFile> destFile;
|
||||
MOZ_TRY(NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile)));
|
||||
nsAutoString destLeafName;
|
||||
MOZ_TRY(destFile->GetLeafName(destLeafName));
|
||||
auto rv = NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return PrintEndDocumentPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> destDir;
|
||||
MOZ_TRY(destFile->GetParent(getter_AddRefs(destDir)));
|
||||
return nsIDeviceContextSpec::EndDocumentAsync(
|
||||
__func__,
|
||||
[destFile = std::move(destFile),
|
||||
tempFile = std::move(mTempFile)]() -> nsresult {
|
||||
nsAutoString destLeafName;
|
||||
MOZ_TRY(destFile->GetLeafName(destLeafName));
|
||||
|
||||
// This should be fine - Windows API calls usually prevent moving between
|
||||
// different volumes (See Win32 API's `MOVEFILE_COPY_ALLOWED` flag), but we
|
||||
// handle that down this call.
|
||||
MOZ_TRY(mTempFile->MoveTo(destDir, destLeafName));
|
||||
mTempFile = nullptr;
|
||||
nsCOMPtr<nsIFile> destDir;
|
||||
MOZ_TRY(destFile->GetParent(getter_AddRefs(destDir)));
|
||||
|
||||
return NS_OK;
|
||||
// This should be fine - Windows API calls usually prevent moving
|
||||
// between different volumes (See Win32 API's `MOVEFILE_COPY_ALLOWED`
|
||||
// flag), but we handle that down this call.
|
||||
MOZ_TRY(tempFile->MoveTo(destDir, destLeafName));
|
||||
return NS_OK;
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -69,9 +69,6 @@ class nsDeviceContextSpecWin : public nsIDeviceContextSpec {
|
||||
// A temporary file to create an "anonymous" print target. See bug 1664253,
|
||||
// this should ideally not be needed.
|
||||
nsCOMPtr<nsIFile> mTempFile;
|
||||
|
||||
private:
|
||||
nsresult DoEndDocument();
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user