commit 56149b17a6bc4f1afafdbf1999edec1bd00991ce
parent 715789ae2130095ac08223b76eae619b045e11f0
Author: Alex Franchuk <afranchuk@mozilla.com>
Date: Thu, 23 Oct 2025 13:35:59 +0000
Bug 1992267 - Do not show nsBrowserApp MessageBoxes for background tasks r=gsvelto,glandium
Differential Revision: https://phabricator.services.mozilla.com/D267423
Diffstat:
1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp
@@ -105,6 +105,10 @@ using namespace mozilla;
#define kDesktopFolder "browser"
+#ifdef MOZ_BACKGROUNDTASKS
+static bool gIsBackgroundTask = false;
+#endif
+
static MOZ_FORMAT_PRINTF(1, 2) void Output(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
@@ -112,36 +116,58 @@ static MOZ_FORMAT_PRINTF(1, 2) void Output(const char* fmt, ...) {
#ifndef XP_WIN
vfprintf(stderr, fmt, ap);
#else
+ bool showMessageBox = true;
+
char msg[2048];
vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
wchar_t wide_msg[2048];
MultiByteToWideChar(CP_UTF8, 0, msg, -1, wide_msg, _countof(wide_msg));
+
# if MOZ_WINCONSOLE
- fwprintf_s(stderr, wide_msg);
-# else
- // Linking user32 at load-time interferes with the DLL blocklist (bug 932100).
- // This is a rare codepath, so we can load user32 at run-time instead.
- HMODULE user32 = LoadLibraryW(L"user32.dll");
- if (user32) {
- decltype(MessageBoxW)* messageBoxW =
- (decltype(MessageBoxW)*)GetProcAddress(user32, "MessageBoxW");
- if (messageBoxW) {
- messageBoxW(nullptr, wide_msg, L"Firefox",
- MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
+ showMessageBox = false;
+# elif defined(MOZ_BACKGROUNDTASKS)
+ // Only show a UI if this isn't a background tasks.
+ showMessageBox = !gIsBackgroundTask;
+# endif
+
+ if (showMessageBox) {
+ // Linking user32 at load-time interferes with the DLL blocklist (bug
+ // 932100). This is a rare codepath, so we can load user32 at run-time
+ // instead.
+
+ // If we fail to display the message box, we set showMessageBox to false to
+ // fall back to printing to stderr below.
+ HMODULE user32 = LoadLibraryW(L"user32.dll");
+ if (user32) {
+ decltype(MessageBoxW)* messageBoxW =
+ (decltype(MessageBoxW)*)GetProcAddress(user32, "MessageBoxW");
+ if (messageBoxW) {
+ messageBoxW(nullptr, wide_msg, L"Firefox",
+ MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
+ } else {
+ showMessageBox = false;
+ }
+ FreeLibrary(user32);
+ } else {
+ showMessageBox = false;
}
- FreeLibrary(user32);
}
-# endif
+
+ if (!showMessageBox) {
+ fwprintf_s(stderr, wide_msg);
+ }
#endif
va_end(ap);
}
/**
- * Return true if |arg| matches the given argument name.
+ * Return true if |arg| is a flag with the given string.
+ *
+ * A flag starts with one or two `-` characters, or a `/` character on windows.
*/
-static bool IsArg(const char* arg, const char* s) {
+static bool IsFlag(const char* arg, const char* s) {
if (*arg == '-') {
if (*++arg == '-') ++arg;
return !strcasecmp(arg, s);
@@ -154,13 +180,27 @@ static bool IsArg(const char* arg, const char* s) {
return false;
}
+/**
+ * Return true if any arguments are flags with the given string.
+ *
+ * A flag is defined per `IsFlag`.
+ */
+static bool HasFlag(int argc, char* argv[], const char* s) {
+ for (int i = 1; i < argc; i++) {
+ if (IsFlag(argv[i], s)) {
+ return true;
+ }
+ }
+ return false;
+}
+
MOZ_RUNINIT Bootstrap::UniquePtr gBootstrap;
static int do_main(int argc, char* argv[], char* envp[]) {
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
// Note that -app must be the *first* argument.
const char* appDataFile = getenv("XUL_APP_FILE");
- if ((!appDataFile || !*appDataFile) && (argc > 1 && IsArg(argv[1], "app"))) {
+ if ((!appDataFile || !*appDataFile) && (argc > 1 && IsFlag(argv[1], "app"))) {
if (argc == 2) {
Output("Incorrect number of arguments passed to -app");
return 255;
@@ -176,7 +216,7 @@ static int do_main(int argc, char* argv[], char* envp[]) {
argv[2] = argv[0];
argv += 2;
argc -= 2;
- } else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
+ } else if (argc > 1 && IsFlag(argv[1], "xpcshell")) {
for (int i = 1; i < argc; i++) {
argv[i] = argv[i + 1];
}
@@ -299,8 +339,14 @@ int main(int argc, char* argv[], char* envp[]) {
ReserveDefaultFileDescriptors();
#endif
+#ifdef MOZ_BACKGROUNDTASKS
+ // Check whether this is a background task very early, as the `Output`
+ // function uses this information.
+ gIsBackgroundTask = HasFlag(argc, argv, "backgroundtask");
+#endif
+
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
- if (argc > 1 && IsArg(argv[1], "contentproc")) {
+ if (argc > 1 && IsFlag(argv[1], "contentproc")) {
// Set the process type and gecko child id.
SetGeckoProcessType(argv[--argc]);
SetGeckoChildID(argv[--argc]);
@@ -436,7 +482,7 @@ int main(int argc, char* argv[], char* envp[]) {
// We will likely only ever support this as a command line argument on Windows
// and OSX, so we're ifdefing here just to not create any expectations.
#if defined(XP_WIN) || defined(XP_MACOSX)
- if (argc > 1 && IsArg(argv[1], "silentmode")) {
+ if (argc > 1 && IsFlag(argv[1], "silentmode")) {
::putenv(const_cast<char*>("MOZ_APP_SILENT_START=1"));
# if defined(XP_WIN)
// On windows We also want to set a separate variable, which we want to