mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: prefill native print dialog options on macOS with OOP printing (#50643)
Chromium enabled out-of-process (OOP) printing by default on macOS in https://chromium-review.googlesource.com/c/chromium/src/+/6032774. This broke webContents.print() option prefilling (e.g. copies, collate, duplex) in two ways: 1. ScriptedPrint() silently aborted because RegisterSystemPrintClient() was only called from GetDefaultPrintSettings(), but Electron's flow calls UpdatePrintSettings() instead when options are provided. 2. PrinterQueryOop::UpdatePrintSettings() sends settings to the remote PrintBackend service, but on macOS the native dialog runs in-browser using the local PrintingContextMac::print_info_, which was never updated with the user's requested settings. Fix by registering the system print client in UpdatePrintSettings() and applying cached settings to the local printing context before showing the in-browser system print dialog. Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
@@ -68,7 +68,7 @@ index f91857eb0b6ad385721b8224100de26dfdd7dd8d..45e8766fcb8d46d8edc3bf8d21d3f826
|
||||
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
|
||||
}
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f0c49c1e8 100644
|
||||
index aa79c324af2cec50019bca3bccff5d420fb30ffd..0b85598f87673537eccdd0b310e8462e96990d04 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -80,6 +80,20 @@ namespace printing {
|
||||
@@ -260,12 +260,18 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
if (prefs && prefs->HasPrefPath(prefs::kPrintRasterizePdfDpi)) {
|
||||
int value = prefs->GetInteger(prefs::kPrintRasterizePdfDpi);
|
||||
if (value > 0)
|
||||
@@ -740,8 +765,22 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -740,8 +765,28 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
}
|
||||
}
|
||||
|
||||
-#if BUILDFLAG(IS_WIN)
|
||||
- // TODO(crbug.com/40260379): Remove this if the printable areas can be made
|
||||
+#if BUILDFLAG(ENABLE_OOP_PRINTING)
|
||||
+ if (ShouldPrintJobOop() && !query_with_ui_client_id().has_value()) {
|
||||
+ RegisterSystemPrintClient();
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ std::unique_ptr<PrinterQuery> query =
|
||||
+ queue_->CreatePrinterQuery(GetCurrentTargetFrame()->GetGlobalId());
|
||||
+ auto* query_ptr = query.get();
|
||||
@@ -285,7 +291,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
// fully available from `PrintBackend::GetPrinterSemanticCapsAndDefaults()`
|
||||
// for in-browser queries.
|
||||
if (printer_type == mojom::PrinterType::kLocal) {
|
||||
@@ -762,8 +801,6 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -762,8 +807,6 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -294,7 +300,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::SetAccessibilityTree(
|
||||
@@ -779,7 +816,7 @@ void PrintViewManagerBase::SetAccessibilityTree(
|
||||
@@ -779,7 +822,7 @@ void PrintViewManagerBase::SetAccessibilityTree(
|
||||
void PrintViewManagerBase::IsPrintingEnabled(
|
||||
IsPrintingEnabledCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -303,7 +309,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
|
||||
@@ -805,7 +842,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
|
||||
@@ -805,7 +848,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -312,7 +318,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
std::optional<enterprise_connectors::ContentAnalysisDelegate::Data>
|
||||
scanning_data = enterprise_data_protection::GetPrintAnalysisData(
|
||||
web_contents(), enterprise_data_protection::PrintScanningContext::
|
||||
@@ -835,11 +872,9 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
|
||||
@@ -835,11 +878,9 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
|
||||
// destroyed. In such cases the error notification to the user will
|
||||
// have already been displayed, and a second message should not be
|
||||
// shown.
|
||||
@@ -326,7 +332,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
ReleasePrinterQuery();
|
||||
}
|
||||
|
||||
@@ -851,15 +886,33 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
|
||||
@@ -851,15 +892,33 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
|
||||
test_observers_.RemoveObserver(&observer);
|
||||
}
|
||||
|
||||
@@ -360,7 +366,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::RenderFrameDeleted(
|
||||
@@ -901,13 +954,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
|
||||
@@ -901,13 +960,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
|
||||
// System dialog was cancelled. Clean up the print job and notify the
|
||||
// BackgroundPrintingManager.
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -376,7 +382,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnDocDone(int job_id, PrintedDocument* document) {
|
||||
@@ -921,18 +975,26 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
@@ -921,18 +981,26 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
// Printing is done, we don't need it anymore.
|
||||
// print_job_->is_job_pending() may still be true, depending on the order
|
||||
// of object registration.
|
||||
@@ -405,7 +411,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
TerminatePrintJob(true);
|
||||
}
|
||||
|
||||
@@ -942,7 +1004,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||
@@ -942,7 +1010,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||
|
||||
// Is the document already complete?
|
||||
if (print_job_->document() && print_job_->document()->IsComplete()) {
|
||||
@@ -414,7 +420,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -995,7 +1057,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
@@ -995,7 +1063,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
|
||||
// Disconnect the current `print_job_`.
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
@@ -426,7 +432,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
if (!weak_this)
|
||||
return false;
|
||||
|
||||
@@ -1015,7 +1080,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
@@ -1015,7 +1086,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
|
||||
#endif
|
||||
print_job_->AddObserver(*this);
|
||||
|
||||
@@ -435,7 +441,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1073,7 +1138,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1073,7 +1144,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
// Ensure that any residual registration of printing client is released.
|
||||
// This might be necessary in some abnormal cases, such as the associated
|
||||
// render process having terminated.
|
||||
@@ -444,7 +450,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
if (!analyzing_content_) {
|
||||
UnregisterSystemPrintClient();
|
||||
}
|
||||
@@ -1083,6 +1148,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1083,6 +1154,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -456,7 +462,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
if (!print_job_)
|
||||
return;
|
||||
|
||||
@@ -1090,7 +1160,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -1090,7 +1166,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
// printing_rfh_ should only ever point to a RenderFrameHost with a live
|
||||
// RenderFrame.
|
||||
DCHECK(rfh->IsRenderFrameLive());
|
||||
@@ -465,7 +471,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
}
|
||||
|
||||
print_job_->RemoveObserver(*this);
|
||||
@@ -1132,7 +1202,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -1132,7 +1208,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
@@ -474,7 +480,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
return true;
|
||||
|
||||
if (!cookie) {
|
||||
@@ -1155,7 +1225,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
@@ -1155,7 +1231,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -483,7 +489,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
// Don't start printing if enterprise checks are being performed to check if
|
||||
// printing is allowed, or if content analysis is going to take place right
|
||||
// before starting `print_job_`.
|
||||
@@ -1286,6 +1356,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
@@ -1286,6 +1362,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
auto callback_wrapper = base::BindOnce(
|
||||
&PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
|
||||
std::move(callback), render_process_host->GetDeprecatedID());
|
||||
@@ -492,7 +498,7 @@ index aa79c324af2cec50019bca3bccff5d420fb30ffd..455095a2cd63eabe4f267747070b443f
|
||||
std::unique_ptr<PrinterQuery> printer_query =
|
||||
queue()->PopPrinterQuery(params->cookie);
|
||||
if (!printer_query)
|
||||
@@ -1296,10 +1368,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
@@ -1296,10 +1374,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
|
||||
params->expected_pages_count, params->has_selection, params->margin_type,
|
||||
params->is_scripted, !render_process_host->IsPdf(),
|
||||
base::BindOnce(&OnDidScriptedPrint, queue_, std::move(printer_query),
|
||||
@@ -614,7 +620,7 @@ index 2a477e820d9f0126a05f86cd44f02c2189275bad..a2e9442ff9f5acf8e301f457b1806251
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc
|
||||
index dc2a15ab4d784b0b6c85b84a30c3c08a17ed8e3d..8facb5981cc421cad6bce71dfa8985b0a3270405 100644
|
||||
index dc2a15ab4d784b0b6c85b84a30c3c08a17ed8e3d..e197026e8a7f132c1bf90a0f5f1eabb4f5f064ee 100644
|
||||
--- a/chrome/browser/printing/printer_query_oop.cc
|
||||
+++ b/chrome/browser/printing/printer_query_oop.cc
|
||||
@@ -126,7 +126,7 @@ void PrinterQueryOop::OnDidAskUserForSettings(
|
||||
@@ -626,6 +632,28 @@ index dc2a15ab4d784b0b6c85b84a30c3c08a17ed8e3d..8facb5981cc421cad6bce71dfa8985b0
|
||||
// Want the same PrintBackend service as the query so that we use the same
|
||||
// device context.
|
||||
print_document_client_id_ =
|
||||
@@ -189,6 +189,21 @@ void PrinterQueryOop::GetSettingsWithUI(uint32_t document_page_count,
|
||||
// browser process.
|
||||
// - Other platforms don't have a system print UI or do not use OOP
|
||||
// printing, so this does not matter.
|
||||
+
|
||||
+ // Apply cached settings to the local printing context so that the in-browser
|
||||
+ // system print dialog is prefilled with user-specified options (e.g. copies,
|
||||
+ // collate, duplex). OOP UpdatePrintSettings only applies settings to the
|
||||
+ // remote service context, not the local one used by the native dialog.
|
||||
+ if (settings().dpi()) {
|
||||
+ printing_context()->SetPrintSettings(settings());
|
||||
+ printing_context()->UpdatePrinterSettings(PrintingContext::PrinterSettings{
|
||||
+#if BUILDFLAG(IS_MAC)
|
||||
+ .external_preview = false,
|
||||
+#endif
|
||||
+ .show_system_dialog = false,
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
PrinterQuery::GetSettingsWithUI(
|
||||
document_page_count, has_selection, is_scripted,
|
||||
base::BindOnce(&PrinterQueryOop::OnDidAskUserForSettings,
|
||||
diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc
|
||||
index 21c81377d32ae8d4185598a7eba88ed1d2063ef0..0767f4e9369e926b1cea99178c1a1975941f1765 100644
|
||||
--- a/components/printing/browser/print_manager.cc
|
||||
|
||||
Reference in New Issue
Block a user