Bug 1355147 - Add basic support for headless mode on macOS. r?jrmuizel draft
authorBrendan Dahl <brendan.dahl@gmail.com>
Mon, 03 Jul 2017 15:33:16 -0700
changeset 617136 f53e7aaf4418749c3c90dd3cf8b8374fb9e6131c
parent 615935 388d81ed93fa640f91d155f36254667c734157cf
child 617137 79791843773b103c172b2d0221d4b55def142f70
push id70939
push userbmo:bdahl@mozilla.com
push dateFri, 28 Jul 2017 00:20:56 +0000
reviewersjrmuizel
bugs1355147
milestone56.0a1
Bug 1355147 - Add basic support for headless mode on macOS. r?jrmuizel MozReview-Commit-ID: 23Wchhimynz
toolkit/xre/nsAppRunner.cpp
widget/cocoa/moz.build
widget/cocoa/nsAppShell.mm
xpfe/appshell/nsWebShellWindow.cpp
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1672,17 +1672,17 @@ DumpHelp()
          "  --new-instance     Open new instance, not a new window in running instance.\n"
          "  --UILocale <locale> Start with <locale> resources as UI Locale.\n"
          "  --safe-mode        Disables extensions and themes for this session.\n", (const char*) gAppData->name);
 
 #if defined(XP_WIN)
   printf("  --console          Start %s with a debugging console.\n", (const char*) gAppData->name);
 #endif
 
-#ifdef MOZ_WIDGET_GTK
+#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
   printf("  --headless         Run without a GUI.\n");
 #endif
 
   // this works, but only after the components have registered.  so if you drop in a new command line handler, --help
   // won't not until the second run.
   // out of the bug, because we ship a component.reg file, it works correctly.
   DumpArbitraryHelp();
 }
@@ -3167,17 +3167,17 @@ XREMain::XRE_mainInit(bool* aExitFlag)
     printf_stderr("*** You are running in chaos test mode. See ChaosMode.h. ***\n");
   }
 
   if (CheckArg("headless")) {
     PR_SetEnv("MOZ_HEADLESS=1");
   }
 
   if (gfxPlatform::IsHeadless()) {
-#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
+#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
     printf_stderr("*** You are running in headless mode.\n");
 #else
     Output(true, "Error: headless mode is not currently supported on this platform.\n");
     return 1;
 #endif
   }
 
   nsresult rv;
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -83,16 +83,17 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '/layout/forms',
     '/layout/generic',
     '/layout/style',
     '/layout/xul',
     '/widget',
+    '/widget/headless',
 ]
 
 if CONFIG['MOZ_ENABLE_SKIA_PDF']:
     LOCAL_INCLUDES += [
         # Skia includes because widget code includes PrintTargetSkPDF.h, and that
         # includes skia headers.
         '/gfx/skia/skia/include/config',
         '/gfx/skia/skia/include/core',
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -29,16 +29,17 @@
 #include "nsCocoaUtils.h"
 #include "nsChildView.h"
 #include "nsToolkit.h"
 #include "TextInputHandler.h"
 #include "mozilla/HangMonitor.h"
 #include "GeckoProfiler.h"
 #include "ScreenHelperCocoa.h"
 #include "mozilla/widget/ScreenManager.h"
+#include "HeadlessScreenHelper.h"
 #include "pratom.h"
 #if !defined(RELEASE_OR_BETA) || defined(DEBUG)
 #include "nsSandboxViolationSink.h"
 #endif
 
 #include <IOKit/pwr_mgt/IOPMLib.h>
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
@@ -305,17 +306,22 @@ nsAppShell::Init()
   
   mCFRunLoopSource = ::CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
   NS_ENSURE_STATE(mCFRunLoopSource);
 
   ::CFRunLoopAddSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
 
   if (XRE_IsParentProcess()) {
     ScreenManager& screenManager = ScreenManager::GetSingleton();
-    screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperCocoa>());
+
+    if (gfxPlatform::IsHeadless()) {
+      screenManager.SetHelper(mozilla::MakeUnique<HeadlessScreenHelper>());
+    } else {
+      screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperCocoa>());
+    }
   }
 
   rv = nsBaseAppShell::Init();
 
   if (!gAppShellMethodsSwizzled) {
     // We should only replace the original terminate: method if we're not
     // running in a Cocoa embedder. See bug 604901.
     if (!mRunningCocoaEmbedded) {
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -496,16 +496,19 @@ nsWebShellWindow::WindowDeactivated()
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm && window)
     fm->WindowLowered(window);
 }
 
 #ifdef USE_NATIVE_MENUS
 static void LoadNativeMenus(nsIDOMDocument *aDOMDoc, nsIWidget *aParentWindow)
 {
+  if (gfxPlatform::IsHeadless()) {
+    return;
+  }
   nsCOMPtr<nsINativeMenuService> nms = do_GetService("@mozilla.org/widget/nativemenuservice;1");
   if (!nms) {
     return;
   }
 
   // Find the menubar tag (if there is more than one, we ignore all but
   // the first).
   nsCOMPtr<nsIDOMNodeList> menubarElements;