Bug 1524687: Part 9 - Convert gtk widget module to static registration. r=erahm
authorKris Maglione <maglione.k@gmail.com>
Thu, 24 Jan 2019 17:27:24 -0800
changeset 517333 1c6224158f64ae4291133faa56f538413092ff98
parent 517332 b663c11ca61f033bd52e1fc8488693a2da6feeab
child 517334 5a18627596250d711ad705f67b14b21a97b2542e
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1524687
milestone67.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 1524687: Part 9 - Convert gtk widget module to static registration. r=erahm
dom/base/test/test_bug715041.xul
dom/base/test/test_bug715041_removal.xul
testing/specialpowers/content/MockColorPicker.jsm
testing/specialpowers/content/MockFilePicker.jsm
toolkit/components/places/tests/gtest/places_test_harness_tail.h
widget/gtk/components.conf
widget/gtk/moz.build
widget/gtk/nsWidgetFactory.cpp
widget/gtk/nsWidgetFactory.h
widget/moz.build
widget/nsAppShellSingleton.h
widget/nsIIdleService.idl
widget/nsIdleService.cpp
widget/nsIdleService.h
--- a/dom/base/test/test_bug715041.xul
+++ b/dom/base/test/test_bug715041.xul
@@ -715,17 +715,17 @@ target="_blank">Mozilla Bug 715041</a>
     try {
       componentMgr.unregisterFactory(idleServiceCID, idleServiceObj);
     }
     catch(err) {
       dump("test_bug715041.xul: ShiftLocalTimerBackCleanUp() Failed to unregister factory, mock idle service!\n");
     }
 
     try {
-      componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, oldIdleServiceFactoryObj);
+      componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, null);
     }
     catch(err) {
       dump("test_bug715041.xul: ShiftLocalTimerBackCleanUp() Failed to register factory, original idle service!\n");
     }
 
     SimpleTest.finish();
   }
 
@@ -780,23 +780,16 @@ target="_blank">Mozilla Bug 715041</a>
   try {
     var oldIdleServiceCID = componentMgr.contractIDToCID(idleServiceContractID);
   }
   catch(err) {
     dump("test_bug715041.xul: Failed to convert ID to CID for old idle service.\n");
   }
 
   try {
-    componentMgr.unregisterFactory(oldIdleServiceCID, oldIdleServiceFactoryObj);
-  }
-  catch(err) {
-    dump("test_bug715041.xul: Failed to unregister old idle service factory object!\n");
-  }
-
-  try {
     componentMgr.registerFactory(idleServiceCID, "Test Simple Idle/Back Notifications", idleServiceContractID, idleServiceObj);
   }
   catch(err) {
     dump("test_bug715041.xul: Failed to register mock idle service.\n");
   }
 
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestLongerTimeout(10);
--- a/dom/base/test/test_bug715041_removal.xul
+++ b/dom/base/test/test_bug715041_removal.xul
@@ -760,17 +760,17 @@ target="_blank">Mozilla Bug 715041</a>
     try {
       componentMgr.unregisterFactory(idleServiceCID, idleServiceObj);
     }
     catch(err) {
       dump("test_bug715041_removal.xul: RemoveLastAddLastCleanUp() Failed to unregister factory, mock idle service!\n");
     }
 
     try {
-      componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, oldIdleServiceFactoryObj);
+      componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, null);
     }
     catch(err) {
       dump("test_bug715041_removal.xul: RemoveLastAddLastCleanUp() Failed to register factory, original idle service!\n");
     }
 
     dump("JS RemoveLastAddLastCleanUp() DONE\n");
     dump("Finishing testing idle API.\n");
     SimpleTest.finish();
@@ -808,23 +808,16 @@ target="_blank">Mozilla Bug 715041</a>
   try {
     var oldIdleServiceCID = componentMgr.contractIDToCID(idleServiceContractID);
   }
   catch(err) {
     dump("test_bug715041._removalxul: Failed to convert ID to CID for old idle service.\n");
   }
 
   try {
-    componentMgr.unregisterFactory(oldIdleServiceCID, oldIdleServiceFactoryObj);
-  }
-  catch(err) {
-    dump("test_bug715041_removal.xul: Failed to unregister old idle service factory object!\n");
-  }
-
-  try {
     componentMgr.registerFactory(idleServiceCID, "Test Simple Idle/Back Notifications", idleServiceContractID, idleServiceObj);
   }
   catch(err) {
     dump("test_bug715041_removal.xul: Failed to register mock idle service.\n");
   }
 
   //test case enabled
   var RemoveLocalIdleObserverWhileIdleEnabled = true;
--- a/testing/specialpowers/content/MockColorPicker.jsm
+++ b/testing/specialpowers/content/MockColorPicker.jsm
@@ -8,17 +8,17 @@ const Cm = Components.manager;
 
 const CONTRACT_ID = "@mozilla.org/colorpicker;1";
 
 // Allow stuff from this scope to be accessed from non-privileged scopes. This
 // would crash if used outside of automation.
 Cu.forcePermissiveCOWs();
 
 var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID = "", oldFactory = null;
+var oldClassID = "";
 var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
 var newFactory = function(window) {
   return {
     createInstance(aOuter, aIID) {
       if (aOuter)
         throw Cr.NS_ERROR_NO_AGGREGATION;
       return new MockColorPickerInstance(window).QueryInterface(aIID);
     },
@@ -31,26 +31,21 @@ var newFactory = function(window) {
 
 var MockColorPicker = {
   init(window) {
     this.reset();
     this.factory = newFactory(window);
     if (!registrar.isCIDRegistered(newClassID)) {
       try {
         oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-        oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
       } catch (ex) {
         oldClassID = "";
-        oldFactory = null;
         dump("TEST-INFO | can't get colorpicker registered component, " +
              "assuming there is none");
       }
-      if (oldClassID != "" && oldFactory != null) {
-        registrar.unregisterFactory(oldClassID, oldFactory);
-      }
       registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
     }
   },
 
   reset() {
     this.returnColor = "";
     this.showCallback = null;
     this.shown = false;
@@ -58,18 +53,18 @@ var MockColorPicker = {
   },
 
   cleanup() {
     var previousFactory = this.factory;
     this.reset();
     this.factory = null;
 
     registrar.unregisterFactory(newClassID, previousFactory);
-    if (oldClassID != "" && oldFactory != null) {
-      registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
+    if (oldClassID != "") {
+      registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
     }
   },
 };
 
 function MockColorPickerInstance(window) {
   this.window = window;
 }
 MockColorPickerInstance.prototype = {
--- a/testing/specialpowers/content/MockFilePicker.jsm
+++ b/testing/specialpowers/content/MockFilePicker.jsm
@@ -12,17 +12,17 @@ ChromeUtils.defineModuleGetter(this, "Fi
                                "resource://gre/modules/FileUtils.jsm");
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 // Allow stuff from this scope to be accessed from non-privileged scopes. This
 // would crash if used outside of automation.
 Cu.forcePermissiveCOWs();
 
 var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID, oldFactory;
+var oldClassID;
 var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
 var newFactory = function(window) {
   return {
     createInstance(aOuter, aIID) {
       if (aOuter)
         throw Cr.NS_ERROR_NO_AGGREGATION;
       return new MockFilePickerInstance(window).QueryInterface(aIID);
     },
@@ -54,18 +54,16 @@ var MockFilePicker = {
 
   init(window) {
     this.window = window;
 
     this.reset();
     this.factory = newFactory(window);
     if (!registrar.isCIDRegistered(newClassID)) {
       oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-      oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
-      registrar.unregisterFactory(oldClassID, oldFactory);
       registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
     }
   },
 
   reset() {
     this.appendFilterCallback = null;
     this.appendFiltersCallback = null;
     this.displayDirectory = null;
@@ -79,19 +77,19 @@ var MockFilePicker = {
     this.shown = false;
     this.showing = false;
   },
 
   cleanup() {
     var previousFactory = this.factory;
     this.reset();
     this.factory = null;
-    if (oldFactory) {
+    if (oldClassID) {
       registrar.unregisterFactory(newClassID, previousFactory);
-      registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
+      registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
     }
   },
 
   internalFileData(obj) {
     return {
       nsIFile: "nsIFile" in obj ? obj.nsIFile : null,
       domFile: "domFile" in obj ? obj.domFile : null,
       domDirectory: "domDirectory" in obj ? obj.domDirectory : null,
--- a/toolkit/components/places/tests/gtest/places_test_harness_tail.h
+++ b/toolkit/components/places/tests/gtest/places_test_harness_tail.h
@@ -2,16 +2,17 @@
  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsWidgetsCID.h"
 #include "nsIComponentRegistrar.h"
 #include "nsICrashReporter.h"
+#include "nsIIdleService.h"
 
 #ifndef TEST_NAME
 #  error "Must #define TEST_NAME before including places_test_harness_tail.h"
 #endif
 
 int gTestsIndex = 0;
 
 #define TEST_INFO_STR "TEST-INFO | "
@@ -48,25 +49,19 @@ void do_test_pending() {
 void do_test_finished() {
   NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
   NS_ASSERTION(gPendingTests > 0, "Invalid pending test count!");
   gPendingTests--;
 }
 
 void disable_idle_service() {
   (void)fprintf(stderr, TEST_INFO_STR "Disabling Idle Service.\n");
-  static NS_DEFINE_IID(kIdleCID, NS_IDLE_SERVICE_CID);
-  nsresult rv;
-  nsCOMPtr<nsIFactory> idleFactory = do_GetClassObject(kIdleCID, &rv);
-  do_check_success(rv);
-  nsCOMPtr<nsIComponentRegistrar> registrar;
-  rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
-  do_check_success(rv);
-  rv = registrar->UnregisterFactory(kIdleCID, idleFactory);
-  do_check_success(rv);
+
+  nsCOMPtr<nsIIdleService> idle = do_GetService("@mozilla.org/widget/idleservice;1");
+  idle->SetDisabled(true);
 }
 
 TEST(IHistory, Test) {
   RefPtr<WaitForConnectionClosed> spinClose = new WaitForConnectionClosed();
 
   // Tinderboxes are constantly on idle.  Since idle tasks can interact with
   // tests, causing random failures, disable the idle service.
   disable_idle_service();
new file mode 100644
--- /dev/null
+++ b/widget/gtk/components.conf
@@ -0,0 +1,166 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Headers = [
+    '/widget/gtk/nsWidgetFactory.h',
+]
+
+InitFunc = 'nsWidgetGtk2ModuleCtor'
+UnloadFunc = 'nsWidgetGtk2ModuleDtor'
+
+Classes = [
+    {
+        'cid': '{2d96b3df-c051-11d1-a827-0040959a28c9}',
+        'contract_ids': ['@mozilla.org/widget/appshell/gtk;1'],
+        'legacy_constructor': 'nsAppShellConstructor',
+        'headers': ['/widget/gtk/nsWidgetFactory.h'],
+        'processes': ProcessSelector.ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS,
+    },
+    {
+        'cid': '{c401eb80-f9ea-11d3-bb6f-e732b73ebe7c}',
+        'contract_ids': ['@mozilla.org/gfx/screenmanager;1'],
+        'singleton': True,
+        'type': 'mozilla::widget::ScreenManager',
+        'headers': ['mozilla/StaticPtr.h', 'mozilla/widget/ScreenManager.h'],
+        'constructor': 'mozilla::widget::ScreenManager::GetAddRefedSingleton',
+        'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+    },
+    {
+        'cid': '{a9339876-0027-430f-b953-84c9c11c2da3}',
+        'contract_ids': ['@mozilla.org/widget/taskbarprogress/gtk;1'],
+        'type': 'TaskbarProgress',
+        'headers': ['/widget/gtk/TaskbarProgress.h'],
+    },
+    {
+        'cid': '{0f872c8c-3ee6-46bd-92a2-69652c6b474e}',
+        'contract_ids': ['@mozilla.org/colorpicker;1'],
+        'type': 'nsColorPicker',
+        'headers': ['/widget/gtk/nsColorPicker.h'],
+        'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+    },
+    {
+        'cid': '{bd57cee8-1dd1-11b2-9fe7-95cf4709aea3}',
+        'contract_ids': ['@mozilla.org/filepicker;1'],
+        'type': 'nsFilePicker',
+        'headers': ['/widget/gtk/nsFilePicker.h'],
+        'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+    },
+    {
+        'cid': '{948a0023-e3a7-11d2-96cf-0060b0fb9956}',
+        'contract_ids': ['@mozilla.org/widget/htmlformatconverter;1'],
+        'type': 'nsHTMLFormatConverter',
+        'headers': ['/widget/nsHTMLFormatConverter.h'],
+    },
+    {
+        'cid': '{b148eed2-236d-11d3-b35c-00a0cc3c1cde}',
+        'contract_ids': ['@mozilla.org/sound;1'],
+        'singleton': True,
+        'type': 'nsISound',
+        'constructor': 'nsSound::GetInstance',
+        'headers': ['/widget/gtk/nsSound.h'],
+        'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+    },
+    {
+        'cid': '{fc2389b8-c650-4093-9e42-b05e5f0685b7}',
+        'contract_ids': ['@mozilla.org/widget/image-to-gdk-pixbuf;1'],
+        'type': 'nsImageToPixbuf',
+        'headers': ['/widget/gtk/nsImageToPixbuf.h'],
+    },
+    {
+        'cid': '{8b5314bc-db01-11d2-96ce-0060b0fb9956}',
+        'contract_ids': ['@mozilla.org/widget/transferable;1'],
+        'type': 'nsTransferable',
+        'headers': ['/widget/nsTransferable.h'],
+    },
+]
+
+if defined('MOZ_X11'):
+    Classes += [
+        {
+            'cid': '{8b5314ba-db01-11d2-96ce-0060b0fb9956}',
+            'contract_ids': ['@mozilla.org/widget/clipboard;1'],
+            'type': 'nsIClipboard',
+            'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+        },
+        {
+            'cid': '{77221d5a-1dd2-11b2-8c69-c710f15d2ed5}',
+            'contract_ids': ['@mozilla.org/widget/clipboardhelper;1'],
+            'type': 'nsClipboardHelper',
+            'headers': ['/widget/nsClipboardHelper.h'],
+        },
+        {
+            'cid': '{8b5314bb-db01-11d2-96ce-0060b0fb9956}',
+            'contract_ids': ['@mozilla.org/widget/dragservice;1'],
+            'singleton': True,
+            'type': 'nsDragService',
+            'headers': ['/widget/gtk/nsDragService.h'],
+            'constructor': 'nsDragService::GetInstance',
+            'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+        },
+        {
+            'cid': '{d755a760-9f27-11df-0800-200c9a664242}',
+            'contract_ids': ['@mozilla.org/gfx/info;1'],
+            'type': 'mozilla::widget::GfxInfo',
+            'headers': ['/widget/GfxInfoX11.h'],
+            'init_method': 'Init',
+        },
+        {
+            'cid': '{6987230e-0098-4e78-bc5f-1493ee7519fa}',
+            'contract_ids': ['@mozilla.org/widget/idleservice;1'],
+            'singleton': True,
+            'type': 'nsIdleService',
+            'headers': ['/widget/gtk/nsIdleServiceGTK.h'],
+            'constructor': 'nsIdleServiceGTK::GetInstance',
+        },
+    ]
+
+if buildconfig.substs['MOZ_WIDGET_TOOLKIT'] == 'gtk':
+    Classes += [
+        {
+            'cid': '{e221df9b-3d66-4045-9a66-5720949f8d10}',
+            'contract_ids': ['@mozilla.org/applicationchooser;1'],
+            'type': 'nsApplicationChooser',
+            'headers': ['/widget/gtk/nsApplicationChooser.h'],
+            'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+        },
+    ]
+
+if defined('NS_PRINTING'):
+    Classes += [
+        {
+            'cid': '{d3f69889-e13a-4321-980c-a39332e21f34}',
+            'contract_ids': ['@mozilla.org/gfx/devicecontextspec;1'],
+            'type': 'nsDeviceContextSpecGTK',
+            'headers': ['/widget/gtk/nsDeviceContextSpecG.h'],
+        },
+        {
+            'cid': '{06beec76-a183-4d9f-85dd-085f26da565a}',
+            'contract_ids': ['@mozilla.org/widget/printdialog-service;1'],
+            'type': 'nsPrintDialogServiceGTK',
+            'headers': ['/widget/gtk/nsPrintDialogGTK.h'],
+            'init_method': 'Init',
+        },
+        {
+            'cid': '{2f977d53-5485-11d4-87e2-0010a4e75ef2}',
+            'contract_ids': ['@mozilla.org/gfx/printsession;1'],
+            'type': 'nsPrintSession',
+            'headers': ['/widget/nsPrintSession.h'],
+            'init_method': 'Init',
+        },
+        {
+            'cid': '{841387c8-72e6-484b-9296-bf6eea80d58a}',
+            'contract_ids': ['@mozilla.org/gfx/printsettings-service;1'],
+            'type': 'nsPrintSettingsServiceGTK',
+            'headers': ['/widget/gtk/nsPrintSettingsServiceGTK.h'],
+            'init_method': 'Init',
+        },
+        {
+            'cid': '{a6cf9129-15b3-11d2-932e-00805f8add32}',
+            'contract_ids': ['@mozilla.org/gfx/printerenumerator;1'],
+            'type': 'nsPrinterEnumeratorGTK',
+            'headers': ['/widget/gtk/nsDeviceContextSpecG.h'],
+        },
+    ]
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -107,16 +107,20 @@ if CONFIG['ACCESSIBILITY']:
     ]
 
 UNIFIED_SOURCES += [
     'gtk3drawing.cpp',
     'nsApplicationChooser.cpp',
     'WidgetStyleCache.cpp',
 ]
 
+XPCOM_MANIFESTS += [
+    'components.conf',
+]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/layout/base',
     '/layout/generic',
     '/layout/xul',
--- a/widget/gtk/nsWidgetFactory.cpp
+++ b/widget/gtk/nsWidgetFactory.cpp
@@ -1,296 +1,74 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=4:tabstop=4:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/ModuleUtils.h"
+#include "nsWidgetFactory.h"
+
+#include "mozilla/Components.h"
 #include "mozilla/WidgetUtils.h"
 #include "NativeKeyBindings.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShell.h"
 #include "nsAppShellSingleton.h"
 #include "nsBaseWidget.h"
 #include "nsGtkKeyUtils.h"
 #include "nsLookAndFeel.h"
 #include "nsWindow.h"
-#include "nsTransferable.h"
 #include "nsHTMLFormatConverter.h"
 #include "HeadlessClipboard.h"
 #include "IMContextWrapper.h"
 #ifdef MOZ_X11
-#  include "nsClipboardHelper.h"
 #  include "nsClipboard.h"
-#  include "nsDragService.h"
-#endif
-#ifdef MOZ_WIDGET_GTK
-#  include "nsApplicationChooser.h"
 #endif
 #include "TaskbarProgress.h"
-#include "nsColorPicker.h"
 #include "nsFilePicker.h"
 #include "nsSound.h"
 #include "nsGTKToolkit.h"
 #include "WakeLockListener.h"
 
-#ifdef NS_PRINTING
-#  include "nsPrintSettingsServiceGTK.h"
-#  include "nsPrintSession.h"
-#  include "nsDeviceContextSpecG.h"
-#endif
-
-#include "nsImageToPixbuf.h"
-#include "nsPrintDialogGTK.h"
-
-#if defined(MOZ_X11)
-#  include "nsIdleServiceGTK.h"
-#  include "GfxInfoX11.h"
-#endif
-
-#include "nsIComponentRegistrar.h"
-#include "nsComponentManagerUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/widget/ScreenManager.h"
 #include <gtk/gtk.h>
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 #ifdef MOZ_X11
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceGTK,
-                                         nsIdleServiceGTK::GetInstance)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDragService,
-                                         nsDragService::GetInstance)
-#endif
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISound, nsSound::GetInstance)
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager,
-                                         ScreenManager::GetAddRefedSingleton)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf)
-NS_GENERIC_FACTORY_CONSTRUCTOR(TaskbarProgress)
-
-#if defined(MOZ_X11)
-namespace mozilla {
-namespace widget {
-// This constructor should really be shared with all platforms.
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
-}  // namespace widget
-}  // namespace mozilla
-#endif
-
-#ifdef NS_PRINTING
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecGTK)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSettingsServiceGTK, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorGTK)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceGTK, Init)
-#endif
-
-static nsresult nsFilePickerConstructor(nsISupports *aOuter, REFNSIID aIID,
-                                        void **aResult) {
-  *aResult = nullptr;
-  if (aOuter != nullptr) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-
-  nsCOMPtr<nsIFilePicker> picker = new nsFilePicker;
-
-  return picker->QueryInterface(aIID, aResult);
-}
-
-#ifdef MOZ_WIDGET_GTK
-static nsresult nsApplicationChooserConstructor(nsISupports *aOuter,
-                                                REFNSIID aIID, void **aResult) {
-  *aResult = nullptr;
-  if (aOuter != nullptr) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-  nsCOMPtr<nsIApplicationChooser> chooser = new nsApplicationChooser;
-
-  if (!chooser) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  return chooser->QueryInterface(aIID, aResult);
-}
-#endif
-
-static nsresult nsColorPickerConstructor(nsISupports *aOuter, REFNSIID aIID,
-                                         void **aResult) {
-  *aResult = nullptr;
-  if (aOuter != nullptr) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-
-  nsCOMPtr<nsIColorPicker> picker = new nsColorPicker;
-
-  if (!picker) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  return picker->QueryInterface(aIID, aResult);
-}
-
-static nsresult nsClipboardConstructor(nsISupports *aOuter, REFNSIID aIID,
-                                       void **aResult) {
-  *aResult = nullptr;
-  if (aOuter != nullptr) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-
+NS_IMPL_COMPONENT_FACTORY(nsIClipboard) {
   nsCOMPtr<nsIClipboard> inst;
   if (gfxPlatform::IsHeadless()) {
     inst = new HeadlessClipboard();
   } else {
-    RefPtr<nsClipboard> clipboard = new nsClipboard();
-    nsresult rv = clipboard->Init();
-    NS_ENSURE_SUCCESS(rv, rv);
-    inst = clipboard;
+    auto clipboard = MakeRefPtr<nsClipboard>();
+    if (NS_FAILED(clipboard->Init())) {
+      return nullptr;
+    }
+    inst = clipboard.forget();
   }
 
-  return inst->QueryInterface(aIID, aResult);
+  return inst.forget().downcast<nsISupports>();
 }
-
-NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
-NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
-NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
-#ifdef MOZ_WIDGET_GTK
-NS_DEFINE_NAMED_CID(NS_APPLICATIONCHOOSER_CID);
-#endif
-NS_DEFINE_NAMED_CID(NS_GTK_TASKBARPROGRESS_CID);
-NS_DEFINE_NAMED_CID(NS_SOUND_CID);
-NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
-#ifdef MOZ_X11
-NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
-NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID);
-NS_DEFINE_NAMED_CID(NS_DRAGSERVICE_CID);
-#endif
-NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
-NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
-#ifdef NS_PRINTING
-NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_PRINTER_ENUMERATOR_CID);
-NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID);
-NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
-NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVICE_CID);
-#endif
-NS_DEFINE_NAMED_CID(NS_IMAGE_TO_PIXBUF_CID);
-#if defined(MOZ_X11)
-NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
 #endif
 
-static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
-    {&kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor,
-     Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS},
-    {&kNS_COLORPICKER_CID, false, nullptr, nsColorPickerConstructor,
-     Module::MAIN_PROCESS_ONLY},
-    {&kNS_FILEPICKER_CID, false, nullptr, nsFilePickerConstructor,
-     Module::MAIN_PROCESS_ONLY},
-#ifdef MOZ_WIDGET_GTK
-    {&kNS_APPLICATIONCHOOSER_CID, false, nullptr,
-     nsApplicationChooserConstructor, Module::MAIN_PROCESS_ONLY},
-#endif
-    {&kNS_GTK_TASKBARPROGRESS_CID, false, nullptr, TaskbarProgressConstructor},
-    {&kNS_SOUND_CID, false, nullptr, nsISoundConstructor,
-     Module::MAIN_PROCESS_ONLY},
-    {&kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor},
-#ifdef MOZ_X11
-    {&kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor,
-     Module::MAIN_PROCESS_ONLY},
-    {&kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor},
-    {&kNS_DRAGSERVICE_CID, false, nullptr, nsDragServiceConstructor,
-     Module::MAIN_PROCESS_ONLY},
-#endif
-    {&kNS_HTMLFORMATCONVERTER_CID, false, nullptr,
-     nsHTMLFormatConverterConstructor},
-    {&kNS_SCREENMANAGER_CID, false, nullptr, ScreenManagerConstructor,
-     Module::MAIN_PROCESS_ONLY},
-#ifdef NS_PRINTING
-    {&kNS_PRINTSETTINGSSERVICE_CID, false, nullptr,
-     nsPrintSettingsServiceGTKConstructor},
-    {&kNS_PRINTER_ENUMERATOR_CID, false, nullptr,
-     nsPrinterEnumeratorGTKConstructor},
-    {&kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor},
-    {&kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr,
-     nsDeviceContextSpecGTKConstructor},
-    {&kNS_PRINTDIALOGSERVICE_CID, false, nullptr,
-     nsPrintDialogServiceGTKConstructor},
-#endif
-    {&kNS_IMAGE_TO_PIXBUF_CID, false, nullptr, nsImageToPixbufConstructor},
-#if defined(MOZ_X11)
-    {&kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceGTKConstructor},
-    {&kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor},
-#endif
-    {nullptr}};
+nsresult nsWidgetGtk2ModuleCtor() { return nsAppShellInit(); }
 
-static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
-    {"@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID,
-     Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS},
-    {"@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID,
-     Module::MAIN_PROCESS_ONLY},
-    {"@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID,
-     Module::MAIN_PROCESS_ONLY},
-#ifdef MOZ_WIDGET_GTK
-    {"@mozilla.org/applicationchooser;1", &kNS_APPLICATIONCHOOSER_CID,
-     Module::MAIN_PROCESS_ONLY},
-#endif
-    {"@mozilla.org/widget/taskbarprogress/gtk;1", &kNS_GTK_TASKBARPROGRESS_CID},
-    {"@mozilla.org/sound;1", &kNS_SOUND_CID, Module::MAIN_PROCESS_ONLY},
-    {"@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID},
-#ifdef MOZ_X11
-    {"@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID,
-     Module::MAIN_PROCESS_ONLY},
-    {"@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID},
-    {"@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID,
-     Module::MAIN_PROCESS_ONLY},
-#endif
-    {"@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID},
-    {"@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
-     Module::MAIN_PROCESS_ONLY},
-#ifdef NS_PRINTING
-    {"@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID},
-    {"@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID},
-    {"@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID},
-    {"@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID},
-    {NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID},
-#endif
-    {"@mozilla.org/widget/image-to-gdk-pixbuf;1", &kNS_IMAGE_TO_PIXBUF_CID},
-#if defined(MOZ_X11)
-    {"@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID},
-    {"@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID},
-#endif
-    {nullptr}};
-
-static void nsWidgetGtk2ModuleDtor() {
+void nsWidgetGtk2ModuleDtor() {
   // Shutdown all XP level widget classes.
   WidgetUtils::Shutdown();
 
   NativeKeyBindings::Shutdown();
   nsLookAndFeel::Shutdown();
   nsFilePicker::Shutdown();
   nsSound::Shutdown();
   nsWindow::ReleaseGlobals();
   IMContextWrapper::Shutdown();
   KeymapWrapper::Shutdown();
   nsGTKToolkit::Shutdown();
   nsAppShellShutdown();
 #ifdef MOZ_ENABLE_DBUS
   WakeLockListener::Shutdown();
 #endif
 }
-
-static const mozilla::Module kWidgetModule = {
-    mozilla::Module::kVersion,
-    kWidgetCIDs,
-    kWidgetContracts,
-    nullptr,
-    nullptr,
-    nsAppShellInit,
-    nsWidgetGtk2ModuleDtor,
-    Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS};
-
-NSMODULE_DEFN(nsWidgetGtk2Module) = &kWidgetModule;
new file mode 100644
--- /dev/null
+++ b/widget/gtk/nsWidgetFactory.h
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef widget_gtk_nsWidgetFactory_h
+#define widget_gtk_nsWidgetFactory_h
+
+#include "nscore.h"
+#include "nsID.h"
+
+class nsISupports;
+
+nsresult nsAppShellConstructor(nsISupports *outer, const nsIID &iid,
+                               void **result);
+
+nsresult nsWidgetGtk2ModuleCtor();
+void nsWidgetGtk2ModuleDtor();
+
+#endif  // defined widget_gtk_nsWidgetFactory_h
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -122,19 +122,22 @@ XPIDL_SOURCES += [
 
 XPIDL_MODULE = 'widget'
 
 EXPORTS += [
     'GfxDriverInfo.h',
     'GfxInfoBase.h',
     'GfxInfoCollector.h',
     'InputData.h',
+    'nsBaseDragService.h',
+    'nsBaseFilePicker.h',
     'nsBaseScreen.h',
     'nsBaseWidget.h',
     'nsIDeviceContextSpec.h',
+    'nsIdleService.h',
     'nsIKeyEventInPluginCallback.h',
     'nsIPluginWidget.h',
     'nsIPrintDialogService.h',
     'nsIRollupListener.h',
     'nsIWidget.h',
     'nsIWidgetListener.h',
     'nsWidgetInitData.h',
     'nsWidgetsCID.h',
--- a/widget/nsAppShellSingleton.h
+++ b/widget/nsAppShellSingleton.h
@@ -45,17 +45,17 @@ static nsresult nsAppShellInit() {
     return rv;
   }
 
   return NS_OK;
 }
 
 static void nsAppShellShutdown() { NS_RELEASE(sAppShell); }
 
-static nsresult nsAppShellConstructor(nsISupports *outer, const nsIID &iid,
-                                      void **result) {
+nsresult nsAppShellConstructor(nsISupports *outer, const nsIID &iid,
+                               void **result) {
   NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
   NS_ENSURE_TRUE(sAppShell, NS_ERROR_NOT_INITIALIZED);
 
   return sAppShell->QueryInterface(iid, result);
 }
 
 #endif  // nsAppShellSingleton_h__
--- a/widget/nsIIdleService.idl
+++ b/widget/nsIIdleService.idl
@@ -59,16 +59,24 @@ interface nsIIdleService : nsISupports
      * @param observer the observer that needs to be removed.
      * @param time the amount of time they were listening for.
      * @note
      * Removing an observer will remove it once, for the idle time you specify. 
      * If you have added an observer multiple times, you will need to remove it
      * just as many times.
      */
     void removeIdleObserver(in nsIObserver observer, in unsigned long time);
+
+    /**
+     * If true, the idle service is temporarily disabled, and all idle events
+     * will be ignored.
+     *
+     * This should only be used in automation.
+     */
+    attribute boolean disabled;
 };
 
 %{C++  
     /**
      * Observer topic notification for idle window: OBSERVER_TOPIC_IDLE.
      * Observer topic notification for active window: OBSERVER_TOPIC_ACTIVE.
      */
     
--- a/widget/nsIdleService.cpp
+++ b/widget/nsIdleService.cpp
@@ -619,16 +619,26 @@ bool nsIdleService::PollIdleTime(uint32_
   return false;
 }
 
 bool nsIdleService::UsePollMode() {
   uint32_t dummy;
   return PollIdleTime(&dummy);
 }
 
+nsresult nsIdleService::GetDisabled(bool* aResult) {
+  *aResult = mDisabled;
+  return NS_OK;
+}
+
+nsresult nsIdleService::SetDisabled(bool aDisabled) {
+  mDisabled = aDisabled;
+  return NS_OK;
+}
+
 void nsIdleService::StaticIdleTimerCallback(nsITimer* aTimer, void* aClosure) {
   static_cast<nsIdleService*>(aClosure)->IdleTimerCallback();
 }
 
 void nsIdleService::IdleTimerCallback(void) {
   // Remember that we no longer have a timer running.
   mCurrentlySetToTimeoutAt = TimeStamp();
 
@@ -673,16 +683,24 @@ void nsIdleService::IdleTimerCallback(vo
 
   // Restart timer and bail if no-one are expected to be in idle
   if (mDeltaToNextIdleSwitchInS > currentIdleTimeInS) {
     // If we didn't expect anyone to be idle, then just re-start the timer.
     ReconfigureTimer();
     return;
   }
 
+  if (mDisabled) {
+    MOZ_LOG(sLog, LogLevel::Info,
+            ("idleService: Skipping idle callback while disabled"));
+
+    ReconfigureTimer();
+    return;
+  }
+
   // Tell expired listeners they are expired,and find the next timeout
   Telemetry::AutoTimer<Telemetry::IDLE_NOTIFY_IDLE_MS> timer;
 
   // We need to initialise the time to the next idle switch.
   mDeltaToNextIdleSwitchInS = UINT32_MAX;
 
   // Create list of observers that should be notified.
   nsCOMArray<nsIObserver> notifyList;
--- a/widget/nsIdleService.h
+++ b/widget/nsIdleService.h
@@ -190,16 +190,22 @@ class nsIdleService : public nsIIdleServ
    *
    * Time in seconds
    *
    * If this value is 0 it means there are no active observers
    */
   uint32_t mDeltaToNextIdleSwitchInS;
 
   /**
+   * If true, the idle service is temporarily disabled, and all idle events
+   * will be ignored.
+   */
+  bool mDisabled = false;
+
+  /**
    * Absolute value for when the last user interaction took place.
    */
   mozilla::TimeStamp mLastUserInteraction;
 
   /**
    * Function that ensures the timer is running with at least the minimum time
    * needed.  It will kill the timer if there are no active observers.
    */