From 1eb4c8e65394ab2eeb20f0d5b39677c503c09732 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 20 Aug 2020 10:27:16 -0700 Subject: [PATCH] fix: honor pageRanges on macOS --- docs/api/web-contents.md | 14 ++--- docs/api/webview-tag.md | 12 ++-- patches/chromium/.patches | 1 + ..._properly_honor_print_range_on_macos.patch | 63 +++++++++++++++++++ .../browser/api/electron_api_web_contents.cc | 5 +- 5 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 patches/chromium/fix_properly_honor_print_range_on_macos.patch diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 0aa5609c9344d..c64099ffeb2fe 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1296,9 +1296,9 @@ Returns [`PrinterInfo[]`](structures/printer-info.md) * `pagesPerSheet` Number (optional) - The number of pages to print per page sheet. * `collate` Boolean (optional) - Whether the web page should be collated. * `copies` Number (optional) - The number of copies of the web page to print. - * `pageRanges` Record (optional) - The page range to print. - * `from` Number - the start page. - * `to` Number - the end page. + * `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored. + * `from` Number - Index of the first page to print (0-based). + * `to` Number - Index of the last page to print (inclusive) (0-based). * `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`. * `dpi` Record (optional) * `horizontal` Number (optional) - The horizontal dpi. @@ -1324,10 +1324,10 @@ Example usage: const options = { silent: true, deviceName: 'My-Printer', - pageRanges: { + pageRanges: [{ from: 0, to: 1 - } + }] } win.webContents.print(options, (success, errorType) => { if (!success) console.log(errorType) @@ -1345,8 +1345,8 @@ win.webContents.print(options, (success, errorType) => { default margin, 1 for no margin, and 2 for minimum margin. * `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100. * `pageRanges` Record (optional) - The page range to print. - * `from` Number - zero-based index of the first page to print. - * `to` Number - zero-based index of the last page to print (inclusive). + * `from` Number - Index of the first page to print (0-based). + * `to` Number - Index of the last page to print (inclusive) (0-based). * `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`, `A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns. * `printBackground` Boolean (optional) - Whether to print CSS backgrounds. diff --git a/docs/api/webview-tag.md b/docs/api/webview-tag.md index 65d3c2284d7f1..05325fe7cf543 100644 --- a/docs/api/webview-tag.md +++ b/docs/api/webview-tag.md @@ -560,9 +560,9 @@ Stops any `findInPage` request for the `webview` with the provided `action`. * `pagesPerSheet` Number (optional) - The number of pages to print per page sheet. * `collate` Boolean (optional) - Whether the web page should be collated. * `copies` Number (optional) - The number of copies of the web page to print. - * `pageRanges` Record (optional) - The page range to print. - * `from` Number - zero-based index of the first page to print. - * `to` Number - zero-based index of the last page to print (inclusive). + * `pageRanges` Object[] (optional) - The page range to print. + * `from` Number - Index of the first page to print (1-based). + * `to` Number - Index of the last page to print (inclusive) (1-based). * `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`. * `dpi` Record (optional) * `horizontal` Number (optional) - The horizontal dpi. @@ -587,9 +587,9 @@ Prints `webview`'s web page. Same as `webContents.print([options])`. default margin, 1 for no margin, and 2 for minimum margin. and `width` in microns. * `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100. - * `pageRanges` Record (optional) - The page range to print. - * `from` Number - the first page to print. - * `to` Number - the last page to print (inclusive). + * `pageRanges` Record (optional) - The page range to print. On macOS, only the first range is honored. + * `from` Number - Index of the first page to print (0-based). + * `to` Number - Index of the last page to print (inclusive) (0-based). * `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`, `A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` * `printBackground` Boolean (optional) - Whether to print CSS backgrounds. diff --git a/patches/chromium/.patches b/patches/chromium/.patches index e43f9e4ab97ef..da29395218d2f 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -100,3 +100,4 @@ remove_some_deps_that_do_not_work_on_arm64.patch fix_check_issecureeventinputenabled_in_constructor_before_setting.patch skip_atk_toolchain_check.patch worker_feat_add_hook_to_notify_script_ready.patch +fix_properly_honor_print_range_on_macos.patch diff --git a/patches/chromium/fix_properly_honor_print_range_on_macos.patch b/patches/chromium/fix_properly_honor_print_range_on_macos.patch new file mode 100644 index 0000000000000..03d0b05ac2bf4 --- /dev/null +++ b/patches/chromium/fix_properly_honor_print_range_on_macos.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Shelley Vohr +Date: Thu, 20 Aug 2020 10:55:48 -0700 +Subject: fix: properly honor print range on macOS + +The print ranges in Chromium's print job settings were not being properly +plumbed through to PMPrintSettings on mcOS. This fixes that by setting +them should they exist. + +This will be upstreamed. + +diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h +index 06cdc0e1a4a50e29a148c97c964c30a939e800da..5db5cdb61be0beee4506313dcde46c499e011383 100644 +--- a/printing/printing_context_mac.h ++++ b/printing/printing_context_mac.h +@@ -81,6 +81,10 @@ class PRINTING_EXPORT PrintingContextMac : public PrintingContext { + // Returns true if the orientation was set. + bool SetOrientationIsLandscape(bool landscape); + ++ // Set the page range in native print info object. ++ // Returns true if the range was set. ++ bool SetPrintRangeInPrintSettings(const PageRanges& ranges); ++ + // Sets duplex mode in PMPrintSettings. + // Returns true if duplex mode is set. + bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode); +diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm +index 56bcfbe625537c7b1bc2a999c261836bb15896ba..3965b877718160ce55e7c97d75e8992f45ac3f2f 100644 +--- a/printing/printing_context_mac.mm ++++ b/printing/printing_context_mac.mm +@@ -188,7 +188,8 @@ PMPaper MatchPaper(CFArrayRef paper_list, + !SetCopiesInPrintSettings(settings_->copies()) || + !SetCollateInPrintSettings(settings_->collate()) || + !SetDuplexModeInPrintSettings(settings_->duplex_mode()) || +- !SetOutputColor(settings_->color())) { ++ !SetOutputColor(settings_->color()) || ++ !SetPrintRangeInPrintSettings(settings_->ranges()) ) { + return OnError(); + } + } +@@ -341,6 +342,22 @@ PMPaper MatchPaper(CFArrayRef paper_list, + return PMSetCopies(print_settings, copies, false) == noErr; + } + ++bool PrintingContextMac::SetPrintRangeInPrintSettings(const PageRanges& ranges) { ++ // Default is already NSPrintAllPages - we can safely bail. ++ if (ranges.empty()) ++ return true; ++ ++ PMPrintSettings print_settings = ++ static_cast([print_info_.get() PMPrintSettings]); ++ ++ // macOS does not allow multiple ranges, so pluck the first. ++ auto range = ranges.front(); ++ bool set_first_page = PMSetFirstPage(print_settings, range.from + 1, false) == noErr; ++ bool set_last_page = PMSetLastPage(print_settings, range.to + 1, false) == noErr; ++ ++ return set_first_page && set_last_page; ++} ++ + bool PrintingContextMac::SetCollateInPrintSettings(bool collate) { + PMPrintSettings print_settings = + static_cast([print_info_.get() PMPrintSettings]); diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 5b8f25cb0fa3c..d23fd2ac71541 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -2073,8 +2073,9 @@ void WebContents::Print(gin::Arguments* args) { int from, to; if (range.Get("from", &from) && range.Get("to", &to)) { base::Value range(base::Value::Type::DICTIONARY); - range.SetIntKey(printing::kSettingPageRangeFrom, from); - range.SetIntKey(printing::kSettingPageRangeTo, to); + // Chromium uses 1-based page ranges, so increment each by 1. + range.SetIntKey(printing::kSettingPageRangeFrom, from + 1); + range.SetIntKey(printing::kSettingPageRangeTo, to + 1); page_range_list.Append(std::move(range)); } else { continue;