[gtk/fix-printer-enumeration: 30/30] Fix dialog-less printing




commit c6a68f3de293c91b3a5a83642b10fddd25ef57f5
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Nov 30 22:07:02 2021 -0500

    Fix dialog-less printing
    
    We were sometimes ending printer enumeration prematurely,
    and the code was confused about the meaning of found_printer.
    
    The new setup follows these rules:
    - We *only* end the search prematurely if found_printer
      is set, which indicates that we found the right printer
    - We *always* call find_printer_idle exactly once, and
      make it return less than perfect matches like the
      default printer, or the first printer we found
    
    Fixes: #4439

 gtk/gtkprintoperation-unix.c | 186 +++++++++++++++++++++----------------------
 1 file changed, 93 insertions(+), 93 deletions(-)
---
diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c
index 644100898b..0096ed91da 100644
--- a/gtk/gtkprintoperation-unix.c
+++ b/gtk/gtkprintoperation-unix.c
@@ -1,5 +1,5 @@
 /* GTK - The GIMP Toolkit
- * gtkprintoperation-unix.c: Print Operation Details for Unix 
+ * gtkprintoperation-unix.c: Print Operation Details for Unix
  *                           and Unix-like platforms
  * Copyright (C) 2006, Red Hat, Inc.
  *
@@ -25,7 +25,7 @@
 #include <sys/stat.h>
 #include <string.h>
 #include <errno.h>
-#include <stdlib.h>       
+#include <stdlib.h>
 #include <fcntl.h>
 
 #include <glib/gstdio.h>
@@ -45,7 +45,7 @@
 #include "gtkintl.h"
 
 
-typedef struct 
+typedef struct
 {
   GtkWindow *parent;        /* just in case we need to throw error dialogs */
   GMainLoop *loop;
@@ -56,7 +56,7 @@ typedef struct
   cairo_surface_t *surface;
   gulong job_status_changed_tag;
 
-  
+
 } GtkPrintOperationUnix;
 
 typedef struct _PrinterFinder PrinterFinder;
@@ -71,18 +71,18 @@ unix_start_page (GtkPrintOperation *op,
                 GtkPrintContext   *print_context,
                 GtkPageSetup      *page_setup)
 {
-  GtkPrintOperationUnix *op_unix;  
+  GtkPrintOperationUnix *op_unix;
   GtkPaperSize *paper_size;
   cairo_surface_type_t type;
   double w, h;
 
   op_unix = op->priv->platform_data;
-  
+
   paper_size = gtk_page_setup_get_paper_size (page_setup);
 
   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
-  
+
   type = cairo_surface_get_type (op_unix->surface);
 
   if ((op->priv->manual_number_up < 2) ||
@@ -167,11 +167,11 @@ shell_command_substitute_file (const char *cmd,
   *settings_filename_replaced = FALSE;
 
   start = inptr = cmd;
-  while ((inptr = strchr (inptr, '%')) != NULL) 
+  while ((inptr = strchr (inptr, '%')) != NULL)
     {
       g_string_append_len (final, start, inptr - start);
       inptr++;
-      switch (*inptr) 
+      switch (*inptr)
         {
           case 'f':
             g_string_append (final, pdf_filename);
@@ -236,11 +236,11 @@ gtk_print_operation_unix_launch_preview (GtkPrintOperation *op,
     display = gdk_display_get_default ();
 
   fd = g_file_open_tmp ("settingsXXXXXX.ini", &settings_filename, &error);
-  if (fd < 0) 
+  if (fd < 0)
     goto out;
 
   key_file = g_key_file_new ();
-  
+
   print_settings = gtk_print_settings_copy (gtk_print_operation_get_print_settings (op));
 
   if (print_settings != NULL)
@@ -345,7 +345,7 @@ gtk_print_operation_unix_launch_preview (GtkPrintOperation *op,
 
 static void
 unix_finish_send  (GtkPrintJob  *job,
-                   gpointer      user_data, 
+                   gpointer      user_data,
                    const GError *error)
 {
   GtkPrintOperation *op = (GtkPrintOperation *) user_data;
@@ -370,19 +370,19 @@ unix_end_run (GtkPrintOperation *op,
   GtkPrintOperationUnix *op_unix = op->priv->platform_data;
 
   cairo_surface_finish (op_unix->surface);
-  
+
   if (cancelled)
     return;
 
   if (wait)
     op_unix->loop = g_main_loop_new (NULL, FALSE);
-  
+
   /* TODO: Check for error */
   if (op_unix->job != NULL)
     {
       g_object_ref (op);
       gtk_print_job_send (op_unix->job,
-                          unix_finish_send, 
+                          unix_finish_send,
                           op, NULL);
     }
 
@@ -398,7 +398,7 @@ unix_end_run (GtkPrintOperation *op,
 }
 
 static void
-job_status_changed_cb (GtkPrintJob       *job, 
+job_status_changed_cb (GtkPrintJob       *job,
                       GtkPrintOperation *op)
 {
   _gtk_print_operation_set_status (op, gtk_print_job_get_status (job), NULL);
@@ -406,7 +406,7 @@ job_status_changed_cb (GtkPrintJob       *job,
 
 
 static void
-print_setup_changed_cb (GtkPrintUnixDialog *print_dialog, 
+print_setup_changed_cb (GtkPrintUnixDialog *print_dialog,
                         GParamSpec         *pspec,
                         gpointer            user_data)
 {
@@ -450,13 +450,13 @@ get_print_dialog (GtkPrintOperation *op,
                                        priv->print_settings);
 
   if (priv->default_page_setup)
-    gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd), 
+    gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd),
                                           priv->default_page_setup);
 
   gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (pd),
                                               priv->embed_page_setup);
 
-  gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd), 
+  gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd),
                                           priv->current_page);
 
   gtk_print_unix_dialog_set_support_selection (GTK_PRINT_UNIX_DIALOG (pd),
@@ -468,10 +468,10 @@ get_print_dialog (GtkPrintOperation *op,
   g_signal_emit_by_name (op, "create-custom-widget",
                         &priv->custom_widget);
 
-  if (priv->custom_widget) 
+  if (priv->custom_widget)
     {
       custom_tab_label = priv->custom_tab_label;
-      
+
       if (custom_tab_label == NULL)
        {
          custom_tab_label = g_get_application_name ();
@@ -480,18 +480,18 @@ get_print_dialog (GtkPrintOperation *op,
        }
 
       label = gtk_label_new (custom_tab_label);
-      
+
       gtk_print_unix_dialog_add_custom_tab (GTK_PRINT_UNIX_DIALOG (pd),
                                            priv->custom_widget, label);
 
       g_signal_connect (pd, "notify::selected-printer", (GCallback) print_setup_changed_cb, op);
       g_signal_connect (pd, "notify::page-setup", (GCallback) print_setup_changed_cb, op);
     }
-  
+
   return pd;
 }
-  
-typedef struct 
+
+typedef struct
 {
   GtkPrintOperation           *op;
   gboolean                     do_print;
@@ -523,7 +523,7 @@ finish_print (PrintResponseData *rdata,
   GtkPrintOperationPrivate *priv = op->priv;
   GtkPrintJob *job;
   double top, bottom, left, right;
-  
+
   if (rdata->do_print)
     {
       gtk_print_operation_set_print_settings (op, settings);
@@ -555,38 +555,38 @@ finish_print (PrintResponseData *rdata,
         {
          GtkPrintOperationUnix *op_unix;
          cairo_t *cr;
-         
+
          op_unix = g_new0 (GtkPrintOperationUnix, 1);
          priv->platform_data = op_unix;
          priv->free_platform_data = (GDestroyNotify) op_unix_free;
          op_unix->parent = rdata->parent;
-         
+
          priv->start_page = unix_start_page;
          priv->end_page = unix_end_page;
          priv->end_run = unix_end_run;
-         
+
          job = gtk_print_job_new (priv->job_name, printer, settings, page_setup);
           op_unix->job = job;
           gtk_print_job_set_track_print_status (job, priv->track_print_status);
-         
+
          op_unix->surface = gtk_print_job_get_surface (job, &priv->error);
-         if (op_unix->surface == NULL) 
+         if (op_unix->surface == NULL)
             {
              rdata->result = GTK_PRINT_OPERATION_RESULT_ERROR;
              rdata->do_print = FALSE;
              goto out;
             }
-         
+
          cr = cairo_create (op_unix->surface);
          gtk_print_context_set_cairo_context (priv->print_context, cr, 72, 72);
          cairo_destroy (cr);
 
           _gtk_print_operation_set_status (op, gtk_print_job_get_status (job), NULL);
-         
+
           op_unix->job_status_changed_tag =
            g_signal_connect (job, "status-changed",
                              G_CALLBACK (job_status_changed_cb), op);
-         
+
           priv->print_pages = gtk_print_job_get_pages (job);
           priv->page_ranges = gtk_print_job_get_page_ranges (job, &priv->num_page_ranges);
           priv->manual_num_copies = gtk_print_job_get_num_copies (job);
@@ -598,16 +598,16 @@ finish_print (PrintResponseData *rdata,
           priv->manual_number_up = gtk_print_job_get_n_up (job);
           priv->manual_number_up_layout = gtk_print_job_get_n_up_layout (job);
         }
-    } 
+    }
  out:
   if (rdata->print_cb)
-    rdata->print_cb (op, rdata->parent, rdata->do_print, rdata->result); 
+    rdata->print_cb (op, rdata->parent, rdata->do_print, rdata->result);
 
   if (rdata->destroy)
     rdata->destroy (rdata);
 }
 
-static void 
+static void
 handle_print_response (GtkWidget *dialog,
                       int        response,
                       gpointer   data)
@@ -627,7 +627,7 @@ handle_print_response (GtkWidget *dialog,
       rdata->do_preview = FALSE;
       if (printer != NULL)
        rdata->do_print = TRUE;
-    } 
+    }
   else if (response == GTK_RESPONSE_APPLY)
     {
       /* print preview */
@@ -650,15 +650,15 @@ handle_print_response (GtkWidget *dialog,
       gtk_print_operation_set_print_settings (rdata->op, settings);
       g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget);
     }
- 
+
   if (rdata->loop)
     g_main_loop_quit (rdata->loop);
-  
+
   finish_print (rdata, printer, page_setup, settings, page_setup_set);
 
   if (settings)
     g_object_unref (settings);
-    
+
   gtk_window_destroy (GTK_WINDOW (pd));
 }
 
@@ -675,7 +675,7 @@ found_printer (GtkPrinter        *printer,
   if (rdata->loop)
     g_main_loop_quit (rdata->loop);
 
-  if (printer != NULL) 
+  if (printer != NULL)
     {
       rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
 
@@ -688,18 +688,18 @@ found_printer (GtkPrinter        *printer,
 
       gtk_print_settings_set_printer (settings,
                                      gtk_printer_get_name (printer));
-      
+
       if (priv->default_page_setup)
        page_setup = gtk_page_setup_copy (priv->default_page_setup);
       else
        page_setup = gtk_page_setup_new ();
   }
-  
+
   finish_print (rdata, printer, page_setup, settings, FALSE);
 
   if (settings)
     g_object_unref (settings);
-  
+
   if (page_setup)
     g_object_unref (page_setup);
 }
@@ -723,13 +723,13 @@ gtk_print_operation_unix_run_dialog_async (GtkPrintOperation          *op,
   rdata->parent = parent;
   rdata->loop = NULL;
   rdata->destroy = print_response_data_free;
-  
+
   if (show_dialog)
     {
       pd = get_print_dialog (op, parent);
       gtk_window_set_modal (GTK_WINDOW (pd), TRUE);
 
-      g_signal_connect (pd, "response", 
+      g_signal_connect (pd, "response",
                        G_CALLBACK (handle_print_response), rdata);
 
       gtk_window_present (GTK_WINDOW (pd));
@@ -739,7 +739,7 @@ gtk_print_operation_unix_run_dialog_async (GtkPrintOperation          *op,
       printer_name = NULL;
       if (op->priv->print_settings)
        printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
-      
+
       find_printer (printer_name, (GFunc) found_printer, rdata);
     }
 }
@@ -751,8 +751,8 @@ write_preview (void                *closure,
 {
   int fd = GPOINTER_TO_INT (closure);
   gssize written;
-  
-  while (length > 0) 
+
+  while (length > 0)
     {
       written = write (fd, data, length);
 
@@ -760,9 +760,9 @@ write_preview (void                *closure,
        {
          if (errno == EAGAIN || errno == EINTR)
            continue;
-         
+
          return CAIRO_STATUS_WRITE_ERROR;
-       }    
+       }
 
       data += written;
       length -= written;
@@ -792,7 +792,7 @@ gtk_print_operation_unix_create_preview_surface (GtkPrintOperation *op,
   double w, h;
   cairo_surface_t *surface;
   static cairo_user_data_key_t key;
-  
+
   filename = g_build_filename (g_get_tmp_dir (), "previewXXXXXX.pdf", NULL);
   fd = g_mkstemp (filename);
 
@@ -803,14 +803,14 @@ gtk_print_operation_unix_create_preview_surface (GtkPrintOperation *op,
     }
 
   *target = filename;
-  
+
   paper_size = gtk_page_setup_get_paper_size (page_setup);
   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
-    
+
   *dpi_x = *dpi_y = 72;
   surface = cairo_pdf_surface_create_for_stream (write_preview, GINT_TO_POINTER (fd), w, h);
- 
+
   cairo_surface_set_user_data (surface, &key, GINT_TO_POINTER (fd), close_preview);
 
   return surface;
@@ -837,7 +837,7 @@ gtk_print_operation_unix_resize_preview_surface (GtkPrintOperation *op,
                                                  cairo_surface_t   *surface)
 {
   double w, h;
-  
+
   w = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
   h = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
   cairo_pdf_surface_set_size (surface, w, h);
@@ -852,7 +852,7 @@ gtk_print_operation_unix_run_dialog (GtkPrintOperation *op,
   GtkWidget *pd;
   PrintResponseData rdata;
   const char *printer_name;
-   
+
   rdata.op = op;
   rdata.do_print = FALSE;
   rdata.do_preview = FALSE;
@@ -867,7 +867,7 @@ gtk_print_operation_unix_run_dialog (GtkPrintOperation *op,
       pd = get_print_dialog (op, parent);
       gtk_window_set_modal (GTK_WINDOW (pd), TRUE);
 
-      g_signal_connect (pd, "response", 
+      g_signal_connect (pd, "response",
                        G_CALLBACK (handle_print_response), &rdata);
 
       gtk_window_present (GTK_WINDOW (pd));
@@ -882,7 +882,7 @@ gtk_print_operation_unix_run_dialog (GtkPrintOperation *op,
       printer_name = NULL;
       if (op->priv->print_settings)
        printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
-      
+
       rdata.loop = g_main_loop_new (NULL, FALSE);
       find_printer (printer_name,
                    (GFunc) found_printer, &rdata);
@@ -893,12 +893,12 @@ gtk_print_operation_unix_run_dialog (GtkPrintOperation *op,
     }
 
   *do_print = rdata.do_print;
-  
+
   return rdata.result;
 }
 
 
-typedef struct 
+typedef struct
 {
   GtkPageSetup         *page_setup;
   GtkPageSetupDoneFunc  done_cb;
@@ -967,13 +967,13 @@ get_page_setup_dialog (GtkWindow        *parent,
  *
  * Runs a page setup dialog, letting the user modify the values from
  * @page_setup. If the user cancels the dialog, the returned `GtkPageSetup`
- * is identical to the passed in @page_setup, otherwise it contains the 
+ * is identical to the passed in @page_setup, otherwise it contains the
  * modifications done in the dialog.
  *
  * Note that this function may use a recursive mainloop to show the page
- * setup dialog. See gtk_print_run_page_setup_dialog_async() if this is 
+ * setup dialog. See gtk_print_run_page_setup_dialog_async() if this is
  * a problem.
- * 
+ *
  * Returns: (transfer full): a new `GtkPageSetup`
  */
 GtkPageSetup *
@@ -982,8 +982,8 @@ gtk_print_run_page_setup_dialog (GtkWindow        *parent,
                                 GtkPrintSettings *settings)
 {
   GtkWidget *dialog;
-  PageSetupResponseData rdata;  
-  
+  PageSetupResponseData rdata;
+
   rdata.page_setup = NULL;
   rdata.done_cb = NULL;
   rdata.data = NULL;
@@ -997,7 +997,7 @@ gtk_print_run_page_setup_dialog (GtkWindow        *parent,
                     &rdata);
 
   gtk_window_present (GTK_WINDOW (dialog));
- 
+
   g_main_loop_run (rdata.loop);
   g_main_loop_unref (rdata.loop);
   rdata.loop = NULL;
@@ -1034,10 +1034,10 @@ gtk_print_run_page_setup_dialog_async (GtkWindow            *parent,
 {
   GtkWidget *dialog;
   PageSetupResponseData *rdata;
-  
+
   dialog = get_page_setup_dialog (parent, page_setup, settings);
   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-  
+
   rdata = g_new (PageSetupResponseData, 1);
   rdata->page_setup = NULL;
   rdata->done_cb = done_cb;
@@ -1051,7 +1051,7 @@ gtk_print_run_page_setup_dialog_async (GtkWindow            *parent,
   gtk_window_present (GTK_WINDOW (dialog));
  }
 
-struct _PrinterFinder 
+struct _PrinterFinder
 {
   gboolean found_printer;
   GFunc func;
@@ -1087,8 +1087,8 @@ find_printer_idle (gpointer data)
 }
 
 static void
-printer_added_cb (GtkPrintBackend *backend, 
-                  GtkPrinter      *printer, 
+printer_added_cb (GtkPrintBackend *backend,
+                  GtkPrinter      *printer,
                  PrinterFinder   *finder)
 {
   if (finder->found_printer)
@@ -1112,26 +1112,28 @@ printer_added_cb (GtkPrintBackend *backend,
        finder->found_printer = TRUE;
     }
   else
-    if (finder->first_printer == NULL)
-      finder->first_printer = g_object_ref (printer);
-  
+    {
+      if (finder->first_printer == NULL)
+        finder->first_printer = g_object_ref (printer);
+    }
+
   if (finder->found_printer)
     g_idle_add (find_printer_idle, finder);
 }
 
 static void
-printer_list_done_cb (GtkPrintBackend *backend, 
+printer_list_done_cb (GtkPrintBackend *backend,
                      PrinterFinder   *finder)
 {
   finder->backends = g_list_remove (finder->backends, backend);
-  
+
   g_signal_handlers_disconnect_by_func (backend, printer_added_cb, finder);
   g_signal_handlers_disconnect_by_func (backend, printer_list_done_cb, finder);
-  
+
   gtk_print_backend_destroy (backend);
   g_object_unref (backend);
 
-  if (finder->backends == NULL && !finder->found_printer)
+  if (finder->backends == NULL)
     g_idle_add (find_printer_idle, finder);
 }
 
@@ -1164,11 +1166,11 @@ find_printer_init (PrinterFinder   *finder,
     }
   else
     {
-      g_signal_connect (backend, "printer-added", 
-                       (GCallback) printer_added_cb, 
+      g_signal_connect (backend, "printer-added",
+                       (GCallback) printer_added_cb,
                        finder);
-      g_signal_connect (backend, "printer-list-done", 
-                       (GCallback) printer_list_done_cb, 
+      g_signal_connect (backend, "printer-list-done",
+                       (GCallback) printer_list_done_cb,
                        finder);
     }
 
@@ -1178,15 +1180,15 @@ static void
 printer_finder_free (PrinterFinder *finder)
 {
   GList *l;
-  
+
   g_free (finder->printer_name);
-  
+
   if (finder->printer)
     g_object_unref (finder->printer);
-  
+
   if (finder->default_printer)
     g_object_unref (finder->default_printer);
-  
+
   if (finder->first_printer)
     g_object_unref (finder->first_printer);
 
@@ -1198,9 +1200,9 @@ printer_finder_free (PrinterFinder *finder)
       gtk_print_backend_destroy (backend);
       g_object_unref (backend);
     }
-  
+
   g_list_free (finder->backends);
-  
+
   g_free (finder);
 }
 
@@ -1228,10 +1230,8 @@ find_printer (const char *printer,
       find_printer_init (finder, GTK_PRINT_BACKEND (node->data));
     }
 
-  if (finder->backends == NULL && !finder->found_printer)
+  if (finder->backends == NULL)
     g_idle_add (find_printer_idle, finder);
-  else
-    printer_finder_free (finder);
 }
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]