Bug 1145916 - [e10s] Defer starting a GTK Print Job during printer enumeration until the next tick. r=karlt
authorMike Conley <mconley@mozilla.com>
Mon, 27 Jul 2015 17:11:46 -0400
changeset 287021 9e625ab16ddc68f249ebd5ea40d124a434b80ed3
parent 287020 1dd68bfb40418dcafe1e626d31c8f29abe9f1f57
child 287022 96006ddf834d6708f933f62723511595b86edbf3
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1145916, 753041
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1145916 - [e10s] Defer starting a GTK Print Job during printer enumeration until the next tick. r=karlt Before, we were calling nsDeviceContextSpecGTK::StartPrintJob within the gtk_enumerate_printers callback function as soon as we found the printer we wanted to print from. This was causing the GTK printing backend to get confused about what the capabilities of the selected printer were when running in the content process, due to https://bugzilla.gnome.org/show_bug.cgi?id=753041. This moves the call to StartPrintJob to the next tick of the event loop.
widget/gtk/nsDeviceContextSpecG.cpp
widget/gtk/nsDeviceContextSpecG.h
--- a/widget/gtk/nsDeviceContextSpecG.cpp
+++ b/widget/gtk/nsDeviceContextSpecG.cpp
@@ -269,38 +269,45 @@ gboolean nsDeviceContextSpecGTK::Printer
   // Find the printer whose name matches the one inside the settings.
   nsXPIDLString printerName;
   nsresult rv =
     spec->mPrintSettings->GetPrinterName(getter_Copies(printerName));
   if (NS_SUCCEEDED(rv) && printerName) {
     NS_ConvertUTF16toUTF8 requestedName(printerName);
     const char* currentName = gtk_printer_get_name(aPrinter);
     if (requestedName.Equals(currentName)) {
-      nsDeviceContextSpecGTK::StartPrintJob(spec, aPrinter);
+      spec->mPrintSettings->SetGtkPrinter(aPrinter);
+
+      // Bug 1145916 - attempting to kick off a print job for this printer
+      // during this tick of the event loop will result in the printer backend
+      // misunderstanding what the capabilities of the printer are due to a
+      // GTK bug (https://bugzilla.gnome.org/show_bug.cgi?id=753041). We
+      // sidestep this by deferring the print to the next tick.
+      nsCOMPtr<nsIRunnable> event =
+        NS_NewRunnableMethod(spec, &nsDeviceContextSpecGTK::StartPrintJob);
+      NS_DispatchToCurrentThread(event);
       return TRUE;
     }
   }
 
   // We haven't found it yet - keep searching...
   return FALSE;
 }
 
-/* static */
-void nsDeviceContextSpecGTK::StartPrintJob(nsDeviceContextSpecGTK* spec,
-                                           GtkPrinter* printer) {
-  GtkPrintJob* job = gtk_print_job_new(spec->mTitle.get(),
-                                       printer,
-                                       spec->mGtkPrintSettings,
-                                       spec->mGtkPageSetup);
+void nsDeviceContextSpecGTK::StartPrintJob() {
+  GtkPrintJob* job = gtk_print_job_new(mTitle.get(),
+                                       mPrintSettings->GetGtkPrinter(),
+                                       mGtkPrintSettings,
+                                       mGtkPageSetup);
 
-  if (!gtk_print_job_set_source_file(job, spec->mSpoolName.get(), nullptr))
+  if (!gtk_print_job_set_source_file(job, mSpoolName.get(), nullptr))
     return;
 
-  NS_ADDREF(spec->mSpoolFile.get());
-  gtk_print_job_send(job, print_callback, spec->mSpoolFile, ns_release_macro);
+  NS_ADDREF(mSpoolFile.get());
+  gtk_print_job_send(job, print_callback, mSpoolFile, ns_release_macro);
 }
 
 void
 nsDeviceContextSpecGTK::EnumeratePrinters()
 {
   gtk_enumerate_printers(&nsDeviceContextSpecGTK::PrinterEnumerator, this,
                          nullptr, TRUE);
 }
@@ -323,17 +330,17 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::En
     // In the multi-process case, we proxy the print settings dialog over to
     // the parent process, and only get the name of the printer back on the
     // content process side. In that case, we need to enumerate the printers
     // on the content side, and find a printer with a matching name.
 
     GtkPrinter* printer = mPrintSettings->GetGtkPrinter();
     if (printer) {
       // We have a printer, so we can print right away.
-      nsDeviceContextSpecGTK::StartPrintJob(this, printer);
+      StartPrintJob();
     } else {
       // We don't have a printer. We have to enumerate the printers and find
       // one with a matching name.
       nsCOMPtr<nsIRunnable> event =
         NS_NewRunnableMethod(this, &nsDeviceContextSpecGTK::EnumeratePrinters);
       NS_DispatchToCurrentThread(event);
     }
   } else {
--- a/widget/gtk/nsDeviceContextSpecG.h
+++ b/widget/gtk/nsDeviceContextSpecG.h
@@ -51,19 +51,18 @@ protected:
   GtkPageSetup*     mGtkPageSetup;
 
   nsCString         mSpoolName;
   nsCOMPtr<nsIFile> mSpoolFile;
   nsCString         mTitle;
 
 private:
   void EnumeratePrinters();
+  void StartPrintJob();
   static gboolean PrinterEnumerator(GtkPrinter *aPrinter, gpointer aData);
-  static void StartPrintJob(nsDeviceContextSpecGTK *spec,
-                            GtkPrinter *printer);
 };
 
 //-------------------------------------------------------------------------
 // Printer Enumerator
 //-------------------------------------------------------------------------
 class nsPrinterEnumeratorGTK final : public nsIPrinterEnumerator
 {
   ~nsPrinterEnumeratorGTK() {}