From 3a11e9c9ce72e36c6124e9dc2f8379df4f004ea9 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Thu, 28 Sep 2023 12:58:46 +0200 Subject: [PATCH] print: Use same print operation throughout Use a hack to wait in print signal for the layout dialog to be ready instead of creating a new print operation with the same settings. This works around a bug in GTK where the wrong printer gets selected (issue #243), as well as the print dialog getting shown twice when using the print portal (part of #61). --- src/widgets/print.rs | 60 +++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/widgets/print.rs b/src/widgets/print.rs index 2ad0efb4..7c8a4657 100644 --- a/src/widgets/print.rs +++ b/src/widgets/print.rs @@ -53,6 +53,14 @@ enum VAlignment { Bottom, } +#[derive(Debug, Clone, Copy, Default)] +enum Status { + #[default] + Prepare, + Print, + Abort, +} + /// Scope guard for non user ui changes /// /// Creates a context in which other signals know that changes are not user input. @@ -250,6 +258,8 @@ mod imp { pub(super) orientation: RefCell, pub(super) ui_updates: UiUpdates, + + pub(super) status: Cell, } #[glib::object_subclass] @@ -291,6 +301,11 @@ mod imp { obj.set_transient_for(Some(&obj.parent_window())); obj.set_modal(true); + obj.connect_close_request(|obj| { + obj.imp().status.set(Status::Abort); + glib::Propagation::Proceed + }); + self.alignment .connect_selected_notify(glib::clone!(@weak obj => move |_| obj.draw_preview())); @@ -341,7 +356,7 @@ mod imp { }); self.print_operation.connect_draw_page(glib::clone!(@weak obj => - move |operation, _context, _page_nr| { + move |operation, context, _page_nr| { let imp = obj.imp(); let basename = obj @@ -394,8 +409,6 @@ mod imp { } } - imp.print_operation.cancel(); - let orientation = match obj.page_setup().orientation() { gtk::PageOrientation::Portrait => "portrait", gtk::PageOrientation::Landscape => "landscape", @@ -404,6 +417,23 @@ mod imp { obj.set_orientation(orientation); obj.present(); + + loop { + match imp.status.get() { + Status::Prepare => { + glib::MainContext::default().iteration(true); + } + Status::Print => { + log::debug!("Layout dialog confirmed"); + obj.draw_page(context); + break;} + Status::Abort => { + log::debug!("Layout dialog aborted"); + imp.print_operation.cancel(); + break; + } + } + } } )); } @@ -802,8 +832,6 @@ impl LpPrint { fn print(&self) { self.close(); - let print_operation = gtk::PrintOperation::new(); - let print_settings = self.print_operation().print_settings(); if let Some(print_settings) = &print_settings { @@ -812,27 +840,7 @@ impl LpPrint { } } - print_operation.set_print_settings(print_settings.as_ref()); - print_operation.set_default_page_setup(Some(&self.print_operation().default_page_setup())); - - print_operation.connect_begin_print(move |op, _ctx| { - op.set_n_pages(1); - }); - - print_operation.connect_draw_page( - glib::clone!(@weak self as obj => move |_operation, context, _page_nr| { - obj.draw_page(context); - }), - ); - - let res = print_operation.run( - gtk::PrintOperationAction::Print, - Some(&self.parent_window()), - ); - - if let Err(err) = res { - log::warn!("Print error: {err}"); - } + self.imp().status.set(Status::Print); } /// Draw PDF for printing -- GitLab