I've been hand-writing GOTV postcards for two organizations1, and I decided to write a quick app to print address labels for one of them. (The other requires hand-written addresses.) It's been a long time since I did any coding, and this seemed like a nice low-stakes project to start the Cocoa wheels turning in my head again2. Worst case, I could always throw the code away and use mail-merge in Word or Pages like a normal person.
I soon had a fully functional app — not in a state to share publicly, but good enough for personal use.
There was one thing that bugged me though.
If your printer supports double-sided printing, the macOS print panel always defaults to double-sided, no matter what option you chose the last time you printed. This is apparently on purpose and has been the case for a while now.
I found that as a user you can change this with a few simple steps:
sudoprivileges, enable the web interface to CUPS.
- And I stopped reading there, because WTF.
Okay, well, I figured I'm writing the printing code in my app, so as the All-Powerful Programmer all I have to do is set the
NSPrintInfo's duplex mode to
kPMDuplexNone, which indicates single-sided printing. But no, AppKit blows away the value I set and forces the duplex mode to
kPMDuplexNoTumble, which indicates double-sided printing.
The only workaround I could figure out was to subclass
NSPrintPanel and override the method that opens the print panel in a sheet. My override sets the duplex mode immediately after the sheet is presented, replacing the double-sided setting AppKit stuck in, and doing so before the user interacts with the print panel. You can see my code on GitHub.
I haven't looked at how (or whether) commercial label-printing programs deal with this issue. All I know is how I dealt with it. [EDIT: It occurred to me that one way would be to not use the system print panel at all, but rather to implement one's own print panel, like Google Chrome does. Doable, but not worth it for me, and IMO it's not great to have to resort to re-implementing standard system UI just to work around a quirk.]
Unfortunately this is not a generally useful workaround, because the "Two-Sided" checkbox in the print panel is still checked, which means it does not accurately reflect the state of the
NSPrintInfo. My app hides the checkbox, but this means it also hides the number-of-copies text field. This is okay for my purposes. I never want multiple copies, and because I'm printing labels I never want double-sided.
Right now I'm too lazy, but I should probably file a Feedback ticket:
- I want the ability for my app to force single-sided every time instead of AppKit insisting on double-sided3. Another way of putting it is that I'd like the controls in the print panel to accurately reflect the values they correspond to in the
NSPrintInfoinstance I provide.
- I want to be able to hide just the "Two-Sided" checkbox without having to hide the number-of-copies text field.
- It might make sense for AppKit to default to single-sided printing, if not outright force it, when "Labels" is chosen as the media type.
In the latest Big Sur beta (20A5374i as of 2020-09-30) I think there is a change I did not see in the release notes. If I'm not mistaken, the "Two-Sided" checkbox remembers its setting between invocations of the print panel. But this doesn't help me. I need to always force single-sided. ↩