Broken page setup logic in gtkprintoperation-win32, page setup not saved
Steps to reproduce
- run gedit
- hamburger->print
- select a printer
- open printer properties
- select non-default (landscape) page orientation
- press apply
- press cancel
- hamburger->print
- select the same printer
- open printer properties
Current behavior
Page orientation is portrait (default) again
Expected outcome
Page orientation should still be landscape, because we just set it to landscape in the previous operation
Version information
gtk-3.24.5
Additional information
There's !396 (merged) that fixes printer settings saving, so that is one part of the puzzle. But even if i apply that MR, page orientation (portrait/landscape) and paper size (A4/A5...) are still not saved.
Debugging led me to realize that paper properties are saved in GtkPrintSettings just fine (i've dumped them as GVariant to be sure), the problem lies in these parts of gtkprintoperation-win32.c
:
if (page_setup ||
gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
{
GtkPageOrientation orientation = gtk_print_settings_get_orientation (settings);
if (page_setup)
orientation = gtk_page_setup_get_orientation (page_setup);
devmode->dmFields |= DM_ORIENTATION;
devmode->dmOrientation = orientation_to_win32 (orientation);
}
if (page_setup)
paper_size = gtk_paper_size_copy (gtk_page_setup_get_paper_size (page_setup));
else
{
int size;
if (gtk_print_settings_has_key (settings, "win32-paper-size") &&
(size = gtk_print_settings_get_int (settings, "win32-paper-size")) != 0)
{
devmode->dmFields |= DM_PAPERSIZE;
devmode->dmPaperSize = size;
paper_size = NULL;
}
else
paper_size = gtk_print_settings_get_paper_size (settings);
}
if (paper_size)
{
devmode->dmFields |= DM_PAPERSIZE;
devmode->dmPaperSize = paper_size_to_win32 (paper_size);
As you can see, page orientation and paper size are taken from either page_setup
or settings
, and page_setup
takes precedence. Thing is, page_setup
is passed like this:
printdlgex->hDevMode = devmode_from_settings (settings,
op->priv->default_page_setup);
I.e. it just passes the default_page_setup
property of the GtkPrintOperation
, which is set by gedit in accordance to the documentation for gtk_print_operation_run()
. It's never NULL, so it is always used, and settings from GtkPrintSettings
are ignored.
Another problem is devmode_to_settings()
, which does the opposite conversion. Note its signature:
static void
devmode_to_settings (GtkPrintSettings *settings,
HANDLE hDevMode)
I.e. it doesn't take a GtkPageSetup
and only passes the settings back to GtkPrintSettings
. So GtkPageSetup
page orientation and size never change, yet they are always used to initialize the print dialog.
gtkprintunixdialog.c
logic is too different from its Windows counterpart for me to be able to analyze both and make conclusions on the correctness of the Windows code.
I'm currently thinking on how to fix this, but here are the questions that bothers me:
- Are page setup settings per-printer or global? Same goes for printer settings. Notepad (i know, not a good app to look up to) has a separate page setup dialog, which changes the page orientation/size that are shown in the print dialog. Also, changes to paper orientation/size in the print dialog affect the settings in the page setup dialog. Also, these settings are global (apply to all printers; you don't even need to close the printing dialog for that to happen).
- Should we really be saving page-related settings in
GtkPrintSettings
at all? Maybe we should save them inGtkPageSetup
...