Bug 1805477 - Prevent pages-per-sheet on macOS being double applied by system print dialog. r=dholbert

Note: NSPagesAcross/NSPagesDown is internal API to Apple and is basically
unknown to the Internet. I discovered it by digging through printing structs in
a debugger while trying to find out how the pages-per-sheet information was
being communicated internally in Cocoa. However, after finding it, I see Google
knows about a grand total of 18 pages on the Internet that mention it, all as
part of debug info dumps. That's still helpful though, since it shows that
these two dictionary entries have been in use since at least 2008, giving some
confidence about backwards compatibility and that it will likely remain in use.

Related to these dictionary keys, Apple's official documentation claims that
there are similarly named keys called NSPrintPagesAcross/NSPrintPagesDown:

https://developer.apple.com/documentation/appkit/nsprintpagesacross
https://developer.apple.com/documentation/appkit/nsprintpagesdown

However, I couldn't get those to work, either to read values or to set values.
The references I could find to them on the Internet were in debug output and
people also stating they couldn't get them to work. I have to wonder if someone
at Apple changed the names at some point and forgot to update the
documentation?!

Finally, note that NSPrintPagesPerSheet is long deprecated and nowadays just
has a dummy value of "1" hardcoded.

https://developer.apple.com/documentation/appkit/nsprintpagespersheet

Differential Revision: https://phabricator.services.mozilla.com/D164317
This commit is contained in:
Jonathan Watt 2022-12-14 00:40:38 +00:00
Родитель 1d98de863a
Коммит 93e114e684
1 изменённых файлов: 56 добавлений и 0 удалений

Просмотреть файл

@ -25,6 +25,46 @@ using mozilla::gfx::PrintTarget;
NS_IMPL_ISUPPORTS(nsPrintDialogServiceX, nsIPrintDialogService)
// Splits our single pages-per-sheet count for native NSPrintInfo:
static void setPagesPerSheet(NSPrintInfo* aPrintInfo, int32_t aPPS) {
int32_t across, down;
// Assumes portrait - we'll swap if landscape.
switch (aPPS) {
case 2:
across = 1;
down = 2;
break;
case 4:
across = 2;
down = 2;
break;
case 6:
across = 2;
down = 3;
break;
case 9:
across = 3;
down = 3;
break;
case 16:
across = 4;
down = 4;
break;
default:
across = 1;
down = 1;
break;
}
if ([aPrintInfo orientation] == NSPaperOrientationLandscape) {
std::swap(across, down);
}
NSMutableDictionary* dict = [aPrintInfo dictionary];
[dict setObject:[NSNumber numberWithInt:across] forKey:@"NSPagesAcross"];
[dict setObject:[NSNumber numberWithInt:down] forKey:@"NSPagesDown"];
}
nsPrintDialogServiceX::nsPrintDialogServiceX() {}
nsPrintDialogServiceX::~nsPrintDialogServiceX() {}
@ -74,6 +114,12 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
}
}
// Temporarily set the pages-per-sheet count set in our print preview to
// pre-populate the system dialog with the same value:
int32_t pagesPerSheet;
aSettings->GetNumPagesPerSheet(&pagesPerSheet);
setPagesPerSheet(printInfo, pagesPerSheet);
// Put the print info into the current print operation, since that's where
// [panel runModal] will look for it. We create the view because otherwise
// we'll get unrelated warnings printed to the console.
@ -111,6 +157,16 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
return NS_ERROR_ABORT;
}
// We handle pages-per-sheet internally and we want to prevent the macOS
// printing code from also applying the pages-per-sheet count. So we need
// to move the count off the NSPrintInfo and over to the nsIPrintSettings.
NSMutableDictionary* dict = [result dictionary];
auto pagesAcross = [[dict objectForKey:@"NSPagesAcross"] intValue];
auto pagesDown = [[dict objectForKey:@"NSPagesDown"] intValue];
[dict setObject:[NSNumber numberWithUnsignedInt:1] forKey:@"NSPagesAcross"];
[dict setObject:[NSNumber numberWithUnsignedInt:1] forKey:@"NSPagesDown"];
aSettings->SetNumPagesPerSheet(pagesAcross * pagesDown);
// Export settings.
[viewController exportSettings];