mozilla-kde.patch
branchfirefox115
changeset 1190 2a24a948b5cf
parent 1189 ba0c97b018a6
child 1191 37e065158be7
--- a/mozilla-kde.patch	Mon Jun 05 21:17:55 2023 +0200
+++ b/mozilla-kde.patch	Sat Jul 29 14:34:45 2023 +0200
@@ -3,22 +3,18 @@
 # Date 1559294891 -7200
 #      Fri May 31 11:28:11 2019 +0200
 # Node ID c2aa7198fb925e7fde96abf65b6f68b9b755f112
-# Parent  4f8492f0f4bfa17f5b4523a1cdda15a45e3d74d3
+# Parent  0086fcc0d5c86a31cbac0a261ed7b526dd2df2e8
 Description: Add KDE integration to Firefox (toolkit parts)
 Author: Wolfgang Rosenauer <wolfgang@rosenauer.org>
 Author: Lubos Lunak <lunak@suse.com>
 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751
      https://bugzilla.novell.com/show_bug.cgi?id=170055
 
-diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
---- a/modules/libpref/Preferences.cpp
-+++ b/modules/libpref/Preferences.cpp
-@@ -91,16 +91,17 @@
- #include "plstr.h"
- #include "prdtoa.h"
- #include "prlink.h"
- #include "xpcpublic.h"
- #include "js/RootingAPI.h"
+Index: firefox-115.0/modules/libpref/Preferences.cpp
+===================================================================
+--- firefox-115.0.orig/modules/libpref/Preferences.cpp
++++ firefox-115.0/modules/libpref/Preferences.cpp
+@@ -95,6 +95,7 @@
  #ifdef MOZ_BACKGROUNDTASKS
  #  include "mozilla/BackgroundTasks.h"
  #endif
@@ -26,26 +22,15 @@
  
  #ifdef DEBUG
  #  include <map>
- #endif
- 
- #ifdef MOZ_MEMORY
- #  include "mozmemory.h"
- #endif
-@@ -4907,16 +4908,27 @@ nsresult Preferences::InitInitialObjects
-     "unix.js"
- #  if defined(_AIX)
-     ,
-     "aix.js"
- #  endif
+@@ -4911,6 +4912,16 @@ nsresult Preferences::InitInitialObjects
  #endif
    };
  
-+  if(nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires the helper?
-+    for(int i = 0;
-+        i < MOZ_ARRAY_LENGTH(specialFiles);
-+        ++i ) {
-+      if( *specialFiles[ i ] == '\0' ) {
-+        specialFiles[ i ] = "kde.js";
++  if (nsKDEUtils::kdeSession()) {  // TODO what if some setup actually requires
++                                   // the helper?
++    for (int i = 0; i < MOZ_ARRAY_LENGTH(specialFiles); ++i) {
++      if (*specialFiles[i] == '\0') {
++        specialFiles[i] = "kde.js";
 +        break;
 +      }
 +    }
@@ -54,17 +39,7 @@
    rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles,
                             ArrayLength(specialFiles));
    if (NS_FAILED(rv)) {
-     NS_WARNING("Error parsing application default preferences.");
-   }
- 
-   // Load jar:$app/omni.jar!/defaults/preferences/*.js
-   // or jar:$gre/omni.jar!/defaults/preferences/*.js.
-@@ -4981,17 +4993,17 @@ nsresult Preferences::InitInitialObjects
-       }
- 
-       nsCOMPtr<nsIFile> path = do_QueryInterface(elem);
-       if (!path) {
-         continue;
+@@ -4985,7 +4996,7 @@ nsresult Preferences::InitInitialObjects
        }
  
        // Do we care if a file provided by this process fails to load?
@@ -73,20 +48,11 @@
      }
    }
  
- #if defined(MOZ_WIDGET_GTK)
-   // To ensure the system-wide preferences are not overwritten by
-   // firefox/browser/defauts/preferences/*.js we need to load
-   // the /etc/firefox/defaults/pref/*.js settings as last.
-   // Under Flatpak, the NS_OS_SYSTEM_CONFIG_DIR points to /app/etc/firefox
-diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build
---- a/modules/libpref/moz.build
-+++ b/modules/libpref/moz.build
-@@ -122,16 +122,20 @@ EXPORTS.mozilla += [
- ]
- EXPORTS.mozilla += sorted(["!" + g for g in gen_h])
- 
- UNIFIED_SOURCES += [
-     "Preferences.cpp",
+Index: firefox-115.0/modules/libpref/moz.build
+===================================================================
+--- firefox-115.0.orig/modules/libpref/moz.build
++++ firefox-115.0/modules/libpref/moz.build
+@@ -126,6 +126,10 @@ UNIFIED_SOURCES += [
      "SharedPrefMap.cpp",
  ]
  
@@ -97,20 +63,11 @@
  gen_all_tuple = tuple(gen_h + gen_cpp + gen_rs)
  
  GeneratedFile(
-     *gen_all_tuple,
-     script="init/generate_static_pref_list.py",
-     entry_point="emit_code",
-     inputs=["init/StaticPrefList.yaml"]
- )
-diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py
---- a/python/mozbuild/mozpack/chrome/flags.py
-+++ b/python/mozbuild/mozpack/chrome/flags.py
-@@ -229,16 +229,17 @@ class Flags(OrderedDict):
-         "os": StringFlag,
-         "osversion": VersionFlag,
-         "abi": StringFlag,
-         "platform": Flag,
-         "xpcnativewrappers": Flag,
+Index: firefox-115.0/python/mozbuild/mozpack/chrome/flags.py
+===================================================================
+--- firefox-115.0.orig/python/mozbuild/mozpack/chrome/flags.py
++++ firefox-115.0/python/mozbuild/mozpack/chrome/flags.py
+@@ -234,6 +234,7 @@ class Flags(OrderedDict):
          "tablet": Flag,
          "process": StringFlag,
          "backgroundtask": StringFlag,
@@ -118,20 +75,11 @@
      }
      RE = re.compile(r"([!<>=]+)")
  
-     def __init__(self, *flags):
-         """
-         Initialize a set of flags given in string form.
-            flags = Flags('contentaccessible=yes', 'appversion>=3.5')
-         """
-diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py
---- a/python/mozbuild/mozpack/chrome/manifest.py
-+++ b/python/mozbuild/mozpack/chrome/manifest.py
-@@ -38,16 +38,17 @@ class ManifestEntry(object):
-         "os",
-         "osversion",
-         "abi",
-         "xpcnativewrappers",
-         "tablet",
+Index: firefox-115.0/python/mozbuild/mozpack/chrome/manifest.py
+===================================================================
+--- firefox-115.0.orig/python/mozbuild/mozpack/chrome/manifest.py
++++ firefox-115.0/python/mozbuild/mozpack/chrome/manifest.py
+@@ -43,6 +43,7 @@ class ManifestEntry(object):
          "process",
          "contentaccessible",
          "backgroundtask",
@@ -139,20 +87,11 @@
      ]
  
      def __init__(self, base, *flags):
-         """
-         Initialize a manifest entry with the given base path and flags.
-         """
-         self.base = base
-         self.flags = Flags(*flags)
-diff --git a/toolkit/components/downloads/moz.build b/toolkit/components/downloads/moz.build
---- a/toolkit/components/downloads/moz.build
-+++ b/toolkit/components/downloads/moz.build
-@@ -46,10 +46,14 @@ XPCOM_MANIFESTS += [
- 
- if CONFIG["MOZ_PLACES"]:
-     EXTRA_JS_MODULES += [
-         "DownloadHistory.sys.mjs",
-     ]
+Index: firefox-115.0/toolkit/components/downloads/moz.build
+===================================================================
+--- firefox-115.0.orig/toolkit/components/downloads/moz.build
++++ firefox-115.0/toolkit/components/downloads/moz.build
+@@ -51,5 +51,9 @@ if CONFIG["MOZ_PLACES"]:
  
  FINAL_LIBRARY = "xul"
  
@@ -162,15 +101,11 @@
 +
  with Files("**"):
      BUG_COMPONENT = ("Toolkit", "Downloads API")
-diff --git a/toolkit/mozapps/downloads/HelperAppDlg.jsm b/toolkit/mozapps/downloads/HelperAppDlg.jsm
---- a/toolkit/mozapps/downloads/HelperAppDlg.jsm
-+++ b/toolkit/mozapps/downloads/HelperAppDlg.jsm
-@@ -1250,36 +1250,66 @@ nsUnknownContentTypeDialog.prototype = {
-         params.handlerApp &&
-         params.handlerApp.executable &&
-         params.handlerApp.executable.isFile()
-       ) {
-         // Remember the file they chose to run.
+Index: firefox-115.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
+===================================================================
+--- firefox-115.0.orig/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
++++ firefox-115.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs
+@@ -1246,26 +1246,56 @@ nsUnknownContentTypeDialog.prototype = {
          this.chosenApp = params.handlerApp;
        }
      } else if ("@mozilla.org/applicationchooser;1" in Cc) {
@@ -247,20 +182,11 @@
      } else {
        var nsIFilePicker = Ci.nsIFilePicker;
        var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
-       fp.init(
-         this.mDialog,
-         this.dialogElement("strings").getString("chooseAppFilePickerTitle"),
-         nsIFilePicker.modeOpen
-       );
-diff --git a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
---- a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
-+++ b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
-@@ -11,16 +11,18 @@
- #include "prenv.h"
- #include "nsInterfaceHashtable.h"
- #include "nsHashtablesFwd.h"
- #include "nsHashKeys.h"
- #include "nsNetUtil.h"
+Index: firefox-115.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
+===================================================================
+--- firefox-115.0.orig/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
++++ firefox-115.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
+@@ -16,6 +16,8 @@
  #include "nsISupportsPrimitives.h"
  #include "nsIGSettingsService.h"
  #include "nsReadableUtils.h"
@@ -269,17 +195,7 @@
  
  using namespace mozilla;
  
- class nsUnixSystemProxySettings final : public nsISystemProxySettings {
-  public:
-   NS_DECL_ISUPPORTS
-   NS_DECL_NSISYSTEMPROXYSETTINGS
- 
-@@ -34,16 +36,18 @@ class nsUnixSystemProxySettings final : 
-   nsCOMPtr<nsIGSettingsCollection> mProxySettings;
-   nsInterfaceHashtable<nsCStringHashKey, nsIGSettingsCollection>
-       mSchemeProxySettings;
-   nsresult GetProxyFromGSettings(const nsACString& aScheme,
-                                  const nsACString& aHost, int32_t aPort,
+@@ -39,6 +41,8 @@ class nsUnixSystemProxySettings final :
                                   nsACString& aResult);
    nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType,
                                         nsACString& aResult);
@@ -288,17 +204,7 @@
  };
  
  NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings)
- 
- NS_IMETHODIMP
- nsUnixSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) {
-   // dbus prevents us from being threadsafe, but this routine should not block
-   // anyhow
-@@ -392,21 +396,50 @@ nsresult nsUnixSystemProxySettings::GetP
-   return NS_OK;
- }
- 
- nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
-                                                    const nsACString& aScheme,
+@@ -396,6 +400,9 @@ nsresult nsUnixSystemProxySettings::GetP
                                                     const nsACString& aHost,
                                                     const int32_t aPort,
                                                     nsACString& aResult) {
@@ -308,51 +214,40 @@
    if (mProxySettings) {
      nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult);
      if (NS_SUCCEEDED(rv)) return rv;
-   }
- 
+@@ -404,6 +411,28 @@ nsresult nsUnixSystemProxySettings::GetP
    return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult);
  }
  
-+nsresult
-+nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
-+                                           const nsACString& aHost,
-+                                           PRInt32 aPort,
-+                                           nsACString& aResult)
-+{
++nsresult nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
++                                                    const nsACString& aHost,
++                                                    PRInt32 aPort,
++                                                    nsACString& aResult) {
 +  nsAutoCString url;
 +  url = aScheme;
 +  url += "://";
 +  url += aHost;
-+  if( aPort >= 0 )
-+  {
++  if (aPort >= 0) {
 +    url += ":";
 +    url += nsPrintfCString("%d", aPort);
 +  }
 +  nsTArray<nsCString> command;
-+  command.AppendElement( "GETPROXY"_ns );
-+  command.AppendElement( url );
++  command.AppendElement("GETPROXY"_ns);
++  command.AppendElement(url);
 +  nsTArray<nsCString> result;
-+  if( !nsKDEUtils::command( command, &result ) || result.Length() != 1 )
++  if (!nsKDEUtils::command(command, &result) || result.Length() != 1)
 +    return NS_ERROR_FAILURE;
 +  aResult = result[0];
 +  return NS_OK;
 +}
 +
-+
  NS_IMPL_COMPONENT_FACTORY(nsUnixSystemProxySettings) {
    auto result = MakeRefPtr<nsUnixSystemProxySettings>();
    result->Init();
-   return result.forget().downcast<nsISupports>();
- }
-diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build
---- a/toolkit/xre/moz.build
-+++ b/toolkit/xre/moz.build
-@@ -91,17 +91,19 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "co
-         "../components/printingui",
-     ]
- elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "uikit":
-     UNIFIED_SOURCES += [
-         "nsNativeAppSupportDefault.cpp",
+Index: firefox-115.0/toolkit/xre/moz.build
+===================================================================
+--- firefox-115.0.orig/toolkit/xre/moz.build
++++ firefox-115.0/toolkit/xre/moz.build
+@@ -96,7 +96,9 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "ui
          "UIKitDirProvider.mm",
      ]
  elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
@@ -362,16 +257,11 @@
          "nsNativeAppSupportUnix.cpp",
      ]
      CXXFLAGS += CONFIG["MOZ_X11_SM_CFLAGS"]
- else:
-     UNIFIED_SOURCES += [
-         "nsNativeAppSupportDefault.cpp",
-     ]
- 
-diff --git a/toolkit/xre/nsKDEUtils.cpp b/toolkit/xre/nsKDEUtils.cpp
-new file mode 100644
+Index: firefox-115.0/toolkit/xre/nsKDEUtils.cpp
+===================================================================
 --- /dev/null
-+++ b/toolkit/xre/nsKDEUtils.cpp
-@@ -0,0 +1,321 @@
++++ firefox-115.0/toolkit/xre/nsKDEUtils.cpp
+@@ -0,0 +1,286 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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
@@ -395,309 +285,274 @@
 +// copied from X11/X.h as a hack since for an unknown
 +// reason it's not picked up from X11/X.h
 +#ifndef None
-+#define None                 0L /* universal null resource or null atom */
++#  define None 0L /* universal null resource or null atom */
 +#endif
 +
-+//#define DEBUG_KDE
++// #define DEBUG_KDE
 +#ifdef DEBUG_KDE
-+#define KMOZILLAHELPER "kmozillahelper"
++#  define KMOZILLAHELPER "kmozillahelper"
 +#else
 +// not need for lib64, it's a binary
-+#define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper"
++#  define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper"
 +#endif
 +
 +#define KMOZILLAHELPER_VERSION 6
-+#define MAKE_STR2( n ) #n
-+#define MAKE_STR( n ) MAKE_STR2( n )
++#define MAKE_STR2(n) #n
++#define MAKE_STR(n) MAKE_STR2(n)
 +
-+static bool getKdeSession()
-+{
-+    if (PR_GetEnv("KDE_FULL_SESSION"))
-+    {
-+      return true;
-+    }
-+    return false;
++static bool getKdeSession() {
++  if (PR_GetEnv("KDE_FULL_SESSION")) {
++    return true;
++  }
++  return false;
 +}
 +
-+static bool getKdeSupport()
-+    {
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "CHECK"_ns );
-+    command.AppendElement( "KMOZILLAHELPER_VERSION"_ns );
-+    bool kde = nsKDEUtils::command( command );
++static bool getKdeSupport() {
++  nsTArray<nsCString> command;
++  command.AppendElement("CHECK"_ns);
++  command.AppendElement("KMOZILLAHELPER_VERSION"_ns);
++  bool kde = nsKDEUtils::command(command);
 +#ifdef DEBUG_KDE
-+    fprintf( stderr, "KDE RUNNING %d\n", kde );
++  fprintf(stderr, "KDE RUNNING %d\n", kde);
 +#endif
-+    return kde;
-+    }
++  return kde;
++}
 +
-+nsKDEUtils::nsKDEUtils()
-+    : commandFile( NULL )
-+    , replyFile( NULL )
-+    {
-+    }
++nsKDEUtils::nsKDEUtils() : commandFile(NULL), replyFile(NULL) {}
 +
-+nsKDEUtils::~nsKDEUtils()
-+    {
-+//    closeHelper(); not actually useful, exiting will close the fd too
-+    }
++nsKDEUtils::~nsKDEUtils() {
++  //    closeHelper(); not actually useful, exiting will close the fd too
++}
 +
-+nsKDEUtils* nsKDEUtils::self()
-+    {
-+    static nsKDEUtils s;
-+    return &s;
-+    }
++nsKDEUtils* nsKDEUtils::self() {
++  static nsKDEUtils s;
++  return &s;
++}
 +
 +static bool helperRunning = false;
 +static bool helperFailed = false;
 +
-+bool nsKDEUtils::kdeSession()
-+    {
-+    static bool session = getKdeSession();
-+    return session;
-+    }
++bool nsKDEUtils::kdeSession() {
++  static bool session = getKdeSession();
++  return session;
++}
++
++bool nsKDEUtils::kdeSupport() {
++  static bool support = kdeSession() && getKdeSupport();
++  return support && helperRunning;
++}
++
++struct nsKDECommandData {
++  FILE* file;
++  nsTArray<nsCString>* output;
++  GMainLoop* loop;
++  bool success;
++};
 +
-+bool nsKDEUtils::kdeSupport()
-+    {
-+    static bool support = kdeSession() && getKdeSupport();
-+    return support && helperRunning;
++static gboolean kdeReadFunc(GIOChannel*, GIOCondition, gpointer data) {
++  nsKDECommandData* p = static_cast<nsKDECommandData*>(data);
++  char buf[8192];  // TODO big enough
++  bool command_done = false;
++  bool command_failed = false;
++  while (!command_done && !command_failed &&
++         fgets(buf, 8192, p->file) !=
++             NULL) {  // TODO what if the kernel splits a line into two chunks?
++                      // #ifdef DEBUG_KDE
++    //         fprintf( stderr, "READ: %s %d\n", buf, feof( p->file ));
++    // #endif
++    if (char* eol = strchr(buf, '\n')) *eol = '\0';
++    command_done = (strcmp(buf, "\\1") == 0);
++    command_failed = (strcmp(buf, "\\0") == 0);
++    nsAutoCString line(buf);
++    line.ReplaceSubstring("\\n", "\n");
++    line.ReplaceSubstring(
++        "\\"
++        "\\",
++        "\\");  //  \\ -> \ , i.e. unescape
++    if (p->output && !(command_done || command_failed))
++      p->output->AppendElement(nsCString(buf));  // TODO utf8?
++  }
++  bool quit = false;
++  if (feof(p->file) || command_failed) {
++    quit = true;
++    p->success = false;
++  }
++  if (command_done) {  // reading one reply finished
++    quit = true;
++    p->success = true;
++  }
++  if (quit) {
++    if (p->loop) g_main_loop_quit(p->loop);
++    return FALSE;
++  }
++  return TRUE;
++}
++
++bool nsKDEUtils::command(const nsTArray<nsCString>& command,
++                         nsTArray<nsCString>* output) {
++  return self()->internalCommand(command, NULL, false, output);
++}
++
++bool nsKDEUtils::command(nsIArray* command, nsIArray** output) {
++  nsTArray<nsCString> in;
++  PRUint32 length;
++  command->GetLength(&length);
++  for (PRUint32 i = 0; i < length; i++) {
++    nsCOMPtr<nsISupportsCString> str = do_QueryElementAt(command, i);
++    if (str) {
++      nsAutoCString s;
++      str->GetData(s);
++      in.AppendElement(s);
 +    }
++  }
 +
-+struct nsKDECommandData
-+    {
-+    FILE* file;
-+    nsTArray<nsCString>* output;
-+    GMainLoop* loop;
-+    bool success;
-+    };
++  nsTArray<nsCString> out;
++  bool ret = self()->internalCommand(in, NULL, false, &out);
++
++  if (!output) return ret;
++
++  nsCOMPtr<nsIMutableArray> result = do_CreateInstance(NS_ARRAY_CONTRACTID);
++  if (!result) return false;
++
++  for (PRUint32 i = 0; i < out.Length(); i++) {
++    nsCOMPtr<nsISupportsCString> rstr =
++        do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
++    if (!rstr) return false;
++
++    rstr->SetData(out[i]);
++    result->AppendElement(rstr);
++  }
++
++  NS_ADDREF(*output = result);
++  return ret;
++}
++
++bool nsKDEUtils::commandBlockUi(const nsTArray<nsCString>& command,
++                                GtkWindow* parent,
++                                nsTArray<nsCString>* output) {
++  return self()->internalCommand(command, parent, true, output);
++}
 +
-+static gboolean kdeReadFunc( GIOChannel*, GIOCondition, gpointer data )
++bool nsKDEUtils::internalCommand(const nsTArray<nsCString>& command,
++                                 GtkWindow* parent, bool blockUi,
++                                 nsTArray<nsCString>* output) {
++  if (!startHelper()) return false;
++  feedCommand(command);
++  // do not store the data in 'this' but in extra structure, just in case there
++  // is reentrancy (can there be? the event loop is re-entered)
++  nsKDECommandData data;
++  data.file = replyFile;
++  data.output = output;
++  data.success = false;
++  if (blockUi) {
++    data.loop = g_main_loop_new(NULL, FALSE);
++    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
++    if (parent && gtk_window_get_group(parent))
++      gtk_window_group_add_window(gtk_window_get_group(parent),
++                                  GTK_WINDOW(window));
++    gtk_widget_realize(window);
++    gtk_widget_set_sensitive(window, TRUE);
++    gtk_grab_add(window);
++    GIOChannel* channel = g_io_channel_unix_new(fileno(data.file));
++    g_io_add_watch(channel,
++                   static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP),
++                   kdeReadFunc, &data);
++    g_io_channel_unref(channel);
++    g_main_loop_run(data.loop);
++    g_main_loop_unref(data.loop);
++    gtk_grab_remove(window);
++    gtk_widget_destroy(window);
++  } else {
++    data.loop = NULL;
++    while (kdeReadFunc(NULL, static_cast<GIOCondition>(0), &data))
++      ;
++  }
++  return data.success;
++}
++
++bool nsKDEUtils::startHelper() {
++  if (helperRunning) return true;
++  if (helperFailed) return false;
++  helperFailed = true;
++  int fdcommand[2];
++  int fdreply[2];
++  if (pipe(fdcommand) < 0) return false;
++  if (pipe(fdreply) < 0) {
++    close(fdcommand[0]);
++    close(fdcommand[1]);
++    return false;
++  }
++  char* args[2] = {const_cast<char*>(KMOZILLAHELPER), NULL};
++  switch (fork()) {
++    case -1: {
++      close(fdcommand[0]);
++      close(fdcommand[1]);
++      close(fdreply[0]);
++      close(fdreply[1]);
++      return false;
++    }
++    case 0:  // child
 +    {
-+    nsKDECommandData* p = static_cast< nsKDECommandData* >( data );
-+    char buf[ 8192 ]; // TODO big enough
-+    bool command_done = false;
-+    bool command_failed = false;
-+    while( !command_done && !command_failed && fgets( buf, 8192, p->file ) != NULL )
-+        { // TODO what if the kernel splits a line into two chunks?
-+//#ifdef DEBUG_KDE
-+//        fprintf( stderr, "READ: %s %d\n", buf, feof( p->file ));
-+//#endif
-+        if( char* eol = strchr( buf, '\n' ))
-+            *eol = '\0';
-+        command_done = ( strcmp( buf, "\\1" ) == 0 );
-+        command_failed = ( strcmp( buf, "\\0" ) == 0 );
-+        nsAutoCString line( buf );
-+        line.ReplaceSubstring( "\\n", "\n" );
-+        line.ReplaceSubstring( "\\" "\\", "\\" ); //  \\ -> \ , i.e. unescape
-+        if( p->output && !( command_done || command_failed ))
-+            p->output->AppendElement( nsCString( buf )); // TODO utf8?
-+        }
-+    bool quit = false;
-+    if( feof( p->file ) || command_failed )
-+        {
-+        quit = true;
-+        p->success = false;
-+        }
-+    if( command_done )
-+        { // reading one reply finished
-+        quit = true;
-+        p->success = true;
-+        }
-+    if( quit )
-+        {
-+        if( p->loop )
-+            g_main_loop_quit( p->loop );
-+        return FALSE;
-+        }
-+    return TRUE;
++      if (dup2(fdcommand[0], STDIN_FILENO) < 0) _exit(1);
++      if (dup2(fdreply[1], STDOUT_FILENO) < 0) _exit(1);
++      int maxfd = 1024;  // close all other fds
++      struct rlimit rl;
++      if (getrlimit(RLIMIT_NOFILE, &rl) == 0) maxfd = rl.rlim_max;
++      for (int i = 3; i < maxfd; ++i) close(i);
++#ifdef DEBUG_KDE
++      execvp(KMOZILLAHELPER, args);
++#else
++      execv(KMOZILLAHELPER, args);
++#endif
++      _exit(1);  // failed
 +    }
-+
-+bool nsKDEUtils::command( const nsTArray<nsCString>& command, nsTArray<nsCString>* output )
-+    {
-+    return self()->internalCommand( command, NULL, false, output );
-+    }
-+
-+bool nsKDEUtils::command( nsIArray* command, nsIArray** output)
++    default:  // parent
 +    {
-+    nsTArray<nsCString> in;
-+    PRUint32 length;
-+    command->GetLength( &length );
-+    for ( PRUint32 i = 0; i < length; i++ )
-+        {
-+        nsCOMPtr<nsISupportsCString> str = do_QueryElementAt( command, i );
-+        if( str )
-+            {
-+            nsAutoCString s;
-+            str->GetData( s );
-+            in.AppendElement( s );
-+            }
-+        }
-+
-+    nsTArray<nsCString> out;
-+    bool ret = self()->internalCommand( in, NULL, false, &out );
-+
-+    if ( !output ) return ret;
-+
-+    nsCOMPtr<nsIMutableArray> result = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if ( !result ) return false;
-+
-+    for ( PRUint32 i = 0; i < out.Length(); i++ )
-+        {
-+        nsCOMPtr<nsISupportsCString> rstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+        if ( !rstr ) return false;
-+
-+        rstr->SetData( out[i] );
-+        result->AppendElement( rstr );
-+        }
-+
-+    NS_ADDREF( *output = result);
-+    return ret;
-+    }
-+
-+
-+bool nsKDEUtils::commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output )
-+    {
-+    return self()->internalCommand( command, parent, true, output );
-+    }
-+
-+bool nsKDEUtils::internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool blockUi,
-+    nsTArray<nsCString>* output )
-+    {
-+    if( !startHelper())
++      commandFile = fdopen(fdcommand[1], "w");
++      replyFile = fdopen(fdreply[0], "r");
++      close(fdcommand[0]);
++      close(fdreply[1]);
++      if (commandFile == NULL || replyFile == NULL) {
++        closeHelper();
 +        return false;
-+    feedCommand( command );
-+    // do not store the data in 'this' but in extra structure, just in case there
-+    // is reentrancy (can there be? the event loop is re-entered)
-+    nsKDECommandData data;
-+    data.file = replyFile;
-+    data.output = output;
-+    data.success = false;
-+    if( blockUi )
-+        {
-+        data.loop = g_main_loop_new( NULL, FALSE );
-+        GtkWidget* window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-+        if( parent && gtk_window_get_group(parent) )
-+            gtk_window_group_add_window( gtk_window_get_group(parent), GTK_WINDOW( window ));
-+        gtk_widget_realize( window );
-+        gtk_widget_set_sensitive( window, TRUE );
-+        gtk_grab_add( window );
-+        GIOChannel* channel = g_io_channel_unix_new( fileno( data.file ));
-+        g_io_add_watch( channel, static_cast< GIOCondition >( G_IO_IN | G_IO_ERR | G_IO_HUP ), kdeReadFunc, &data );
-+        g_io_channel_unref( channel );
-+        g_main_loop_run( data.loop );
-+        g_main_loop_unref( data.loop );
-+        gtk_grab_remove( window );
-+        gtk_widget_destroy( window );
-+        }
-+    else
-+        {
-+        data.loop = NULL;
-+        while( kdeReadFunc( NULL, static_cast< GIOCondition >( 0 ), &data ))
-+            ;
-+        }
-+    return data.success;
++      }
++      // ok, helper ready, getKdeRunning() will check if it works
 +    }
++  }
++  helperFailed = false;
++  helperRunning = true;
++  return true;
++}
++
++void nsKDEUtils::closeHelper() {
++  if (commandFile != NULL)
++    fclose(commandFile);  // this will also make the helper quit
++  if (replyFile != NULL) fclose(replyFile);
++  helperRunning = false;
++}
 +
-+bool nsKDEUtils::startHelper()
-+    {
-+    if( helperRunning )
-+        return true;
-+    if( helperFailed )
-+        return false;
-+    helperFailed = true;
-+    int fdcommand[ 2 ];
-+    int fdreply[ 2 ];
-+    if( pipe( fdcommand ) < 0 )
-+        return false;
-+    if( pipe( fdreply ) < 0 )
-+        {
-+        close( fdcommand[ 0 ] );
-+        close( fdcommand[ 1 ] );
-+        return false;
-+        }
-+    char* args[ 2 ] = { const_cast< char* >( KMOZILLAHELPER ), NULL };
-+    switch( fork())
-+        {
-+        case -1:
-+            {
-+            close( fdcommand[ 0 ] );
-+            close( fdcommand[ 1 ] );
-+            close( fdreply[ 0 ] );
-+            close( fdreply[ 1 ] );
-+            return false;
-+            }
-+        case 0: // child
-+            {
-+            if( dup2( fdcommand[ 0 ], STDIN_FILENO ) < 0 )
-+                _exit( 1 );
-+            if( dup2( fdreply[ 1 ], STDOUT_FILENO ) < 0 )
-+                _exit( 1 );
-+            int maxfd = 1024; // close all other fds
-+            struct rlimit rl;
-+            if( getrlimit( RLIMIT_NOFILE, &rl ) == 0 )
-+                maxfd = rl.rlim_max;
-+            for( int i = 3;
-+                 i < maxfd;
-+                 ++i )
-+                close( i );
++void nsKDEUtils::feedCommand(const nsTArray<nsCString>& command) {
++  for (int i = 0; i < command.Length(); ++i) {
++    nsCString line = command[i];
++    line.ReplaceSubstring("\\",
++                          "\\"
++                          "\\");  // \ -> \\ , i.e. escape
++    line.ReplaceSubstring("\n", "\\n");
 +#ifdef DEBUG_KDE
-+            execvp( KMOZILLAHELPER, args );
-+#else
-+            execv( KMOZILLAHELPER, args );
++    fprintf(stderr, "COMM: %s\n", line.get());
 +#endif
-+            _exit( 1 ); // failed
-+            }
-+        default: // parent
-+            {
-+            commandFile = fdopen( fdcommand[ 1 ], "w" );
-+            replyFile = fdopen( fdreply[ 0 ], "r" );
-+            close( fdcommand[ 0 ] );
-+            close( fdreply[ 1 ] );
-+            if( commandFile == NULL || replyFile == NULL )
-+                {
-+                closeHelper();
-+                return false;
-+                }
-+            // ok, helper ready, getKdeRunning() will check if it works
-+            }
-+        }
-+    helperFailed = false;
-+    helperRunning = true;
-+    return true;
-+    }
-+
-+void nsKDEUtils::closeHelper()
-+    {
-+    if( commandFile != NULL )
-+        fclose( commandFile ); // this will also make the helper quit
-+    if( replyFile != NULL )
-+        fclose( replyFile );
-+    helperRunning = false;
-+    }
-+
-+void nsKDEUtils::feedCommand( const nsTArray<nsCString>& command )
-+    {
-+    for( int i = 0;
-+         i < command.Length();
-+         ++i )
-+        {
-+        nsCString line = command[ i ];
-+        line.ReplaceSubstring( "\\", "\\" "\\" ); // \ -> \\ , i.e. escape
-+        line.ReplaceSubstring( "\n", "\\n" );
-+#ifdef DEBUG_KDE
-+        fprintf( stderr, "COMM: %s\n", line.get());
-+#endif
-+        fputs( line.get(), commandFile );
-+        fputs( "\n", commandFile );
-+        }
-+    fputs( "\\E\n", commandFile ); // done as \E, so it cannot happen in normal data
-+    fflush( commandFile );
-+    }
-diff --git a/toolkit/xre/nsKDEUtils.h b/toolkit/xre/nsKDEUtils.h
-new file mode 100644
++    fputs(line.get(), commandFile);
++    fputs("\n", commandFile);
++  }
++  fputs("\\E\n",
++        commandFile);  // done as \E, so it cannot happen in normal data
++  fflush(commandFile);
++}
+Index: firefox-115.0/toolkit/xre/nsKDEUtils.h
+===================================================================
 --- /dev/null
-+++ b/toolkit/xre/nsKDEUtils.h
-@@ -0,0 +1,48 @@
++++ firefox-115.0/toolkit/xre/nsKDEUtils.h
+@@ -0,0 +1,53 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* 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
@@ -714,47 +569,48 @@
 +
 +class nsIArray;
 +
-+class NS_EXPORT nsKDEUtils
-+    {
-+    public:
-+        /* Returns true if running inside a KDE session (regardless of whether there is KDE
-+           support available for Firefox). This should be used e.g. when determining
-+           dialog button order but not for code that requires the KDE support. */
-+        static bool kdeSession();
-+        /* Returns true if running inside a KDE session and KDE support is available
-+           for Firefox. This should be used everywhere where the external helper is needed. */
-+        static bool kdeSupport();
-+        /* Executes the given helper command, returns true if helper returned success. */
-+        static bool command( const nsTArray<nsCString>& command, nsTArray<nsCString>* output = NULL );
-+        static bool command( nsIArray* command, nsIArray** output = NULL );
-+        /* Like command(), but additionally blocks the parent widget like if there was
-+           a modal dialog shown and enters the event loop (i.e. there are still paint updates,
-+           this is for commands that take long). */
-+        static bool commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output = NULL );
++class NS_EXPORT nsKDEUtils {
++ public:
++  /* Returns true if running inside a KDE session (regardless of whether there
++     is KDE support available for Firefox). This should be used e.g. when
++     determining dialog button order but not for code that requires the KDE
++     support. */
++  static bool kdeSession();
++  /* Returns true if running inside a KDE session and KDE support is available
++     for Firefox. This should be used everywhere where the external helper is
++     needed. */
++  static bool kdeSupport();
++  /* Executes the given helper command, returns true if helper returned success.
++   */
++  static bool command(const nsTArray<nsCString>& command,
++                      nsTArray<nsCString>* output = NULL);
++  static bool command(nsIArray* command, nsIArray** output = NULL);
++  /* Like command(), but additionally blocks the parent widget like if there was
++     a modal dialog shown and enters the event loop (i.e. there are still paint
++     updates, this is for commands that take long). */
++  static bool commandBlockUi(const nsTArray<nsCString>& command,
++                             GtkWindow* parent,
++                             nsTArray<nsCString>* output = NULL);
 +
-+    private:
-+        nsKDEUtils();
-+        ~nsKDEUtils();
-+        static nsKDEUtils* self();
-+        bool startHelper();
-+        void closeHelper();
-+        void feedCommand( const nsTArray<nsCString>& command );
-+        bool internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool isParent,
-+            nsTArray<nsCString>* output );
-+        FILE* commandFile;
-+        FILE* replyFile;
-+    };
++ private:
++  nsKDEUtils();
++  ~nsKDEUtils();
++  static nsKDEUtils* self();
++  bool startHelper();
++  void closeHelper();
++  void feedCommand(const nsTArray<nsCString>& command);
++  bool internalCommand(const nsTArray<nsCString>& command, GtkWindow* parent,
++                       bool isParent, nsTArray<nsCString>* output);
++  FILE* commandFile;
++  FILE* replyFile;
++};
 +
-+#endif // nsKDEUtils
-diff --git a/uriloader/exthandler/HandlerServiceParent.cpp b/uriloader/exthandler/HandlerServiceParent.cpp
---- a/uriloader/exthandler/HandlerServiceParent.cpp
-+++ b/uriloader/exthandler/HandlerServiceParent.cpp
-@@ -13,17 +13,17 @@
- #include "ContentHandlerService.h"
- #include "nsIExternalProtocolService.h"
- #include "nsStringEnumerator.h"
- #include "nsIMutableArray.h"
- #include "nsCExternalHandlerService.h"
++#endif  // nsKDEUtils
+Index: firefox-115.0/uriloader/exthandler/HandlerServiceParent.cpp
+===================================================================
+--- firefox-115.0.orig/uriloader/exthandler/HandlerServiceParent.cpp
++++ firefox-115.0/uriloader/exthandler/HandlerServiceParent.cpp
+@@ -18,7 +18,7 @@
  #include "nsComponentManagerUtils.h"
  #include "nsServiceManagerUtils.h"
  #ifdef MOZ_WIDGET_GTK
@@ -763,39 +619,22 @@
  #endif
  
  using mozilla::dom::ContentHandlerService;
- using mozilla::dom::HandlerApp;
- using mozilla::dom::HandlerInfo;
- using mozilla::dom::RemoteHandlerApp;
- 
- namespace {
-@@ -306,17 +306,17 @@ mozilla::ipc::IPCResult HandlerServicePa
-     const nsACString& aProtocolScheme, bool* aHandlerExists) {
-   if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) {
-     *aHandlerExists = false;
-     return IPC_OK();
+@@ -310,8 +310,8 @@ mozilla::ipc::IPCResult HandlerServicePa
    }
  #ifdef MOZ_WIDGET_GTK
    // Check the GNOME registry for a protocol handler
-   *aHandlerExists =
+-  *aHandlerExists =
 -      nsGNOMERegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get());
-+      nsCommonRegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get());
++  *aHandlerExists = nsCommonRegistry::HandlerExists(
++      PromiseFlatCString(aProtocolScheme).get());
  #else
    *aHandlerExists = false;
  #endif
-   return IPC_OK();
- }
- 
- /*
-  * Check if a handler exists for the provided protocol. Check the datastore
-diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build
---- a/uriloader/exthandler/moz.build
-+++ b/uriloader/exthandler/moz.build
-@@ -81,17 +81,19 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "ui
- else:
-     # These files can't be built in unified mode because they redefine LOG.
-     SOURCES += [
-         osdir + "/nsOSHelperAppService.cpp",
-     ]
+Index: firefox-115.0/uriloader/exthandler/moz.build
+===================================================================
+--- firefox-115.0.orig/uriloader/exthandler/moz.build
++++ firefox-115.0/uriloader/exthandler/moz.build
+@@ -86,7 +86,9 @@ else:
  
  if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
      UNIFIED_SOURCES += [
@@ -805,17 +644,7 @@
          "unix/nsMIMEInfoUnix.cpp",
      ]
  elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
-     UNIFIED_SOURCES += [
-         "android/nsMIMEInfoAndroid.cpp",
-     ]
- elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
-     UNIFIED_SOURCES += [
-@@ -129,16 +131,17 @@ include("/ipc/chromium/chromium-config.m
- FINAL_LIBRARY = "xul"
- 
- LOCAL_INCLUDES += [
-     "/docshell/base",
-     "/dom/base",
+@@ -134,6 +136,7 @@ LOCAL_INCLUDES += [
      "/dom/ipc",
      "/netwerk/base",
      "/netwerk/protocol/http",
@@ -823,16 +652,11 @@
  ]
  
  if CONFIG["MOZ_ENABLE_DBUS"]:
-     CXXFLAGS += CONFIG["MOZ_DBUS_CFLAGS"]
- 
- if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
-     CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
-     CXXFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"]
-diff --git a/uriloader/exthandler/unix/nsCommonRegistry.cpp b/uriloader/exthandler/unix/nsCommonRegistry.cpp
-new file mode 100644
+Index: firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.cpp
+===================================================================
 --- /dev/null
-+++ b/uriloader/exthandler/unix/nsCommonRegistry.cpp
-@@ -0,0 +1,53 @@
++++ firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.cpp
+@@ -0,0 +1,42 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* 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
@@ -845,51 +669,40 @@
 +#include "nsString.h"
 +#include "nsKDEUtils.h"
 +
-+/* static */ bool
-+nsCommonRegistry::HandlerExists(const char *aProtocolScheme)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDERegistry::HandlerExists( aProtocolScheme );
-+    return nsGNOMERegistry::HandlerExists( aProtocolScheme );
-+}
-+
-+/* static */ nsresult
-+nsCommonRegistry::LoadURL(nsIURI *aURL)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDERegistry::LoadURL( aURL );
-+    return nsGNOMERegistry::LoadURL( aURL );
++/* static */ bool nsCommonRegistry::HandlerExists(const char* aProtocolScheme) {
++  if (nsKDEUtils::kdeSupport())
++    return nsKDERegistry::HandlerExists(aProtocolScheme);
++  return nsGNOMERegistry::HandlerExists(aProtocolScheme);
 +}
 +
-+/* static */ void
-+nsCommonRegistry::GetAppDescForScheme(const nsACString& aScheme,
-+                                     nsAString& aDesc)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDERegistry::GetAppDescForScheme( aScheme, aDesc );
-+    return nsGNOMERegistry::GetAppDescForScheme( aScheme, aDesc );
++/* static */ nsresult nsCommonRegistry::LoadURL(nsIURI* aURL) {
++  if (nsKDEUtils::kdeSupport()) return nsKDERegistry::LoadURL(aURL);
++  return nsGNOMERegistry::LoadURL(aURL);
 +}
 +
-+
-+/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsCommonRegistry::GetFromExtension(const nsACString& aFileExt)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDERegistry::GetFromExtension( aFileExt );
-+    return nsGNOMERegistry::GetFromExtension( aFileExt );
++/* static */ void nsCommonRegistry::GetAppDescForScheme(
++    const nsACString& aScheme, nsAString& aDesc) {
++  if (nsKDEUtils::kdeSupport())
++    return nsKDERegistry::GetAppDescForScheme(aScheme, aDesc);
++  return nsGNOMERegistry::GetAppDescForScheme(aScheme, aDesc);
 +}
 +
 +/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsCommonRegistry::GetFromType(const nsACString& aMIMEType)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDERegistry::GetFromType( aMIMEType );
-+    return nsGNOMERegistry::GetFromType( aMIMEType );
++nsCommonRegistry::GetFromExtension(const nsACString& aFileExt) {
++  if (nsKDEUtils::kdeSupport())
++    return nsKDERegistry::GetFromExtension(aFileExt);
++  return nsGNOMERegistry::GetFromExtension(aFileExt);
 +}
-diff --git a/uriloader/exthandler/unix/nsCommonRegistry.h b/uriloader/exthandler/unix/nsCommonRegistry.h
-new file mode 100644
++
++/* static */ already_AddRefed<nsMIMEInfoBase> nsCommonRegistry::GetFromType(
++    const nsACString& aMIMEType) {
++  if (nsKDEUtils::kdeSupport()) return nsKDERegistry::GetFromType(aMIMEType);
++  return nsGNOMERegistry::GetFromType(aMIMEType);
++}
+Index: firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.h
+===================================================================
 --- /dev/null
-+++ b/uriloader/exthandler/unix/nsCommonRegistry.h
++++ firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.h
 @@ -0,0 +1,28 @@
 +/* 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
@@ -903,27 +716,27 @@
 +
 +class nsMIMEInfoBase;
 +
-+class nsCommonRegistry
-+{
++class nsCommonRegistry {
 + public:
-+  static bool HandlerExists(const char *aProtocolScheme);
++  static bool HandlerExists(const char* aProtocolScheme);
 +
-+  static nsresult LoadURL(nsIURI *aURL);
++  static nsresult LoadURL(nsIURI* aURL);
 +
-+  static void GetAppDescForScheme(const nsACString& aScheme,
-+                                  nsAString& aDesc);
++  static void GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc);
 +
-+  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
++  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(
++      const nsACString& aFileExt);
 +
-+  static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
++  static already_AddRefed<nsMIMEInfoBase> GetFromType(
++      const nsACString& aMIMEType);
 +};
 +
 +#endif
-diff --git a/uriloader/exthandler/unix/nsKDERegistry.cpp b/uriloader/exthandler/unix/nsKDERegistry.cpp
-new file mode 100644
+Index: firefox-115.0/uriloader/exthandler/unix/nsKDERegistry.cpp
+===================================================================
 --- /dev/null
-+++ b/uriloader/exthandler/unix/nsKDERegistry.cpp
-@@ -0,0 +1,89 @@
++++ firefox-115.0/uriloader/exthandler/unix/nsKDERegistry.cpp
+@@ -0,0 +1,75 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* 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
@@ -937,87 +750,73 @@
 +#include "nsMIMEInfoUnix.h"
 +#include "nsKDEUtils.h"
 +
-+/* static */ bool
-+nsKDERegistry::HandlerExists(const char *aProtocolScheme)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "HANDLEREXISTS"_ns );
-+    command.AppendElement( nsAutoCString( aProtocolScheme ));
-+    return nsKDEUtils::command( command );
++/* static */ bool nsKDERegistry::HandlerExists(const char* aProtocolScheme) {
++  nsTArray<nsCString> command;
++  command.AppendElement("HANDLEREXISTS"_ns);
++  command.AppendElement(nsAutoCString(aProtocolScheme));
++  return nsKDEUtils::command(command);
 +}
 +
-+/* static */ nsresult
-+nsKDERegistry::LoadURL(nsIURI *aURL)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "OPEN"_ns );
-+    nsCString url;
-+    aURL->GetSpec( url );
-+    command.AppendElement( url );
-+    bool rv = nsKDEUtils::command( command );
-+    if (!rv)
-+      return NS_ERROR_FAILURE;
++/* static */ nsresult nsKDERegistry::LoadURL(nsIURI* aURL) {
++  nsTArray<nsCString> command;
++  command.AppendElement("OPEN"_ns);
++  nsCString url;
++  aURL->GetSpec(url);
++  command.AppendElement(url);
++  bool rv = nsKDEUtils::command(command);
++  if (!rv) return NS_ERROR_FAILURE;
 +
-+    return NS_OK;
++  return NS_OK;
 +}
 +
-+/* static */ void
-+nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
-+                                     nsAString& aDesc)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "GETAPPDESCFORSCHEME"_ns );
-+    command.AppendElement( aScheme );
-+    nsTArray<nsCString> output;
-+    if( nsKDEUtils::command( command, &output ) && output.Length() == 1 )
-+        CopyUTF8toUTF16( output[ 0 ], aDesc );
++/* static */ void nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
++                                                     nsAString& aDesc) {
++  nsTArray<nsCString> command;
++  command.AppendElement("GETAPPDESCFORSCHEME"_ns);
++  command.AppendElement(aScheme);
++  nsTArray<nsCString> output;
++  if (nsKDEUtils::command(command, &output) && output.Length() == 1)
++    CopyUTF8toUTF16(output[0], aDesc);
 +}
 +
-+
-+/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsKDERegistry::GetFromExtension(const nsACString& aFileExt)
-+{
-+    NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "GETFROMEXTENSION"_ns );
-+    command.AppendElement( aFileExt );
-+    return GetFromHelper( command );
++/* static */ already_AddRefed<nsMIMEInfoBase> nsKDERegistry::GetFromExtension(
++    const nsACString& aFileExt) {
++  NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
++  nsTArray<nsCString> command;
++  command.AppendElement("GETFROMEXTENSION"_ns);
++  command.AppendElement(aFileExt);
++  return GetFromHelper(command);
 +}
 +
-+/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsKDERegistry::GetFromType(const nsACString& aMIMEType)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "GETFROMTYPE"_ns );
-+    command.AppendElement( aMIMEType );
-+    return GetFromHelper( command );
++/* static */ already_AddRefed<nsMIMEInfoBase> nsKDERegistry::GetFromType(
++    const nsACString& aMIMEType) {
++  nsTArray<nsCString> command;
++  command.AppendElement("GETFROMTYPE"_ns);
++  command.AppendElement(aMIMEType);
++  return GetFromHelper(command);
 +}
 +
-+/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsKDERegistry::GetFromHelper(const nsTArray<nsCString>& command)
-+{
-+    nsTArray<nsCString> output;
-+    if( nsKDEUtils::command( command, &output ) && output.Length() == 3 )
-+        {
-+        nsCString mimetype = output[ 0 ];
-+        RefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix( mimetype );
-+        NS_ENSURE_TRUE(mimeInfo, nullptr);
-+        nsCString description = output[ 1 ];
-+        mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
-+        nsCString handlerAppName = output[ 2 ];
-+        mozilla::StaticPrefs::browser_download_improvements_to_download_panel()
-+            ? mimeInfo->SetPreferredAction(nsIMIMEInfo::saveToDisk)
-+            : mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
-+        mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
-+        return mimeInfo.forget();
-+        }
-+    return nullptr;
++/* static */ already_AddRefed<nsMIMEInfoBase> nsKDERegistry::GetFromHelper(
++    const nsTArray<nsCString>& command) {
++  nsTArray<nsCString> output;
++  if (nsKDEUtils::command(command, &output) && output.Length() == 3) {
++    nsCString mimetype = output[0];
++    RefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(mimetype);
++    NS_ENSURE_TRUE(mimeInfo, nullptr);
++    nsCString description = output[1];
++    mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
++    nsCString handlerAppName = output[2];
++    mimeInfo->SetPreferredAction(nsIMIMEInfo::saveToDisk);
++    mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
++    return mimeInfo.forget();
++  }
++  return nullptr;
 +}
-diff --git a/uriloader/exthandler/unix/nsKDERegistry.h b/uriloader/exthandler/unix/nsKDERegistry.h
-new file mode 100644
+Index: firefox-115.0/uriloader/exthandler/unix/nsKDERegistry.h
+===================================================================
 --- /dev/null
-+++ b/uriloader/exthandler/unix/nsKDERegistry.h
-@@ -0,0 +1,34 @@
++++ firefox-115.0/uriloader/exthandler/unix/nsKDERegistry.h
+@@ -0,0 +1,35 @@
 +/* 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/. */
@@ -1030,36 +829,34 @@
 +#include "nsTArray.h"
 +
 +class nsMIMEInfoBase;
-+//class nsAutoCString;
-+//class nsCString;
++// class nsAutoCString;
++// class nsCString;
 +
-+class nsKDERegistry
-+{
++class nsKDERegistry {
 + public:
-+  static bool HandlerExists(const char *aProtocolScheme);
++  static bool HandlerExists(const char* aProtocolScheme);
 +
-+  static nsresult LoadURL(nsIURI *aURL);
++  static nsresult LoadURL(nsIURI* aURL);
 +
-+  static void GetAppDescForScheme(const nsACString& aScheme,
-+                                  nsAString& aDesc);
++  static void GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc);
 +
-+  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
++  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(
++      const nsACString& aFileExt);
 +
-+  static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
++  static already_AddRefed<nsMIMEInfoBase> GetFromType(
++      const nsACString& aMIMEType);
++
 + private:
-+  static already_AddRefed<nsMIMEInfoBase> GetFromHelper(const nsTArray<nsCString>& command);
-+
++  static already_AddRefed<nsMIMEInfoBase> GetFromHelper(
++      const nsTArray<nsCString>& command);
 +};
 +
-+#endif //nsKDERegistry_h__
-diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
---- a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
-+++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
-@@ -1,48 +1,51 @@
- /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-  *
-  * 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
++#endif  // nsKDERegistry_h__
+Index: firefox-115.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
+===================================================================
+--- firefox-115.0.orig/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
++++ firefox-115.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
+@@ -5,16 +5,19 @@
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  #include "nsMIMEInfoUnix.h"
@@ -1072,7 +869,7 @@
  #  include "nsDBusHandlerApp.h"
  #endif
 +#if defined(XP_UNIX) && !defined(XP_MACOSX)
-+#include "nsKDEUtils.h"
++#  include "nsKDEUtils.h"
 +#endif
  
  nsresult nsMIMEInfoUnix::LoadUriInternal(nsIURI* aURI) {
@@ -1081,14 +878,7 @@
  }
  
  NS_IMETHODIMP
- nsMIMEInfoUnix::GetHasDefaultHandler(bool* _retval) {
-   // if a default app is set, it means the application has been set from
-   // either /etc/mailcap or ${HOME}/.mailcap, in which case we don't want to
-   // give the GNOME answer.
-   if (GetDefaultApplication()) {
-     return nsMIMEInfoImpl::GetHasDefaultHandler(_retval);
-   }
- 
+@@ -29,15 +32,15 @@ nsMIMEInfoUnix::GetHasDefaultHandler(boo
    *_retval = false;
  
    if (mClass == eProtocolInfo) {
@@ -1107,33 +897,21 @@
        }
      }
      if (mimeInfo) *_retval = true;
-   }
- 
-   if (*_retval) return NS_OK;
- 
-   return NS_OK;
-@@ -54,16 +57,33 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi
-   // give the GNOME answer.
-   if (GetDefaultApplication()) {
-     return nsMIMEInfoImpl::LaunchDefaultWithFile(aFile);
-   }
- 
+@@ -59,6 +62,21 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi
    nsAutoCString nativePath;
    aFile->GetNativePath(nativePath);
  
-+  if( nsKDEUtils::kdeSupport()) {
++  if (nsKDEUtils::kdeSupport()) {
 +    bool supports;
-+    if( NS_SUCCEEDED( GetHasDefaultHandler( &supports )) && supports ) {
++    if (NS_SUCCEEDED(GetHasDefaultHandler(&supports)) && supports) {
 +      nsTArray<nsCString> command;
-+      command.AppendElement( "OPEN"_ns );
-+      command.AppendElement( nativePath );
-+      command.AppendElement( "MIMETYPE"_ns );
-+      command.AppendElement( mSchemeOrType );
-+      if( nsKDEUtils::command( command ))
-+        return NS_OK;
++      command.AppendElement("OPEN"_ns);
++      command.AppendElement(nativePath);
++      command.AppendElement("MIMETYPE"_ns);
++      command.AppendElement(mSchemeOrType);
++      if (nsKDEUtils::command(command)) return NS_OK;
 +    }
-+    if (!GetDefaultApplication())
-+      return NS_ERROR_FILE_NOT_FOUND;
++    if (!GetDefaultApplication()) return NS_ERROR_FILE_NOT_FOUND;
 +
 +    return LaunchWithIProcess(GetDefaultApplication(), nativePath);
 +  }
@@ -1141,20 +919,11 @@
    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
    if (!giovfs) {
      return NS_ERROR_FAILURE;
-   }
- 
-   // nsGIOMimeApp->Launch wants a URI string instead of local file
-   nsresult rv;
-   nsCOMPtr<nsIIOService> ioservice =
-diff --git a/uriloader/exthandler/unix/nsOSHelperAppService.cpp b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
---- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
-+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
-@@ -5,17 +5,17 @@
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- 
- #include <sys/types.h>
- #include <sys/stat.h>
- 
+Index: firefox-115.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+===================================================================
+--- firefox-115.0.orig/uriloader/exthandler/unix/nsOSHelperAppService.cpp
++++ firefox-115.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+@@ -10,7 +10,7 @@
  #include "nsOSHelperAppService.h"
  #include "nsMIMEInfoUnix.h"
  #ifdef MOZ_WIDGET_GTK
@@ -1163,17 +932,7 @@
  #  ifdef MOZ_BUILD_APP_IS_BROWSER
  #    include "nsIToolkitShellService.h"
  #    include "nsIGNOMEShellService.h"
- #  endif
- #endif
- #include "nsISupports.h"
- #include "nsString.h"
- #include "nsReadableUtils.h"
-@@ -1102,17 +1102,17 @@ nsresult nsOSHelperAppService::GetHandle
- 
- nsresult nsOSHelperAppService::OSProtocolHandlerExists(
-     const char* aProtocolScheme, bool* aHandlerExists) {
-   nsresult rv = NS_OK;
- 
+@@ -1106,7 +1106,7 @@ nsresult nsOSHelperAppService::OSProtoco
    if (!XRE_IsContentProcess()) {
  #ifdef MOZ_WIDGET_GTK
      // Check the GNOME registry for a protocol handler
@@ -1182,17 +941,7 @@
  #else
      *aHandlerExists = false;
  #endif
-   } else {
-     *aHandlerExists = false;
-     nsCOMPtr<nsIHandlerService> handlerSvc =
-         do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
-     if (NS_SUCCEEDED(rv) && handlerSvc) {
-@@ -1122,17 +1122,17 @@ nsresult nsOSHelperAppService::OSProtoco
-   }
- 
-   return rv;
- }
- 
+@@ -1126,7 +1126,7 @@ nsresult nsOSHelperAppService::OSProtoco
  NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(
      const nsACString& aScheme, nsAString& _retval) {
  #ifdef MOZ_WIDGET_GTK
@@ -1201,17 +950,7 @@
    return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK;
  #else
    return NS_ERROR_NOT_AVAILABLE;
- #endif
- }
- 
- NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(
-     const nsACString& aScheme, bool* _retval) {
-@@ -1227,17 +1227,17 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel
-   nsresult rv =
-       LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt), majorType,
-                                minorType, mime_types_description, true);
- 
-   if (NS_FAILED(rv) || majorType.IsEmpty()) {
+@@ -1231,7 +1231,7 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel
  #ifdef MOZ_WIDGET_GTK
      LOG("Looking in GNOME registry\n");
      RefPtr<nsMIMEInfoBase> gnomeInfo =
@@ -1220,17 +959,7 @@
      if (gnomeInfo) {
        LOG("Got MIMEInfo from GNOME registry\n");
        return gnomeInfo.forget();
-     }
- #endif
- 
-     rv = LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt), majorType,
-                                   minorType, mime_types_description, false);
-@@ -1342,17 +1342,17 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel
- 
-   // Now look up our extensions
-   nsAutoString extensions, mime_types_description;
-   LookUpExtensionsAndDescription(majorType, minorType, extensions,
-                                  mime_types_description);
+@@ -1344,7 +1344,7 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel
  
  #ifdef MOZ_WIDGET_GTK
    if (handler.IsEmpty()) {
@@ -1239,20 +968,11 @@
      if (gnomeInfo) {
        LOG("Got MIMEInfo from GNOME registry without extensions; setting them "
            "to %s\n",
-           NS_LossyConvertUTF16toASCII(extensions).get());
- 
-       NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?");
-       gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions));
-       return gnomeInfo.forget();
-diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
---- a/widget/gtk/moz.build
-+++ b/widget/gtk/moz.build
-@@ -142,16 +142,17 @@ FINAL_LIBRARY = "xul"
- 
- LOCAL_INCLUDES += [
-     "/layout/base",
-     "/layout/forms",
-     "/layout/generic",
+Index: firefox-115.0/widget/gtk/moz.build
+===================================================================
+--- firefox-115.0.orig/widget/gtk/moz.build
++++ firefox-115.0/widget/gtk/moz.build
+@@ -149,6 +149,7 @@ LOCAL_INCLUDES += [
      "/layout/xul",
      "/other-licenses/atk-1.0",
      "/third_party/cups/include",
@@ -1260,19 +980,11 @@
      "/widget",
      "/widget/headless",
  ]
- 
- if CONFIG["MOZ_X11"] or CONFIG["MOZ_WAYLAND"]:
-     LOCAL_INCLUDES += [
-         "/widget/x11",
-     ]
-diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
---- a/widget/gtk/nsFilePicker.cpp
-+++ b/widget/gtk/nsFilePicker.cpp
-@@ -1,15 +1,16 @@
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/. */
+Index: firefox-115.0/widget/gtk/nsFilePicker.cpp
+===================================================================
+--- firefox-115.0.orig/widget/gtk/nsFilePicker.cpp
++++ firefox-115.0/widget/gtk/nsFilePicker.cpp
+@@ -5,6 +5,7 @@
  
  #include <dlfcn.h>
  #include <gtk/gtk.h>
@@ -1280,17 +992,7 @@
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
- 
- #include "mozilla/Types.h"
- #include "nsGtkUtils.h"
- #include "nsIFileURL.h"
- #include "nsIGIOService.h"
-@@ -23,16 +24,18 @@
- #include "nsArrayEnumerator.h"
- #include "nsEnumeratorUtils.h"
- #include "nsNetUtil.h"
- #include "nsReadableUtils.h"
- #include "MozContainer.h"
+@@ -28,6 +29,8 @@
  #include "WidgetUtilsGtk.h"
  
  #include "nsFilePicker.h"
@@ -1299,60 +1001,41 @@
  
  #undef LOG
  #ifdef MOZ_LOGGING
- #  include "mozilla/Logging.h"
- #  include "nsTArray.h"
- #  include "Units.h"
- extern mozilla::LazyLogModule gWidgetLog;
- #  define LOG(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args)
-@@ -237,17 +240,19 @@ nsFilePicker::AppendFilters(int32_t aFil
-   mAllowURLs = !!(aFilterMask & filterAllowURLs);
-   return nsBaseFilePicker::AppendFilters(aFilterMask);
- }
- 
- NS_IMETHODIMP
+@@ -242,7 +245,8 @@ NS_IMETHODIMP
  nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) {
    if (aFilter.EqualsLiteral("..apps")) {
      // No platform specific thing we can do here, really....
 -    return NS_OK;
 +    // Unless it's KDE.
-+    if( mMode != modeOpen || !nsKDEUtils::kdeSupport())
-+      return NS_OK;
++    if (mMode != modeOpen || !nsKDEUtils::kdeSupport()) return NS_OK;
    }
  
    nsAutoCString filter, name;
-   CopyUTF16toUTF8(aFilter, filter);
-   CopyUTF16toUTF8(aTitle, name);
- 
-   mFilters.AppendElement(filter);
-   mFilterNames.AppendElement(name);
-@@ -347,16 +352,39 @@ nsresult nsFilePicker::Show(nsIFilePicke
-   return NS_OK;
- }
- 
- NS_IMETHODIMP
- nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
+@@ -352,6 +356,31 @@ nsFilePicker::Open(nsIFilePickerShownCal
    // Can't show two dialogs concurrently with the same filepicker
    if (mRunning) return NS_ERROR_NOT_AVAILABLE;
  
 +  // KDE file picker is not handled via callback
-+  if( nsKDEUtils::kdeSupport()) {
++  if (nsKDEUtils::kdeSupport()) {
 +    mCallback = aCallback;
 +    mRunning = true;
 +    NS_ADDREF_THIS();
-+    g_idle_add([](gpointer data) -> gboolean {
-+      nsFilePicker* queuedPicker = (nsFilePicker*) data;
-+      nsIFilePicker::ResultCode result;
-+      queuedPicker->kdeFileDialog(&result);
-+      if (queuedPicker->mCallback) {
-+        queuedPicker->mCallback->Done(result);
-+        queuedPicker->mCallback = nullptr;
-+      } else {
-+        queuedPicker->mResult = result;
-+      }
-+      queuedPicker->mRunning = false;
-+      NS_RELEASE(queuedPicker);
-+      return G_SOURCE_REMOVE;
-+    }, this);
++    g_idle_add(
++        [](gpointer data) -> gboolean {
++          nsFilePicker* queuedPicker = (nsFilePicker*)data;
++          nsIFilePicker::ResultCode result;
++          queuedPicker->kdeFileDialog(&result);
++          if (queuedPicker->mCallback) {
++            queuedPicker->mCallback->Done(result);
++            queuedPicker->mCallback = nullptr;
++          } else {
++            queuedPicker->mResult = result;
++          }
++          queuedPicker->mRunning = false;
++          NS_RELEASE(queuedPicker);
++          return G_SOURCE_REMOVE;
++        },
++        this);
 +
 +    return NS_OK;
 +  }
@@ -1360,86 +1043,68 @@
    NS_ConvertUTF16toUTF8 title(mTitle);
  
    GtkWindow* parent_widget =
-       GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
- 
-   GtkFileChooserAction action = GetGtkFileChooserAction(mMode);
- 
-   const gchar* accept_button;
-@@ -628,16 +656,244 @@ void nsFilePicker::Done(void* file_choos
-     mCallback->Done(result);
-     mCallback = nullptr;
-   } else {
-     mResult = result;
-   }
+@@ -633,6 +662,205 @@ void nsFilePicker::Done(void* file_choos
    NS_RELEASE_THIS();
  }
  
-+nsCString nsFilePicker::kdeMakeFilter( int index )
-+    {
-+    nsCString buf = mFilters[ index ];
-+    for( PRUint32 i = 0;
-+         i < buf.Length();
-+         ++i )
-+        if( buf[ i ] == ';' ) // KDE separates just using spaces
-+            buf.SetCharAt( ' ', i );
-+    if (!mFilterNames[index].IsEmpty())
-+        {
-+        buf += "|";
-+        buf += mFilterNames[index].get();
-+        }
-+    return buf;
-+    }
++nsCString nsFilePicker::kdeMakeFilter(int index) {
++  nsCString buf = mFilters[index];
++  for (PRUint32 i = 0; i < buf.Length(); ++i)
++    if (buf[i] == ';')  // KDE separates just using spaces
++      buf.SetCharAt(' ', i);
++  if (!mFilterNames[index].IsEmpty()) {
++    buf += "|";
++    buf += mFilterNames[index].get();
++  }
++  return buf;
++}
 +
-+static PRInt32 windowToXid( nsIWidget* widget )
-+    {
-+    GtkWindow *parent_widget = GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
-+    GdkWindow* gdk_window = gtk_widget_get_window( gtk_widget_get_toplevel( GTK_WIDGET( parent_widget )));
-+    return GDK_WINDOW_XID( gdk_window );
-+    }
++static PRInt32 windowToXid(nsIWidget* widget) {
++  GtkWindow* parent_widget =
++      GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
++  GdkWindow* gdk_window =
++      gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(parent_widget)));
++  return GDK_WINDOW_XID(gdk_window);
++}
 +
-+NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode *aReturn)
-+    {
-+    NS_ENSURE_ARG_POINTER(aReturn);
++NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode* aReturn) {
++  NS_ENSURE_ARG_POINTER(aReturn);
 +
-+    if( mMode == modeOpen && mFilters.Length() == 1 && mFilters[ 0 ].EqualsLiteral( "..apps" ))
-+        return kdeAppsDialog( aReturn );
-+
-+    nsCString title;
-+    title.Adopt(ToNewUTF8String(mTitle));
++  if (mMode == modeOpen && mFilters.Length() == 1 &&
++      mFilters[0].EqualsLiteral("..apps"))
++    return kdeAppsDialog(aReturn);
 +
-+    const char* arg = NULL;
-+    if( mAllowURLs )
-+        {
-+        switch( mMode )
-+            {
-+            case nsIFilePicker::modeOpen:
-+            case nsIFilePicker::modeOpenMultiple:
-+                arg = "GETOPENURL";
-+                break;
-+            case nsIFilePicker::modeSave:
-+                arg = "GETSAVEURL";
-+                break;
-+            case nsIFilePicker::modeGetFolder:
-+                arg = "GETDIRECTORYURL";
-+                break;
-+            }
-+        }
-+    else
-+        {
-+        switch( mMode )
-+            {
-+            case nsIFilePicker::modeOpen:
-+            case nsIFilePicker::modeOpenMultiple:
-+                arg = "GETOPENFILENAME";
-+                break;
-+            case nsIFilePicker::modeSave:
-+                arg = "GETSAVEFILENAME";
-+                break;
-+            case nsIFilePicker::modeGetFolder:
-+                arg = "GETDIRECTORYFILENAME";
-+                break;
-+            }
-+        }
++  nsCString title;
++  title.Adopt(ToNewUTF8String(mTitle));
++
++  const char* arg = NULL;
++  if (mAllowURLs) {
++    switch (mMode) {
++      case nsIFilePicker::modeOpen:
++      case nsIFilePicker::modeOpenMultiple:
++        arg = "GETOPENURL";
++        break;
++      case nsIFilePicker::modeSave:
++        arg = "GETSAVEURL";
++        break;
++      case nsIFilePicker::modeGetFolder:
++        arg = "GETDIRECTORYURL";
++        break;
++    }
++  } else {
++    switch (mMode) {
++      case nsIFilePicker::modeOpen:
++      case nsIFilePicker::modeOpenMultiple:
++        arg = "GETOPENFILENAME";
++        break;
++      case nsIFilePicker::modeSave:
++        arg = "GETSAVEFILENAME";
++        break;
++      case nsIFilePicker::modeGetFolder:
++        arg = "GETDIRECTORYFILENAME";
++        break;
++    }
++  }
 +
 +  nsAutoCString directory;
 +  if (mDisplayDirectory) {
@@ -1448,203 +1113,164 @@
 +    mPrevDisplayDirectory->GetNativePath(directory);
 +  }
 +
-+    nsAutoCString startdir;
++  nsAutoCString startdir;
 +  if (!directory.IsEmpty()) {
 +    startdir = directory;
 +  }
 +  if (mMode == nsIFilePicker::modeSave) {
-+    if( !startdir.IsEmpty())
-+      {
++    if (!startdir.IsEmpty()) {
 +      startdir += "/";
 +      startdir += ToNewUTF8String(mDefault);
-+      }
-+    else
++    } else
 +      startdir = ToNewUTF8String(mDefault);
 +  }
 +
-+    nsAutoCString filters;
-+    PRInt32 count = mFilters.Length();
-+    if( count == 0 ) //just in case
-+        filters = "*";
-+    else
-+        {
-+        filters = kdeMakeFilter( 0 );
-+        for (PRInt32 i = 1; i < count; ++i)
-+            {
-+            filters += "\n";
-+            filters += kdeMakeFilter( i );
-+            }
-+        }
-+
-+    nsTArray<nsCString> command;
-+    command.AppendElement( nsAutoCString( arg ));
-+    command.AppendElement( startdir );
-+    if( mMode != nsIFilePicker::modeGetFolder )
-+        {
-+        command.AppendElement( filters );
-+        nsAutoCString selected;
-+        selected.AppendInt( mSelectedType );
-+        command.AppendElement( selected );
-+        }
-+    command.AppendElement( title );
-+    if( mMode == nsIFilePicker::modeOpenMultiple )
-+        command.AppendElement( "MULTIPLE"_ns );
-+    if( PRInt32 xid = windowToXid( mParentWidget ))
-+        {
-+        command.AppendElement( "PARENT"_ns );
-+        nsAutoCString parent;
-+        parent.AppendInt( xid );
-+        command.AppendElement( parent );
-+        }
-+
-+    nsTArray<nsCString> output;
-+    if( nsKDEUtils::commandBlockUi( command, GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), &output ))
-+        {
-+        *aReturn = nsIFilePicker::returnOK;
-+        mFiles.Clear();
-+        if( mMode != nsIFilePicker::modeGetFolder )
-+            {
-+            mSelectedType = atoi( output[ 0 ].get());
-+            output.RemoveElementAt( 0 );
-+            }
-+        if (mMode == nsIFilePicker::modeOpenMultiple)
-+            {
-+            mFileURL.Truncate();
-+            PRUint32 count = output.Length();
-+            for( PRUint32 i = 0;
-+                 i < count;
-+                 ++i )
-+                {
-+                nsCOMPtr<nsIFile> localfile;
-+                nsresult rv = NS_NewNativeLocalFile( output[ i ],
-+                                      PR_FALSE,
-+                                      getter_AddRefs(localfile));
-+                if (NS_SUCCEEDED(rv))
-+                    mFiles.AppendObject(localfile);
-+                }
-+            }
-+        else
-+            {
-+            if( output.Length() == 0 )
-+                mFileURL = nsCString();
-+            else if( mAllowURLs )
-+                mFileURL = output[ 0 ];
-+            else // GetFile() actually requires it to be url even for local files :-/
-+                {
-+                nsCOMPtr<nsIFile> localfile;
-+                nsresult rv = NS_NewNativeLocalFile( output[ 0 ],
-+                                   PR_FALSE,
-+                                   getter_AddRefs(localfile));
-+                if (NS_SUCCEEDED(rv))
-+                  rv = net_GetURLSpecFromActualFile(localfile, mFileURL);
-+                }
-+            }
-+  // Remember last used directory.
-+  nsCOMPtr<nsIFile> file;
-+  GetFile(getter_AddRefs(file));
-+  if (file) {
-+    nsCOMPtr<nsIFile> dir;
-+    file->GetParent(getter_AddRefs(dir));
-+    nsCOMPtr<nsIFile> localDir(do_QueryInterface(dir));
-+    if (localDir) {
-+      localDir.swap(mPrevDisplayDirectory);
++  nsAutoCString filters;
++  PRInt32 count = mFilters.Length();
++  if (count == 0)  // just in case
++    filters = "*";
++  else {
++    filters = kdeMakeFilter(0);
++    for (PRInt32 i = 1; i < count; ++i) {
++      filters += "\n";
++      filters += kdeMakeFilter(i);
 +    }
 +  }
-+        if (mMode == nsIFilePicker::modeSave)
-+            {
-+            nsCOMPtr<nsIFile> file;
-+            GetFile(getter_AddRefs(file));
-+            if (file)
-+                {
-+                bool exists = false;
-+                file->Exists(&exists);
-+                if (exists) // TODO do overwrite check in the helper app
-+                    *aReturn = nsIFilePicker::returnReplace;
-+                }
-+            }
-+        }
-+    else
-+        {
-+        *aReturn = nsIFilePicker::returnCancel;
-+        }
-+    return NS_OK;
-+    }
 +
-+
-+NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode *aReturn)
-+    {
-+    NS_ENSURE_ARG_POINTER(aReturn);
++  nsTArray<nsCString> command;
++  command.AppendElement(nsAutoCString(arg));
++  command.AppendElement(startdir);
++  if (mMode != nsIFilePicker::modeGetFolder) {
++    command.AppendElement(filters);
++    nsAutoCString selected;
++    selected.AppendInt(mSelectedType);
++    command.AppendElement(selected);
++  }
++  command.AppendElement(title);
++  if (mMode == nsIFilePicker::modeOpenMultiple)
++    command.AppendElement("MULTIPLE"_ns);
++  if (PRInt32 xid = windowToXid(mParentWidget)) {
++    command.AppendElement("PARENT"_ns);
++    nsAutoCString parent;
++    parent.AppendInt(xid);
++    command.AppendElement(parent);
++  }
 +
-+    nsCString title;
-+    title.Adopt(ToNewUTF8String(mTitle));
++  nsTArray<nsCString> output;
++  if (nsKDEUtils::commandBlockUi(
++          command,
++          GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)),
++          &output)) {
++    *aReturn = nsIFilePicker::returnOK;
++    mFiles.Clear();
++    if (mMode != nsIFilePicker::modeGetFolder) {
++      mSelectedType = atoi(output[0].get());
++      output.RemoveElementAt(0);
++    }
++    if (mMode == nsIFilePicker::modeOpenMultiple) {
++      mFileURL.Truncate();
++      PRUint32 count = output.Length();
++      for (PRUint32 i = 0; i < count; ++i) {
++        nsCOMPtr<nsIFile> localfile;
++        nsresult rv = NS_NewNativeLocalFile(output[i], PR_FALSE,
++                                            getter_AddRefs(localfile));
++        if (NS_SUCCEEDED(rv)) mFiles.AppendObject(localfile);
++      }
++    } else {
++      if (output.Length() == 0)
++        mFileURL = nsCString();
++      else if (mAllowURLs)
++        mFileURL = output[0];
++      else  // GetFile() actually requires it to be url even for local files :-/
++      {
++        nsCOMPtr<nsIFile> localfile;
++        nsresult rv = NS_NewNativeLocalFile(output[0], PR_FALSE,
++                                            getter_AddRefs(localfile));
++        if (NS_SUCCEEDED(rv))
++          rv = net_GetURLSpecFromActualFile(localfile, mFileURL);
++      }
++    }
++    // Remember last used directory.
++    nsCOMPtr<nsIFile> file;
++    GetFile(getter_AddRefs(file));
++    if (file) {
++      nsCOMPtr<nsIFile> dir;
++      file->GetParent(getter_AddRefs(dir));
++      nsCOMPtr<nsIFile> localDir(dir);
++      if (localDir) {
++        localDir.swap(mPrevDisplayDirectory);
++      }
++    }
++    if (mMode == nsIFilePicker::modeSave) {
++      nsCOMPtr<nsIFile> file;
++      GetFile(getter_AddRefs(file));
++      if (file) {
++        bool exists = false;
++        file->Exists(&exists);
++        if (exists)  // TODO do overwrite check in the helper app
++          *aReturn = nsIFilePicker::returnReplace;
++      }
++    }
++  } else {
++    *aReturn = nsIFilePicker::returnCancel;
++  }
++  return NS_OK;
++}
 +
-+    nsTArray<nsCString> command;
-+    command.AppendElement( "APPSDIALOG"_ns );
-+    command.AppendElement( title );
-+    if( PRInt32 xid = windowToXid( mParentWidget ))
-+        {
-+        command.AppendElement( "PARENT"_ns );
-+        nsAutoCString parent;
-+        parent.AppendInt( xid );
-+        command.AppendElement( parent );
-+        }
++NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode* aReturn) {
++  NS_ENSURE_ARG_POINTER(aReturn);
++
++  nsCString title;
++  title.Adopt(ToNewUTF8String(mTitle));
 +
-+    nsTArray<nsCString> output;
-+    if( nsKDEUtils::commandBlockUi( command, GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), &output ))
-+        {
-+        *aReturn = nsIFilePicker::returnOK;
-+        mFileURL = output.Length() > 0 ? output[ 0 ] : nsCString();
-+        }
-+    else
-+        {
-+        *aReturn = nsIFilePicker::returnCancel;
-+        }
-+    return NS_OK;
-+    }
++  nsTArray<nsCString> command;
++  command.AppendElement("APPSDIALOG"_ns);
++  command.AppendElement(title);
++  if (PRInt32 xid = windowToXid(mParentWidget)) {
++    command.AppendElement("PARENT"_ns);
++    nsAutoCString parent;
++    parent.AppendInt(xid);
++    command.AppendElement(parent);
++  }
++
++  nsTArray<nsCString> output;
++  if (nsKDEUtils::commandBlockUi(
++          command,
++          GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)),
++          &output)) {
++    *aReturn = nsIFilePicker::returnOK;
++    mFileURL = output.Length() > 0 ? output[0] : nsCString();
++  } else {
++    *aReturn = nsIFilePicker::returnCancel;
++  }
++  return NS_OK;
++}
 +
  // All below functions available as of GTK 3.20+
  void* nsFilePicker::GtkFileChooserNew(const gchar* title, GtkWindow* parent,
                                        GtkFileChooserAction action,
-                                       const gchar* accept_label) {
-   static auto sGtkFileChooserNativeNewPtr =
-       (void* (*)(const gchar*, GtkWindow*, GtkFileChooserAction, const gchar*,
-                  const gchar*))dlsym(RTLD_DEFAULT,
-                                      "gtk_file_chooser_native_new");
-diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h
---- a/widget/gtk/nsFilePicker.h
-+++ b/widget/gtk/nsFilePicker.h
-@@ -69,16 +69,22 @@ class nsFilePicker : public nsBaseFilePi
-   nsString mDefaultExtension;
- 
-   nsTArray<nsCString> mFilters;
-   nsTArray<nsCString> mFilterNames;
- 
+Index: firefox-115.0/widget/gtk/nsFilePicker.h
+===================================================================
+--- firefox-115.0.orig/widget/gtk/nsFilePicker.h
++++ firefox-115.0/widget/gtk/nsFilePicker.h
+@@ -74,6 +74,12 @@ class nsFilePicker : public nsBaseFilePi
   private:
    static nsIFile* mPrevDisplayDirectory;
  
 +  bool kdeRunning();
 +  bool getKdeRunning();
-+  NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode *aReturn);
-+  NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode *aReturn);
-+  nsCString kdeMakeFilter( int index );
++  NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode* aReturn);
++  NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode* aReturn);
++  nsCString kdeMakeFilter(int index);
 +
    void* GtkFileChooserNew(const gchar* title, GtkWindow* parent,
                            GtkFileChooserAction action,
                            const gchar* accept_label);
-   void GtkFileChooserShow(void* file_chooser);
-   void GtkFileChooserDestroy(void* file_chooser);
-   void GtkFileChooserSetModal(void* file_chooser, GtkWindow* parent_widget,
-                               gboolean modal);
- 
-diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp
---- a/xpcom/components/ManifestParser.cpp
-+++ b/xpcom/components/ManifestParser.cpp
-@@ -38,16 +38,17 @@
- #include "nsTextFormatter.h"
- #include "nsVersionComparator.h"
- #include "nsXPCOMCIDInternal.h"
- 
- #include "nsIConsoleService.h"
+Index: firefox-115.0/xpcom/components/ManifestParser.cpp
+===================================================================
+--- firefox-115.0.orig/xpcom/components/ManifestParser.cpp
++++ firefox-115.0/xpcom/components/ManifestParser.cpp
+@@ -43,6 +43,7 @@
  #include "nsIScriptError.h"
  #include "nsIXULAppInfo.h"
  #include "nsIXULRuntime.h"
@@ -1652,17 +1278,7 @@
  
  using namespace mozilla;
  
- struct ManifestDirective {
-   const char* directive;
-   int argc;
- 
-   bool ischrome;
-@@ -389,16 +390,17 @@ void ParseManifest(NSLocationType aType,
-   constexpr auto kRemoteEnabled = u"remoteenabled"_ns;
-   constexpr auto kRemoteRequired = u"remoterequired"_ns;
-   constexpr auto kApplication = u"application"_ns;
-   constexpr auto kAppVersion = u"appversion"_ns;
-   constexpr auto kGeckoVersion = u"platformversion"_ns;
+@@ -394,6 +395,7 @@ void ParseManifest(NSLocationType aType,
    constexpr auto kOs = u"os"_ns;
    constexpr auto kOsVersion = u"osversion"_ns;
    constexpr auto kABI = u"abi"_ns;
@@ -1670,17 +1286,7 @@
    constexpr auto kProcess = u"process"_ns;
  #if defined(MOZ_WIDGET_ANDROID)
    constexpr auto kTablet = u"tablet"_ns;
- #endif
-   // You might expect this to be guarded by MOZ_BACKGROUNDTASKS, but it's not
-   // possible to have conditional manifest contents, so we need to recognize and
-   // discard these tokens even when MOZ_BACKGROUNDTASKS is not set.
-   constexpr auto kBackgroundTask = u"backgroundtask"_ns;
-@@ -448,39 +450,44 @@ void ParseManifest(NSLocationType aType,
-         CopyUTF8toUTF16(s, abi);
-         abi.Insert(char16_t('_'), 0);
-         abi.Insert(osTarget, 0);
-       }
-     }
+@@ -453,6 +455,7 @@ void ParseManifest(NSLocationType aType,
    }
  
    nsAutoString osVersion;
@@ -1688,8 +1294,7 @@
  #if defined(XP_WIN)
  #  pragma warning(push)
  #  pragma warning(disable : 4996)  // VC12+ deprecates GetVersionEx
-   OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};
-   if (GetVersionEx(&info)) {
+@@ -461,14 +464,17 @@ void ParseManifest(NSLocationType aType,
      nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", info.dwMajorVersion,
                                info.dwMinorVersion);
    }
@@ -1707,7 +1312,7 @@
  #elif defined(MOZ_WIDGET_ANDROID)
    bool isTablet = false;
    if (jni::IsAvailable()) {
-     jni::String::LocalRef release = java::sdk::Build::VERSION::RELEASE();
+@@ -476,6 +482,7 @@ void ParseManifest(NSLocationType aType,
      osVersion.Assign(release->ToString());
      isTablet = java::GeckoAppShell::IsTablet();
    }
@@ -1715,17 +1320,7 @@
  #endif
  
    if (XRE_IsContentProcess()) {
-     process = kContent;
-   } else {
-     process = kMain;
-   }
- 
-@@ -571,25 +578,27 @@ void ParseManifest(NSLocationType aType,
-     // When in background task mode, default to not registering
-     // category directivies unless backgroundtask=1 is specified.
-     TriState stBackgroundTask = (BackgroundTasks::IsBackgroundTaskMode() &&
-                                  strcmp("category", directive->directive) == 0)
-                                     ? eBad
+@@ -576,6 +583,7 @@ void ParseManifest(NSLocationType aType,
                                      : eUnspecified;
  #endif
      int flags = 0;
@@ -1733,9 +1328,7 @@
  
      while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
             ok) {
-       ToLowerCase(token);
-       NS_ConvertASCIItoUTF16 wtoken(token);
- 
+@@ -585,6 +593,7 @@ void ParseManifest(NSLocationType aType,
        if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
            CheckOsFlag(kOs, wtoken, osTarget, stOs) ||
            CheckStringFlag(kABI, wtoken, abi, stABI) ||
@@ -1743,39 +1336,19 @@
            CheckStringFlag(kProcess, wtoken, process, stProcess) ||
            CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
            CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
-           CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion,
-                            stGeckoVersion)) {
-         continue;
-       }
- 
-@@ -638,17 +647,17 @@ void ParseManifest(NSLocationType aType,
-       }
- 
-       LogMessageWithContext(
-           aFile, line, "Unrecognized chrome manifest modifier '%s'.", token);
-       ok = false;
-     }
+@@ -644,6 +653,7 @@ void ParseManifest(NSLocationType aType,
  
      if (!ok || stApp == eBad || stAppVersion == eBad ||
--        stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad ||
-+        stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad || stDesktop == eBad ||
+         stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad ||
++        stDesktop == eBad ||
  #ifdef MOZ_WIDGET_ANDROID
          stTablet == eBad ||
  #endif
- #ifdef MOZ_BACKGROUNDTASKS
-         stBackgroundTask == eBad ||
- #endif
-         stABI == eBad || stProcess == eBad) {
-       continue;
-diff --git a/xpcom/components/moz.build b/xpcom/components/moz.build
---- a/xpcom/components/moz.build
-+++ b/xpcom/components/moz.build
-@@ -66,16 +66,17 @@ LOCAL_INCLUDES += [
-     "!..",
-     "../base",
-     "../build",
-     "../ds",
-     "/chrome",
+Index: firefox-115.0/xpcom/components/moz.build
+===================================================================
+--- firefox-115.0.orig/xpcom/components/moz.build
++++ firefox-115.0/xpcom/components/moz.build
+@@ -71,6 +71,7 @@ LOCAL_INCLUDES += [
      "/js/xpconnect/loader",
      "/layout/build",
      "/modules/libjar",
@@ -1783,20 +1356,11 @@
  ]
  
  if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
-     CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
-     if CONFIG["MOZ_ENABLE_DBUS"]:
-         CXXFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"]
- 
- include("/ipc/chromium/chromium-config.mozbuild")
-diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp
---- a/xpcom/io/nsLocalFileUnix.cpp
-+++ b/xpcom/io/nsLocalFileUnix.cpp
-@@ -46,16 +46,17 @@
- #include "nsString.h"
- #include "nsIDirectoryEnumerator.h"
- #include "nsSimpleEnumerator.h"
- #include "private/pprio.h"
- #include "prlink.h"
+Index: firefox-115.0/xpcom/io/nsLocalFileUnix.cpp
+===================================================================
+--- firefox-115.0.orig/xpcom/io/nsLocalFileUnix.cpp
++++ firefox-115.0/xpcom/io/nsLocalFileUnix.cpp
+@@ -51,6 +51,7 @@
  
  #ifdef MOZ_WIDGET_GTK
  #  include "nsIGIOService.h"
@@ -1804,64 +1368,38 @@
  #endif
  
  #ifdef MOZ_WIDGET_COCOA
- #  include <Carbon/Carbon.h>
- #  include "CocoaFileUtils.h"
- #  include "prmem.h"
- #  include "plbase64.h"
- 
-@@ -2167,20 +2168,29 @@ nsLocalFile::SetPersistentDescriptor(con
- 
- NS_IMETHODIMP
- nsLocalFile::Reveal() {
-   if (!FilePreferences::IsAllowedPath(mPath)) {
-     return NS_ERROR_FILE_ACCESS_DENIED;
+@@ -2172,10 +2173,18 @@ nsLocalFile::Reveal() {
    }
  
  #ifdef MOZ_WIDGET_GTK
 +  nsAutoCString url;
    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 -  if (!giovfs) {
+-    return NS_ERROR_FAILURE;
 +  url = mPath;
-+  if(nsKDEUtils::kdeSupport()) {
++  if (nsKDEUtils::kdeSupport()) {
 +    nsTArray<nsCString> command;
-+    command.AppendElement( "REVEAL"_ns );
-+    command.AppendElement( mPath );
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
-+  }
++    command.AppendElement("REVEAL"_ns);
++    command.AppendElement(mPath);
++    return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE;
+   }
 +
-+  if (!giovfs)
-     return NS_ERROR_FAILURE;
--  }
++  if (!giovfs) return NS_ERROR_FAILURE;
 +
    return giovfs->RevealFile(this);
  #elif defined(MOZ_WIDGET_COCOA)
    CFURLRef url;
-   if (NS_SUCCEEDED(GetCFURL(&url))) {
-     nsresult rv = CocoaFileUtils::RevealFileInFinder(url);
-     ::CFRelease(url);
-     return rv;
-   }
-@@ -2192,16 +2202,23 @@ nsLocalFile::Reveal() {
- 
- NS_IMETHODIMP
- nsLocalFile::Launch() {
-   if (!FilePreferences::IsAllowedPath(mPath)) {
-     return NS_ERROR_FILE_ACCESS_DENIED;
+@@ -2197,6 +2206,13 @@ nsLocalFile::Launch() {
    }
  
  #ifdef MOZ_WIDGET_GTK
-+  if( nsKDEUtils::kdeSupport()) {
++  if (nsKDEUtils::kdeSupport()) {
 +    nsTArray<nsCString> command;
-+    command.AppendElement( "OPEN"_ns );
-+    command.AppendElement( mPath );
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
++    command.AppendElement("OPEN"_ns);
++    command.AppendElement(mPath);
++    return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE;
 +  }
 +
    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
    if (!giovfs) {
      return NS_ERROR_FAILURE;
-   }
- 
-   return giovfs->LaunchFile(mPath);
- #elif defined(MOZ_WIDGET_ANDROID)
-   // Not supported on GeckoView