--- mozilla/chrome/src/Makefile.in.sav	2009-11-05 20:08:57.000000000 +0100
+++ mozilla/chrome/src/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -86,6 +86,7 @@ EXTRA_DSO_LDOPTS = \
 
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 endif
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
--- mozilla/chrome/src/nsChromeRegistry.cpp.sav	2009-11-05 20:08:57.000000000 +0100
+++ mozilla/chrome/src/nsChromeRegistry.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -114,6 +114,7 @@
 #include "nsIXULAppInfo.h"
 #include "nsIXULRuntime.h"
 #include "nsPresShellIterator.h"
+#include "nsKDEUtils.h"
 
 #ifdef MOZ_XUL
 // keep all the RDF stuff together, in case we can remove it in the far future
@@ -2208,6 +2209,7 @@ nsChromeRegistry::ProcessManifestBuffer(
   NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
   NS_NAMED_LITERAL_STRING(kOs, "os");
   NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
+  NS_NAMED_LITERAL_STRING(kDesktop, "desktop");
 
   nsCOMPtr<nsIIOService> io (do_GetIOService());
   if (!io) return NS_ERROR_FAILURE;
@@ -2251,6 +2253,7 @@ nsChromeRegistry::ProcessManifestBuffer(
   }
   
   nsAutoString osVersion;
+  nsAutoString desktop;
 #if defined(XP_WIN)
   OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
   if (GetVersionEx(&info)) {
@@ -2258,6 +2261,7 @@ nsChromeRegistry::ProcessManifestBuffer(
                                          info.dwMajorVersion,
                                          info.dwMinorVersion);
   }
+  desktop = NS_LITERAL_STRING("win");
 #elif defined(XP_MACOSX)
   long majorVersion, minorVersion;
   if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
@@ -2266,10 +2270,12 @@ nsChromeRegistry::ProcessManifestBuffer(
                                          majorVersion,
                                          minorVersion);
   }
+  desktop = NS_LITERAL_STRING("macosx");
 #elif defined(MOZ_WIDGET_GTK2)
   nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
                                        gtk_major_version,
                                        gtk_minor_version);
+  desktop = nsKDEUtils::kdeSession() ? NS_LITERAL_STRING("kde") : NS_LITERAL_STRING("gnome"); // TODO others?
 #endif
 
   char *token;
@@ -2313,6 +2319,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOsVersion = eUnspecified;
       TriState stOs = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2326,6 +2333,7 @@ nsChromeRegistry::ProcessManifestBuffer(
             CheckFlag(kContentAccessible, wtoken, contentAccessible) ||
             CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2337,7 +2345,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad || 
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> resolved;
@@ -2398,6 +2406,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOs = eUnspecified;
       TriState stOsVersion = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2408,6 +2417,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2419,7 +2429,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad ||
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> resolved;
@@ -2460,6 +2470,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOs = eUnspecified;
       TriState stOsVersion = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2470,6 +2481,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2481,7 +2493,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad ||
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> resolved;
@@ -2524,6 +2536,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOs = eUnspecified;
       TriState stOsVersion = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2534,6 +2547,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2545,7 +2559,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad ||
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> baseuri, overlayuri;
@@ -2580,6 +2594,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOs = eUnspecified;
       TriState stOsVersion = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2590,6 +2605,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2601,7 +2617,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad ||
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> baseuri, overlayuri;
@@ -2640,6 +2656,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOs = eUnspecified;
       TriState stOsVersion = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2650,6 +2667,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2661,7 +2679,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad ||
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
 
       nsCOMPtr<nsIURI> chromeuri, resolveduri;
@@ -2702,6 +2720,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       TriState stApp = eUnspecified;
       TriState stOsVersion = eUnspecified;
       TriState stOs = eUnspecified;
+      TriState stDesktop = eUnspecified;
 
       PRBool badFlag = PR_FALSE;
 
@@ -2712,6 +2731,7 @@ nsChromeRegistry::ProcessManifestBuffer(
 
         if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
             CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+            CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
             CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
             CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
           continue;
@@ -2723,7 +2743,7 @@ nsChromeRegistry::ProcessManifestBuffer(
       }
 
       if (badFlag || stApp == eBad || stAppVersion == eBad || 
-          stOs == eBad || stOsVersion == eBad)
+          stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
         continue;
       
       nsDependentCString host(package);
--- mozilla/modules/libpref/src/Makefile.in.sav	2009-11-05 20:09:08.000000000 +0100
+++ mozilla/modules/libpref/src/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -97,3 +97,5 @@ nsPrefService.$(OBJ_SUFFIX): nsPrefServi
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS:-O2=-O1) $(_VPATH_SRCS)
 endif
+
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
--- mozilla/modules/libpref/src/nsPrefService.cpp.sav	2009-11-05 20:09:08.000000000 +0100
+++ mozilla/modules/libpref/src/nsPrefService.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -51,6 +51,7 @@
 #include "nsCOMArray.h"
 #include "nsXPCOMCID.h"
 #include "nsAutoPtr.h"
+#include "nsKDEUtils.h"
 
 #include "nsQuickSort.h"
 #include "prmem.h"
@@ -606,7 +607,8 @@ pref_LoadPrefsInDir(nsIFile* aDir, char
   return rv;
 }
 
-static nsresult pref_LoadPrefsInDirList(const char *listId)
+static nsresult pref_LoadPrefsInDirList(const char *listId,
+    char const *const *aSpecialFiles = NULL, PRUint32 aSpecialFilesCount = 0)
 {
   nsresult rv;
   nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
@@ -625,7 +627,7 @@ static nsresult pref_LoadPrefsInDirList(
         nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
         if (dir) {
           // Do we care if a file provided by this process fails to load?
-          pref_LoadPrefsInDir(dir, nsnull, 0); 
+          pref_LoadPrefsInDir(dir, aSpecialFiles, aSpecialFilesCount); 
         }
       }
     }
@@ -676,6 +678,7 @@ static nsresult pref_InitInitialObjects(
 #if defined(MOZ_WIDGET_PHOTON)
 	  , "photon.js"
 #endif		 
+      , "" // placeholder for KDE  (empty is otherwise harmless)
 #elif defined(XP_OS2)
       "os2pref.js"
 #elif defined(XP_BEOS)
@@ -683,12 +686,23 @@ static nsresult pref_InitInitialObjects(
 #endif
   };
 
+  if( nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires the helper?
+      for( int i = 0;
+           i < NS_ARRAY_LENGTH(specialFiles);
+           ++i ) {
+          if( *specialFiles[ i ] == '\0' ) {
+              specialFiles[ i ] = "kde.js";
+              break;
+          }
+      }
+  }
+      
   rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles));
   if (NS_FAILED(rv)) {
     NS_WARNING("Error parsing application default preferences.");
   }
 
-  rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
+  rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST, specialFiles, NS_ARRAY_LENGTH(specialFiles));
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
--- mozilla/toolkit/components/downloads/src/Makefile.in.sav	2009-11-05 20:09:12.000000000 +0100
+++ mozilla/toolkit/components/downloads/src/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -100,3 +100,4 @@ include $(topsrcdir)/config/rules.mk
 
 EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
 
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
--- mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp.sav	2009-11-16 15:26:47.000000000 +0100
+++ mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -85,6 +85,7 @@
 #include "nsDocShellCID.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsNetCID.h"
+#include "nsKDEUtils.h"
 
 #if defined(XP_WIN) && !defined(WINCE) 
 #include <shlobj.h>
@@ -2308,6 +2309,15 @@ nsDownload::SetState(DownloadState aStat
         pref->GetBoolPref(PREF_BDM_SHOWALERTONCOMPLETE, &showTaskbarAlert);
 
       if (showTaskbarAlert) {
+        if( nsKDEUtils::kdeSupport()) {
+            nsCStringArray command;
+            command.AppendCString( NS_LITERAL_CSTRING( "DOWNLOADFINISHED" ));
+            nsAutoString displayName;
+            GetDisplayName( displayName );
+            command.AppendCString( nsCAutoString( ToNewUTF8String( displayName )));
+            nsKDEUtils::command( command );
+        } else {
+        // begin non-KDE block
         PRInt32 alertInterval = 2000;
         if (pref)
           pref->GetIntPref(PREF_BDM_SHOWALERTINTERVAL, &alertInterval);
@@ -2343,6 +2353,7 @@ nsDownload::SetState(DownloadState aStat
                   EmptyString());
             }
         }
+        } // end non-KDE block
       }
 #if defined(XP_WIN) && !defined(WINCE)
       nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget);
--- mozilla/toolkit/content/jar.mn.sav	2009-11-05 20:09:13.000000000 +0100
+++ mozilla/toolkit/content/jar.mn	2009-11-16 15:37:59.000000000 +0100
@@ -43,6 +43,8 @@ toolkit.jar:
 *+ content/global/bindings/colorpicker.xml     (widgets/colorpicker.xml)
 *+ content/global/bindings/datetimepicker.xml  (widgets/datetimepicker.xml)
 *+ content/global/bindings/dialog.xml          (widgets/dialog.xml)
+*+ content/global/bindings/dialog-kde.xml      (widgets/dialog-kde.xml)
+% override chrome://global/content/bindings/dialog.xml chrome://global/content/bindings/dialog-kde.xml desktop=kde
 *+ content/global/bindings/editor.xml          (widgets/editor.xml)
 *  content/global/bindings/expander.xml        (widgets/expander.xml)
 *  content/global/bindings/filefield.xml       (widgets/filefield.xml)
@@ -56,6 +58,8 @@ toolkit.jar:
 *+ content/global/bindings/numberbox.xml       (widgets/numberbox.xml)
 *+ content/global/bindings/popup.xml           (widgets/popup.xml)
 *+ content/global/bindings/preferences.xml     (widgets/preferences.xml)
+*+ content/global/bindings/preferences-kde.xml (widgets/preferences-kde.xml)
+% override chrome://global/content/bindings/preferences.xml chrome://global/content/bindings/preferences-kde.xml desktop=kde
 *+ content/global/bindings/progressmeter.xml   (widgets/progressmeter.xml)
 *+ content/global/bindings/radio.xml           (widgets/radio.xml)
 *+ content/global/bindings/resizer.xml         (widgets/resizer.xml)
--- mozilla/toolkit/content/widgets/dialog-kde.xml.sav	2009-11-05 20:09:13.000000000 +0100
+++ mozilla/toolkit/content/widgets/dialog-kde.xml	2009-11-16 15:37:59.000000000 +0100
@@ -19,7 +19,7 @@
           
       <xul:hbox class="dialog-button-box" anonid="buttons"
                 xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
-#ifdef XP_UNIX
+#ifdef XP_UNIX_GNOME
                 >
         <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
         <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
@@ -28,6 +28,15 @@
         <xul:spacer anonid="spacer" flex="1"/>
         <xul:button dlgtype="cancel" class="dialog-button"/>
         <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
+#elif XP_UNIX
+                pack="end">
+        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
+        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+        <xul:spacer anonid="spacer" flex="1" hidden="true"/>
+        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
+        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
+        <xul:button dlgtype="cancel" class="dialog-button"/>
+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
 #else
                 pack="end">
         <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
--- mozilla/toolkit/content/widgets/preferences-kde.xml.sav	2009-11-05 20:09:13.000000000 +0100
+++ mozilla/toolkit/content/widgets/preferences-kde.xml	2009-11-16 15:37:59.000000000 +0100
@@ -573,7 +573,7 @@
         </xul:deck>
       </xul:hbox>
       <xul:hbox anonid="dlg-buttons" class="prefWindow-dlgbuttons"
-#ifdef XP_UNIX
+#ifdef XP_UNIX_GNOME
                 >
         <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
         <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
@@ -582,6 +582,15 @@
         <xul:spacer anonid="spacer" flex="1"/>
         <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
         <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
+#elif XP_UNIX
+                pack="end">
+        <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
+        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+        <xul:spacer anonid="spacer" flex="1"/>
+        <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
+        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
+        <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
 #else
                 pack="end">
         <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
--- mozilla/toolkit/system/unixproxy/Makefile.in.sav	2009-11-16 15:26:00.000000000 +0100
+++ mozilla/toolkit/system/unixproxy/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -59,6 +59,8 @@ REQUIRES = \
         mozgnome \
         $(NULL)
 
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+
 EXTRA_DSO_LDOPTS += \
                $(MOZ_LIBPROXY_LIBS) \
                $(MOZ_COMPONENT_LIBS) \
--- mozilla/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.sav	2009-11-16 15:26:15.000000000 +0100
+++ mozilla/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -49,6 +49,8 @@
 #include "nsPrintfCString.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPrimitives.h"
+#include "nsVoidArray.h"
+#include "nsKDEUtils.h"
 
 class nsUnixSystemProxySettings : public nsISystemProxySettings {
 public:
@@ -65,6 +67,7 @@ private:
   PRBool IsProxyMode(const char* aMode);
   nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, nsACString& aResult);
   nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
+  nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
 };
 
 NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
@@ -412,6 +415,9 @@ nsUnixSystemProxySettings::GetProxyForUR
   rv = aURI->GetPort(&port);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if( nsKDEUtils::kdeSupport())
+    return GetProxyFromKDE( scheme, host, port, aResult );
+
   if (!mGConf)
     return GetProxyFromEnvironment(scheme, host, port, aResult);
 
@@ -432,3 +438,28 @@ static const nsModuleComponentInfo compo
 };
 
 NS_IMPL_NSGETMODULE(nsUnixProxyModule, components)
+
+nsresult
+nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
+                                             const nsACString& aHost,
+                                             PRInt32 aPort,
+                                             nsACString& aResult)
+{
+  nsCAutoString url;
+  url = aScheme;
+  url += "://";
+  url += aHost;
+  if( aPort >= 0 )
+      {
+      url += ":";
+      url += nsPrintfCString("%d", aPort);
+      }
+  nsCStringArray command;
+  command.AppendCString( NS_LITERAL_CSTRING( "GETPROXY" ));
+  command.AppendCString( url );
+  nsCStringArray result;
+  if( !nsKDEUtils::command( command, &result ) || result.Count() != 1 )
+      return NS_ERROR_FAILURE;
+  aResult = *result[ 0 ];
+  return NS_OK;
+}
--- mozilla/toolkit/xre/Makefile.in.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/toolkit/xre/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -98,6 +98,7 @@ endif
 EXPORTS = \
 	xrecore.h \
 	nsXULAppAPI.h \
+	nsKDEUtils.h \
 	$(NULL)
 
 CPPSRCS = \
@@ -133,7 +134,7 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
 CPPSRCS += nsNativeAppSupportBeOS.cpp
 else
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-CPPSRCS += nsNativeAppSupportUnix.cpp
+CPPSRCS += nsNativeAppSupportUnix.cpp nsKDEUtils.cpp
 else
 CPPSRCS += nsNativeAppSupportDefault.cpp
 endif
--- mozilla/toolkit/xre/nsKDEUtils.cpp.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/toolkit/xre/nsKDEUtils.cpp	2009-11-23 13:16:57.000000000 +0100
@@ -0,0 +1,335 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Unix Native App Support.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsKDEUtils.h"
+#include "nsIWidget.h"
+
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkmain.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+
+//#define DEBUG_KDE
+#ifdef DEBUG_KDE
+#define KMOZILLAHELPER "kmozillahelper"
+#else
+// not need for lib64, it's a binary
+#define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper"
+#endif
+
+#define KMOZILLAHELPER_VERSION 6
+#define MAKE_STR2( n ) #n
+#define MAKE_STR( n ) MAKE_STR2( n )
+
+static bool getKdeSession()
+    {
+    Display* dpy = XOpenDisplay( NULL );
+    if( dpy == NULL )
+        return false;
+    Atom kde_full_session = XInternAtom( dpy, "KDE_FULL_SESSION", True );
+    bool kde = false;
+    if( kde_full_session != None )
+        {
+        int cnt;
+        if( Atom* props = XListProperties( dpy, DefaultRootWindow( dpy ), &cnt ))
+            {
+            for( int i = 0;
+                 i < cnt;
+                 ++i )
+                {
+                if( props[ i ] == kde_full_session )
+                    {
+                    kde = true;
+#ifdef DEBUG_KDE
+                    fprintf( stderr, "KDE SESSION %d\n", kde );
+#endif
+                    break;
+                    }
+                }
+            XFree( props );
+            }
+        }
+    XCloseDisplay( dpy );
+    return kde;
+    }
+
+static bool getKdeSupport()
+    {
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "CHECK" ));
+    command.AppendCString( NS_LITERAL_CSTRING( MAKE_STR( KMOZILLAHELPER_VERSION )));
+    bool kde = nsKDEUtils::command( command );
+#ifdef DEBUG_KDE
+    fprintf( stderr, "KDE RUNNING %d\n", kde );
+#endif
+    return kde;
+    }
+
+nsKDEUtils::nsKDEUtils()
+    : commandFile( NULL )
+    , replyFile( NULL )
+    {
+    }
+
+nsKDEUtils::~nsKDEUtils()
+    {
+//    closeHelper(); not actually useful, exiting will close the fd too
+    }
+
+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::kdeSupport()
+    {
+    static bool support = kdeSession() && getKdeSupport();
+    return support && helperRunning;
+    }
+
+struct nsKDECommandData
+    {
+    FILE* file;
+    nsCStringArray* output;
+    GMainLoop* loop;
+    bool success;
+    };
+
+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 );
+        nsCAutoString line( buf );
+        line.ReplaceSubstring( "\\n", "\n" );
+        line.ReplaceSubstring( "\\" "\\", "\\" ); //  \\ -> \ , i.e. unescape
+        if( p->output && !( command_done || command_failed ))
+            p->output->AppendCString( 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 nsCStringArray& command, nsCStringArray* output )
+    {
+    return self()->internalCommand( command, NULL, false, output );
+    }
+
+bool nsKDEUtils::commandBlockUi( const nsCStringArray& command, const GtkWindow* parent, nsCStringArray* output )
+    {
+    return self()->internalCommand( command, parent, true, output );
+    }
+
+bool nsKDEUtils::internalCommand( const nsCStringArray& command, const GtkWindow* parent, bool blockUi,
+    nsCStringArray* output )
+    {
+    if( !startHelper())
+        return false;
+    // if Gtk has meanwhile gotten a grab (bnc#555202, somehow the file dialog
+    // is called with a delay), then do not do anything, as this app would keep
+    // the grabs but block waiting for the helper, which would be unable to do
+    // anything because of the grab
+    if( blockUi && gdk_pointer_is_grabbed())
+        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 && parent->group )
+            gtk_window_group_add_window( parent->group, 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
+            {
+            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
+            }
+        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 nsCStringArray& command )
+    {
+    for( int i = 0;
+         i < command.Count();
+         ++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 );
+    }
--- mozilla/toolkit/xre/nsKDEUtils.h.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/toolkit/xre/nsKDEUtils.h	2009-11-16 15:37:59.000000000 +0100
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsKDEUtils_h__
+#define nsKDEUtils_h__
+
+#include "nsStringGlue.h"
+#include "nsVoidArray.h"
+#include <stdio.h>
+
+typedef struct _GtkWindow GtkWindow;
+
+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 nsCStringArray& command, nsCStringArray* 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 nsCStringArray& command, const GtkWindow* parent, nsCStringArray* output = NULL );
+    private:
+        nsKDEUtils();
+        ~nsKDEUtils();
+        static nsKDEUtils* self();
+        bool startHelper();
+        void closeHelper();
+        void feedCommand( const nsCStringArray& command );
+        bool internalCommand( const nsCStringArray& command, const GtkWindow* parent, bool isParent,
+            nsCStringArray* output );
+        FILE* commandFile;
+        FILE* replyFile;
+    };
+
+#endif // nsKDEUtils
--- mozilla/uriloader/exthandler/Makefile.in.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/uriloader/exthandler/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -109,8 +109,9 @@ endif
 LOCAL_INCLUDES = -I$(srcdir)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-OSHELPER	+= nsGNOMERegistry.cpp
+OSHELPER	+= nsCommonRegistry.cpp nsGNOMERegistry.cpp nsKDERegistry.cpp
 OSHELPER  += nsMIMEInfoUnix.cpp
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
--- mozilla/uriloader/exthandler/unix/nsCommonRegistry.cpp.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsCommonRegistry.cpp	2009-11-23 13:22:53.000000000 +0100
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the GNOME helper app implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsCommonRegistry.h"
+
+#include "nsGNOMERegistry.h"
+#include "nsKDERegistry.h"
+#include "nsString.h"
+#include "nsVoidArray.h"
+#include "nsKDEUtils.h"
+
+/* static */ PRBool
+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 */ 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::GetFromExtension(const nsACString& aFileExt)
+{
+    if( nsKDEUtils::kdeSupport())
+        return nsKDERegistry::GetFromExtension( aFileExt );
+    return nsGNOMERegistry::GetFromExtension( aFileExt );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsCommonRegistry::GetFromType(const nsACString& aMIMEType)
+{
+    if( nsKDEUtils::kdeSupport())
+        return nsKDERegistry::GetFromType( aMIMEType );
+    return nsGNOMERegistry::GetFromType( aMIMEType );
+}
--- mozilla/uriloader/exthandler/unix/nsCommonRegistry.h.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsCommonRegistry.h	2009-11-16 15:37:59.000000000 +0100
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the GNOME helper app implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+
+class nsMIMEInfoBase;
+
+class nsCommonRegistry
+{
+ public:
+  static PRBool HandlerExists(const char *aProtocolScheme);
+
+  static nsresult LoadURL(nsIURI *aURL);
+
+  static void GetAppDescForScheme(const nsACString& aScheme,
+                                  nsAString& aDesc);
+
+  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
+
+  static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
+};
--- mozilla/uriloader/exthandler/unix/nsKDERegistry.cpp.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsKDERegistry.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the GNOME helper app implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsKDERegistry.h"
+#include "prlink.h"
+#include "prmem.h"
+#include "nsString.h"
+#include "nsILocalFile.h"
+#include "nsMIMEInfoUnix.h"
+#include "nsAutoPtr.h"
+#include "nsKDEUtils.h"
+
+/* static */ PRBool
+nsKDERegistry::HandlerExists(const char *aProtocolScheme)
+{
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "HANDLEREXISTS" ));
+    command.AppendCString( nsCAutoString( aProtocolScheme ));
+    return nsKDEUtils::command( command );
+}
+
+/* static */ nsresult
+nsKDERegistry::LoadURL(nsIURI *aURL)
+{
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
+    nsCString url;
+    aURL->GetSpec( url );
+    command.AppendCString( url );
+    return nsKDEUtils::command( command );
+}
+
+/* static */ void
+nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
+                                     nsAString& aDesc)
+{
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "GETAPPDESCFORSCHEME" ));
+    command.AppendCString( aScheme );
+    nsCStringArray output;
+    if( nsKDEUtils::command( command, &output ) && output.Count() == 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");
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "GETFROMEXTENSION" ));
+    command.AppendCString( aFileExt );
+    return GetFromHelper( command );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsKDERegistry::GetFromType(const nsACString& aMIMEType)
+{
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "GETFROMTYPE" ));
+    command.AppendCString( aMIMEType );
+    return GetFromHelper( command );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsKDERegistry::GetFromHelper(const nsCStringArray& command)
+{
+    nsCStringArray output;
+    if( nsKDEUtils::command( command, &output ) && output.Count() == 3 )
+        {
+        nsCString mimetype = *output[ 0 ];
+        nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix( mimetype );
+        NS_ENSURE_TRUE(mimeInfo, nsnull);
+        nsCString description = *output[ 1 ];
+        mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
+        nsCString handlerAppName = *output[ 2 ];
+        mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
+        mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
+        nsMIMEInfoBase* retval;
+        NS_ADDREF((retval = mimeInfo));
+        return retval;
+        }
+    return nsnull;
+}
--- mozilla/uriloader/exthandler/unix/nsKDERegistry.h.sav	2009-11-16 15:37:59.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsKDERegistry.h	2009-11-16 15:37:59.000000000 +0100
@@ -0,0 +1,61 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the GNOME helper app implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+
+class nsMIMEInfoBase;
+class nsCAutoString;
+class nsCStringArray;
+
+class nsKDERegistry
+{
+ public:
+  static PRBool HandlerExists(const char *aProtocolScheme);
+
+  static nsresult LoadURL(nsIURI *aURL);
+
+  static void GetAppDescForScheme(const nsACString& aScheme,
+                                  nsAString& aDesc);
+
+  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
+
+  static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
+ private:
+  static already_AddRefed<nsMIMEInfoBase> GetFromHelper(const nsCStringArray& command);
+
+};
--- mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.sav	2009-11-16 15:25:58.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp	2009-11-23 13:12:28.000000000 +0100
@@ -44,18 +44,19 @@
 
 
 #include "nsMIMEInfoUnix.h"
-#include "nsGNOMERegistry.h"
+#include "nsCommonRegistry.h"
 #include "nsIGnomeVFSService.h"
 #include "nsAutoPtr.h"
 #ifdef MOZ_ENABLE_DBUS
 #include "nsDBusHandlerApp.h"
 #endif
+#include "nsKDEUtils.h"
 
 
 nsresult
 nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
 { 
-  nsresult rv = nsGNOMERegistry::LoadURL(aURI);
+  nsresult rv = nsCommonRegistry::LoadURL(aURI);
 #ifdef MOZ_PLATFORM_HILDON
   if (NS_FAILED(rv)){
     HildonURIAction *action = hildon_uri_get_default_action(mType.get(), nsnull);
@@ -75,11 +76,11 @@ NS_IMETHODIMP
 nsMIMEInfoUnix::GetHasDefaultHandler(PRBool *_retval)
 {
   *_retval = PR_FALSE;
-  nsRefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromType(mType);
+  nsRefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromType(mType);
   if (!mimeInfo) {
     nsCAutoString ext;
     GetPrimaryExtension(ext);
-    mimeInfo = nsGNOMERegistry::GetFromExtension(ext);
+    mimeInfo = nsCommonRegistry::GetFromExtension(ext);
   }
 
   if (mimeInfo)
@@ -106,6 +107,25 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
 {
   nsCAutoString nativePath;
   aFile->GetNativePath(nativePath);
+  
+  if( nsKDEUtils::kdeSupport())
+      {
+      PRBool supports;
+      if( NS_SUCCEEDED( GetHasDefaultHandler( &supports )) && supports )
+          {
+          nsCStringArray command;
+          command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
+          command.AppendCString( nativePath );
+          command.AppendCString( NS_LITERAL_CSTRING( "MIMETYPE" ));
+          command.AppendCString( mType );
+          if( nsKDEUtils::command( command ))
+              return NS_OK;
+          }
+      if (!mDefaultApplication)
+        return NS_ERROR_FILE_NOT_FOUND;
+
+      return LaunchWithIProcess(mDefaultApplication, nativePath);
+      }
 
   nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
 
@@ -116,7 +136,7 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
 
     // If we haven't got an app we try to get a valid one by searching for the
     // extension mapped type
-    nsRefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromExtension(nativePath);
+    nsRefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromExtension(nativePath);
     if (mimeInfo) {
       nsCAutoString type;
       mimeInfo->GetType(type);
--- mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp.sav	2009-11-16 15:25:58.000000000 +0100
+++ mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -44,7 +44,7 @@
 #include "nsOSHelperAppService.h"
 #include "nsMIMEInfoUnix.h"
 #ifdef MOZ_WIDGET_GTK2
-#include "nsGNOMERegistry.h"
+#include "nsCommonRegistry.h"
 #endif
 #include "nsISupports.h"
 #include "nsString.h"
@@ -1210,7 +1210,7 @@ nsresult nsOSHelperAppService::OSProtoco
 
 #ifdef MOZ_WIDGET_GTK2
   // Check the GConf registry for a protocol handler
-  *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme);
+  *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme);
 #endif
 
   return NS_OK;
@@ -1219,7 +1219,7 @@ nsresult nsOSHelperAppService::OSProtoco
 NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
 {
 #ifdef MOZ_WIDGET_GTK2
-  nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval);
+  nsCommonRegistry::GetAppDescForScheme(aScheme, _retval);
   return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK;
 #else
   return NS_ERROR_NOT_AVAILABLE;
@@ -1315,7 +1315,7 @@ nsOSHelperAppService::GetFromExtension(c
     
 #ifdef MOZ_WIDGET_GTK2
     LOG(("Looking in GNOME registry\n"));
-    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt).get();
+    nsMIMEInfoBase *gnomeInfo = nsCommonRegistry::GetFromExtension(aFileExt).get();
     if (gnomeInfo) {
       LOG(("Got MIMEInfo from GNOME registry\n"));
       return gnomeInfo;
@@ -1441,7 +1441,7 @@ nsOSHelperAppService::GetFromType(const
     // get back a MIMEInfo without any extensions set.  In that case we'll have
     // to look in our mime.types files for the extensions.    
     LOG(("Looking in GNOME registry\n"));
-    gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType).get();
+    gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType).get();
     if (gnomeInfo && gnomeInfo->HasExtensions()) {
       LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n"));
       return gnomeInfo;
--- mozilla/widget/src/gtk2/Makefile.in.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/widget/src/gtk2/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -182,6 +182,8 @@ INCLUDES	+= \
 		-I$(topsrcdir)/other-licenses/atk-1.0 \
 		$(NULL)
 
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+
 test_container: mozdrawingarea.o mozcontainer.o test_container.c
 	$(CC) $(MOZ_GTK2_CFLAGS) -o test_container test_container.c \
 		mozdrawingarea.o mozcontainer.o \
--- mozilla/widget/src/gtk2/nsFilePicker.cpp.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/widget/src/gtk2/nsFilePicker.cpp	2009-11-16 15:59:10.000000000 +0100
@@ -40,6 +40,7 @@
 #include <gtk/gtkstock.h>
 #include <gtk/gtkmessagedialog.h>
 #include <gtk/gtkimage.h>
+#include <gdk/gdkx.h>
 
 #include "nsIFileURL.h"
 #include "nsIURI.h"
@@ -59,6 +60,7 @@
 
 #include "nsFilePicker.h"
 #include "nsAccessibilityHelper.h"
+#include "nsKDEUtils.h"
 
 #define DECL_FUNC_PTR(func) static _##func##_fn _##func
 #define GTK_FILE_CHOOSER(widget) ((GtkFileChooser*) widget)
@@ -95,6 +97,7 @@ typedef GtkWidget* (*_gtk_file_chooser_d
                                                       GtkFileChooserAction action,
                                                       const gchar *first_button_text,
                                                       ...);
+typedef void (*_gtk_dialog_set_alternative_button_order_fn)(GtkDialog *dialog, gint first_response_id, ...);
 typedef void (*_gtk_file_chooser_set_select_multiple_fn)(GtkFileChooser* chooser, gboolean truth);
 typedef void (*_gtk_file_chooser_set_do_overwrite_confirmation_fn)(GtkFileChooser* chooser, gboolean do_confirm);
 typedef void (*_gtk_file_chooser_set_current_name_fn)(GtkFileChooser* chooser, const gchar* name);
@@ -119,6 +122,7 @@ DECL_FUNC_PTR(gtk_file_chooser_get_filen
 DECL_FUNC_PTR(gtk_file_chooser_get_uri);
 DECL_FUNC_PTR(gtk_file_chooser_get_uris);
 DECL_FUNC_PTR(gtk_file_chooser_dialog_new);
+DECL_FUNC_PTR(gtk_dialog_set_alternative_button_order);
 DECL_FUNC_PTR(gtk_file_chooser_set_select_multiple);
 DECL_FUNC_PTR(gtk_file_chooser_set_do_overwrite_confirmation);
 DECL_FUNC_PTR(gtk_file_chooser_set_current_name);
@@ -214,6 +218,7 @@ nsFilePicker::LoadSymbolsGTK24()
   GET_LIBGTK_FUNC(gtk_file_chooser_get_uri);
   GET_LIBGTK_FUNC(gtk_file_chooser_get_uris);
   GET_LIBGTK_FUNC(gtk_file_chooser_dialog_new);
+  GET_LIBGTK_FUNC(gtk_dialog_set_alternative_button_order);
   GET_LIBGTK_FUNC(gtk_file_chooser_set_select_multiple);
   GET_LIBGTK_FUNC_OPT(gtk_file_chooser_set_do_overwrite_confirmation);
   GET_LIBGTK_FUNC(gtk_file_chooser_set_current_name);
@@ -442,7 +447,9 @@ nsFilePicker::AppendFilter(const nsAStri
 {
   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;
   }
 
   nsCAutoString filter, name;
@@ -590,6 +597,9 @@ confirm_overwrite_file (GtkWidget *paren
 NS_IMETHODIMP
 nsFilePicker::Show(PRInt16 *aReturn)
 {
+  if( nsKDEUtils::kdeSupport())
+      return kdeFileDialog( aReturn );
+
   NS_ENSURE_ARG_POINTER(aReturn);
 
   nsXPIDLCString title;
@@ -605,6 +615,12 @@ nsFilePicker::Show(PRInt16 *aReturn)
                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    accept_button, GTK_RESPONSE_ACCEPT,
                                    NULL);
+
+  _gtk_dialog_set_alternative_button_order(GTK_DIALOG(file_chooser),
+                                          GTK_RESPONSE_ACCEPT,
+                                          GTK_RESPONSE_CANCEL,
+                                          -1);
+
   if (mAllowURLs) {
     _gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE);
   }
@@ -727,3 +743,229 @@ nsFilePicker::Show(PRInt16 *aReturn)
 
   return NS_OK;
 }
+
+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 = get_gtk_window_for_nsiwidget( widget );
+    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(PRInt16 *aReturn)
+    {
+    NS_ENSURE_ARG_POINTER(aReturn);
+
+    if( mMode == modeOpen && mFilters.Count() == 1 && mFilters[ 0 ]->EqualsLiteral( "..apps" ))
+        return kdeAppsDialog( aReturn );
+
+    nsXPIDLCString 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;
+            }
+        }
+
+  nsCAutoString directory;
+  if (mDisplayDirectory) {
+    mDisplayDirectory->GetNativePath(directory);
+  } else if (mPrevDisplayDirectory) {
+    mPrevDisplayDirectory->GetNativePath(directory);
+  }
+
+    nsCAutoString startdir;
+  if (!directory.IsEmpty()) {
+    startdir = directory;
+  }
+  if (mMode == nsIFilePicker::modeSave) {
+    if( !startdir.IsEmpty())
+      {
+      startdir += "/";
+      startdir += ToNewUTF8String(mDefault);
+      }
+    else
+      startdir = ToNewUTF8String(mDefault);
+  }
+  if( startdir.IsEmpty())
+      startdir = ".";
+
+    nsCAutoString filters;
+    PRInt32 count = mFilters.Count();
+    if( count == 0 ) //just in case
+        filters = "*";
+    else
+        {
+        filters = kdeMakeFilter( 0 );
+        for (PRInt32 i = 1; i < count; ++i)
+            {
+            filters += "\n";
+            filters += kdeMakeFilter( i );
+            }
+        }
+
+    nsCStringArray command;
+    command.AppendCString( nsCAutoString( arg ));
+    command.AppendCString( startdir );
+    if( mMode != nsIFilePicker::modeGetFolder )
+        {
+        command.AppendCString( filters );
+        nsCAutoString selected;
+        selected.AppendInt( mSelectedType );
+        command.AppendCString( selected );
+        }
+    command.AppendCString( title );
+    if( mMode == nsIFilePicker::modeOpenMultiple )
+        command.AppendCString( NS_LITERAL_CSTRING( "MULTIPLE" ));
+    if( PRInt32 xid = windowToXid( mParentWidget ))
+        {
+        command.AppendCString( NS_LITERAL_CSTRING( "PARENT" ));
+        nsCAutoString parent;
+        parent.AppendInt( xid );
+        command.AppendCString( parent );
+        }
+
+    nsCStringArray output;
+    if( nsKDEUtils::commandBlockUi( command, get_gtk_window_for_nsiwidget( mParentWidget ), &output ))
+        {
+        *aReturn = nsIFilePicker::returnOK;
+        mFiles.Clear();
+        if( mMode != nsIFilePicker::modeGetFolder )
+            {
+            mSelectedType = atoi( output[ 0 ]->get());
+            output.RemoveCStringAt( 0 );
+            }
+        if (mMode == nsIFilePicker::modeOpenMultiple)
+            {
+            mFileURL.Truncate();
+            PRUint32 count = output.Count();
+            for( PRUint32 i = 0;
+                 i < count;
+                 ++i )
+                {
+                nsCOMPtr<nsILocalFile> localfile;
+                nsresult rv = NS_NewNativeLocalFile( *output[ i ],
+                                      PR_FALSE,
+                                      getter_AddRefs(localfile));
+                if (NS_SUCCEEDED(rv))
+                    mFiles.AppendObject(localfile);
+                }
+            }
+        else
+            {
+            if( output.Count() == 0 )
+                mFileURL = nsCString();
+            else if( mAllowURLs )
+                mFileURL = *output[ 0 ];
+            else // GetFile() actually requires it to be url even for local files :-/
+                {
+                mFileURL = nsCString( "file://" );
+                mFileURL.Append( *output[ 0 ] );
+                }
+            }
+  // Remember last used directory.
+  nsCOMPtr<nsILocalFile> file;
+  GetFile(getter_AddRefs(file));
+  if (file) {
+    nsCOMPtr<nsIFile> dir;
+    file->GetParent(getter_AddRefs(dir));
+    nsCOMPtr<nsILocalFile> localDir(do_QueryInterface(dir));
+    if (localDir) {
+      localDir.swap(mPrevDisplayDirectory);
+    }
+  }
+        if (mMode == nsIFilePicker::modeSave)
+            {
+            nsCOMPtr<nsILocalFile> file;
+            GetFile(getter_AddRefs(file));
+            if (file)
+                {
+                PRBool exists = PR_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(PRInt16 *aReturn)
+    {
+    NS_ENSURE_ARG_POINTER(aReturn);
+
+    nsXPIDLCString title;
+    title.Adopt(ToNewUTF8String(mTitle));
+
+    nsCStringArray command;
+    command.AppendCString( NS_LITERAL_CSTRING( "APPSDIALOG" ));
+    command.AppendCString( title );
+    if( PRInt32 xid = windowToXid( mParentWidget ))
+        {
+        command.AppendCString( NS_LITERAL_CSTRING( "PARENT" ));
+        nsCAutoString parent;
+        parent.AppendInt( xid );
+        command.AppendCString( parent );
+        }
+
+    nsCStringArray output;
+    if( nsKDEUtils::commandBlockUi( command, get_gtk_window_for_nsiwidget( mParentWidget ), &output ))
+        {
+        *aReturn = nsIFilePicker::returnOK;
+        mFileURL = output.Count() > 0 ? *output[ 0 ] : nsCString();
+        }
+    else
+        {
+        *aReturn = nsIFilePicker::returnCancel;
+        }
+    return NS_OK;
+    }
--- mozilla/widget/src/gtk2/nsFilePicker.h.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/widget/src/gtk2/nsFilePicker.h	2009-11-16 15:37:59.000000000 +0100
@@ -98,6 +98,12 @@ protected:
 private:
   static nsILocalFile *mPrevDisplayDirectory;
   static PRLibrary *mGTK24;
+  
+  bool kdeRunning();
+  bool getKdeRunning();
+  NS_IMETHODIMP kdeFileDialog(PRInt16 *aReturn);
+  NS_IMETHODIMP kdeAppsDialog(PRInt16 *aReturn);
+  nsCString kdeMakeFilter( int index );
 };
 
 #endif
--- mozilla/widget/src/gtk2/nsPrintDialogGTK.cpp.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/widget/src/gtk2/nsPrintDialogGTK.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -145,6 +145,10 @@ ShowCustomDialog(GtkComboBox *changed_bo
                                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                                                          NULL);
   gtk_dialog_set_default_response(GTK_DIALOG(prompt_dialog), GTK_RESPONSE_ACCEPT);
+  gtk_dialog_set_alternative_button_order(GTK_DIALOG(prompt_dialog),
+                                          GTK_RESPONSE_ACCEPT,
+                                          GTK_RESPONSE_REJECT,
+                                          -1);
 
   printBundle->GetStringFromName(NS_LITERAL_STRING("customHeaderFooterPrompt").get(), getter_Copies(intlString));
   GtkWidget* custom_label = gtk_label_new(NS_ConvertUTF16toUTF8(intlString).get());
--- mozilla/xpcom/io/Makefile.in.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/xpcom/io/Makefile.in	2009-11-16 15:37:59.000000000 +0100
@@ -199,3 +199,4 @@ endif
 endif
 
 LOCAL_INCLUDES	= -I..
+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
--- mozilla/xpcom/io/nsLocalFileUnix.cpp.sav	2009-11-05 20:09:14.000000000 +0100
+++ mozilla/xpcom/io/nsLocalFileUnix.cpp	2009-11-16 15:37:59.000000000 +0100
@@ -84,6 +84,7 @@
 
 #ifdef MOZ_WIDGET_GTK2
 #include "nsIGnomeVFSService.h"
+#include "nsKDEUtils.h"
 #endif
 
 #include "nsNativeCharsetUtils.h"
@@ -1648,16 +1649,13 @@ NS_IMETHODIMP
 nsLocalFile::Reveal()
 {
 #ifdef MOZ_WIDGET_GTK2
-    nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-    if (!vfs)
-        return NS_ERROR_FAILURE;
-
+    nsCAutoString url;
     PRBool isDirectory;
     if (NS_FAILED(IsDirectory(&isDirectory)))
         return NS_ERROR_FAILURE;
 
     if (isDirectory) {
-        return vfs->ShowURIForInput(mPath);
+        url = mPath;
     } else {
         nsCOMPtr<nsIFile> parentDir;
         nsCAutoString dirPath;
@@ -1666,8 +1664,21 @@ nsLocalFile::Reveal()
         if (NS_FAILED(parentDir->GetNativePath(dirPath)))
             return NS_ERROR_FAILURE;
 
-        return vfs->ShowURIForInput(dirPath);
+        url = dirPath;
     }
+
+    if( nsKDEUtils::kdeSupport()) {
+        nsCStringArray command;
+        command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
+        command.AppendCString( url );
+        return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
+    }
+
+    nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+    if (!vfs)
+        return NS_ERROR_FAILURE;
+    return vfs->ShowURIForInput(url);
+
 #else
     return NS_ERROR_FAILURE;
 #endif
@@ -1677,6 +1688,13 @@ NS_IMETHODIMP
 nsLocalFile::Launch()
 {
 #ifdef MOZ_WIDGET_GTK2
+    if( nsKDEUtils::kdeSupport()) {
+        nsCStringArray command;
+        command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
+        command.AppendCString( mPath );
+        return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
+    }
+
     nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
     if (!vfs)
         return NS_ERROR_FAILURE;

