diff --git a/helpers/DATA/firefox/firefox-kde.patch b/helpers/DATA/firefox/firefox-kde.patch
deleted file mode 100644
index 403021449e54cf24cc6c083874c5902ae28f9130..0000000000000000000000000000000000000000
--- a/helpers/DATA/firefox/firefox-kde.patch
+++ /dev/null
@@ -1,1815 +0,0 @@
-# HG changeset patch
-# Parent  77c3bdc27160dfa96aa4b3288c7f12a72f273967
-
-diff --git a/browser/base/content/browser-kde.xul b/browser/base/content/browser-kde.xul
-new file mode 100644
---- /dev/null
-+++ b/browser/base/content/browser-kde.xul
-@@ -0,0 +1,1250 @@
-+#filter substitution
-+<?xml version="1.0"?>
-+# -*- Mode: HTML -*-
-+#
-+# 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/.
-+
-+<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
-+<?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
-+<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
-+<?xml-stylesheet href="chrome://browser/skin/controlcenter/panel.css" type="text/css"?>
-+<?xml-stylesheet href="chrome://browser/skin/customizableui/panelUIOverlay.css" type="text/css"?>
-+<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-+<?xml-stylesheet href="chrome://browser/skin/browser-lightweightTheme.css" type="text/css"?>
-+
-+<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-+<?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
-+<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-+
-+# All DTD information is stored in a separate file so that it can be shared by
-+# hiddenWindow.xul.
-+#include browser-doctype.inc
-+
-+<window id="main-window"
-+        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-+        xmlns:svg="http://www.w3.org/2000/svg"
-+        xmlns:html="http://www.w3.org/1999/xhtml"
-+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-+        onload="gBrowserInit.onLoad()" onunload="gBrowserInit.onUnload()" onclose="return WindowIsClosing();"
-+        title="&mainWindow.title;"
-+        title_normal="&mainWindow.title;"
-+#ifdef XP_MACOSX
-+        title_privatebrowsing="&mainWindow.title;&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
-+        titledefault="&mainWindow.title;"
-+        titlemodifier=""
-+        titlemodifier_normal=""
-+        titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
-+#else
-+        title_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
-+        titlemodifier="&mainWindow.titlemodifier;"
-+        titlemodifier_normal="&mainWindow.titlemodifier;"
-+        titlemodifier_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
-+#endif
-+#ifdef CAN_DRAW_IN_TITLEBAR
-+#ifdef XP_WIN
-+        chromemargin="0,2,2,2"
-+#else
-+        chromemargin="0,-1,-1,-1"
-+#endif
-+        tabsintitlebar="true"
-+#endif
-+        titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
-+        lightweightthemes="true"
-+        lightweightthemesfooter="browser-bottombox"
-+        windowtype="navigator:browser"
-+        macanimationtype="document"
-+        screenX="4" screenY="4"
-+        fullscreenbutton="true"
-+        sizemode="normal"
-+        retargetdocumentfocus="urlbar"
-+        persist="screenX screenY width height sizemode">
-+
-+# All JS files which are not content (only) dependent that browser.xul
-+# wishes to include *must* go into the global-scripts.inc file
-+# so that they can be shared by macBrowserOverlay.xul.
-+#include global-scripts.inc
-+<script type="application/javascript" src="chrome://browser/content/nsContextMenu.js"/>
-+
-+<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
-+
-+<script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-+
-+# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
-+# browser-sets.inc file for sharing with hiddenWindow.xul.
-+#define FULL_BROWSER_WINDOW
-+#include browser-sets.inc
-+#undef FULL_BROWSER_WINDOW
-+
-+  <popupset id="mainPopupSet">
-+    <menupopup id="tabContextMenu"
-+               onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
-+               onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
-+      <menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
-+                oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
-+      <menuitem id="context_toggleMuteTab" oncommand="TabContextMenu.contextTab.toggleMuteAudio();"/>
-+      <menuseparator/>
-+      <menuitem id="context_pinTab" label="&pinTab.label;"
-+                accesskey="&pinTab.accesskey;"
-+                oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/>
-+      <menuitem id="context_unpinTab" label="&unpinTab.label;" hidden="true"
-+                accesskey="&unpinTab.accesskey;"
-+                oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/>
-+      <menu id="context_tabViewMenu" label="&moveToGroup.label;"
-+            accesskey="&moveToGroup.accesskey;">
-+        <menupopup id="context_tabViewMenuPopup"
-+                   onpopupshowing="if (event.target == this) TabView.moveToGroupPopupShowing(event);">
-+          <menuseparator id="context_tabViewNamedGroups" hidden="true"/>
-+          <menuitem id="context_tabViewNewGroup" label="&moveToNewGroup.label;"
-+                    oncommand="TabView.moveTabTo(TabContextMenu.contextTab, null);"/>
-+        </menupopup>
-+      </menu>
-+      <menuitem id="context_openTabInWindow" label="&moveToNewWindow.label;"
-+                accesskey="&moveToNewWindow.accesskey;"
-+                tbattr="tabbrowser-multiple"
-+                oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
-+#ifdef E10S_TESTING_ONLY
-+      <menuitem id="context_openNonRemoteWindow" label="Open in new non-e10s window"
-+                tbattr="tabbrowser-remote"
-+                hidden="true"
-+                oncommand="gBrowser.openNonRemoteWindow(TabContextMenu.contextTab);"/>
-+#endif
-+      <menuseparator/>
-+      <menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
-+                tbattr="tabbrowser-multiple-visible"
-+                oncommand="gBrowser.reloadAllTabs();"/>
-+      <menuitem id="context_bookmarkAllTabs"
-+                label="&bookmarkAllTabs.label;"
-+                accesskey="&bookmarkAllTabs.accesskey;"
-+                command="Browser:BookmarkAllTabs"/>
-+      <menuitem id="context_closeTabsToTheEnd" label="&closeTabsToTheEnd.label;" accesskey="&closeTabsToTheEnd.accesskey;"
-+                oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab);"/>
-+      <menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
-+                oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
-+      <menuseparator/>
-+      <menuitem id="context_undoCloseTab"
-+                label="&undoCloseTab.label;"
-+                accesskey="&undoCloseTab.accesskey;"
-+                observes="History:UndoCloseTab"/>
-+      <menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
-+                oncommand="gBrowser.removeTab(TabContextMenu.contextTab, { animate: true });"/>
-+    </menupopup>
-+
-+    <!-- bug 415444/582485: event.stopPropagation is here for the cloned version
-+         of this menupopup -->
-+    <menupopup id="backForwardMenu"
-+               onpopupshowing="return FillHistoryMenu(event.target);"
-+               oncommand="gotoHistoryIndex(event); event.stopPropagation();"
-+               onclick="checkForMiddleClick(this, event);"/>
-+    <tooltip id="aHTMLTooltip" page="true"/>
-+    <tooltip id="remoteBrowserTooltip"/>
-+
-+    <!-- for search and content formfill/pw manager -->
-+    <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
-+
-+    <!-- for search with one-off buttons -->
-+    <panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/>
-+
-+    <!-- for url bar autocomplete -->
-+    <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true">
-+#ifdef NIGHTLY_BUILD
-+      <hbox id="urlbar-search-footer" flex="1" align="stretch" pack="end">
-+        <button id="urlbar-search-settings" label="&changeSearchSettings.button;"
-+                oncommand="BrowserUITelemetry.countSearchSettingsEvent('urlbar'); openPreferences('paneSearch')"/>
-+      </hbox>
-+#endif
-+    </panel>
-+
-+    <!-- for select dropdowns. The menupopup is what shows the list of options,
-+         and the popuponly menulist makes things like the menuactive attributes
-+         work correctly on the menupopup. ContentSelectDropdown expects the
-+         popuponly menulist to be its immediate parent. -->
-+    <menulist popuponly="true" id="ContentSelectDropdown" hidden="true">
-+      <menupopup rolluponmousewheel="true"
-+                 activateontab="true"
-+#ifdef XP_WIN
-+                 consumeoutsideclicks="false" ignorekeys="handled"
-+#endif
-+        />
-+    </menulist>
-+
-+    <!-- for invalid form error message -->
-+    <panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
-+      <description/>
-+    </panel>
-+
-+    <panel id="editBookmarkPanel"
-+           type="arrow"
-+           footertype="promobox"
-+           orient="vertical"
-+           ignorekeys="true"
-+           hidden="true"
-+           onpopupshown="StarUI.panelShown(event);"
-+           aria-labelledby="editBookmarkPanelTitle">
-+      <row id="editBookmarkPanelHeader" align="center" hidden="true">
-+        <vbox align="center">
-+          <image id="editBookmarkPanelStarIcon"/>
-+        </vbox>
-+        <vbox>
-+          <label id="editBookmarkPanelTitle"/>
-+          <description id="editBookmarkPanelDescription"/>
-+          <hbox>
-+            <button id="editBookmarkPanelRemoveButton"
-+                    class="editBookmarkPanelHeaderButton"
-+                    oncommand="StarUI.removeBookmarkButtonCommand();"
-+                    accesskey="&editBookmark.removeBookmark.accessKey;"/>
-+          </hbox>
-+        </vbox>
-+      </row>
-+      <vbox id="editBookmarkPanelContent" flex="1" hidden="true"/>
-+      <hbox id="editBookmarkPanelBottomButtons" pack="end">
-+#ifdef XP_UNIX
-+        <button id="editBookmarkPanelDoneButton"
-+                class="editBookmarkPanelBottomButton"
-+                label="&editBookmark.done.label;"
-+                default="true"
-+                oncommand="StarUI.panel.hidePopup();"/>
-+        <button id="editBookmarkPanelDeleteButton"
-+                class="editBookmarkPanelBottomButton"
-+                label="&editBookmark.cancel.label;"
-+                oncommand="StarUI.cancelButtonOnCommand();"/>
-+#else
-+        <button id="editBookmarkPanelDeleteButton"
-+                class="editBookmarkPanelBottomButton"
-+                label="&editBookmark.cancel.label;"
-+                oncommand="StarUI.cancelButtonOnCommand();"/>
-+        <button id="editBookmarkPanelDoneButton"
-+                class="editBookmarkPanelBottomButton"
-+                label="&editBookmark.done.label;"
-+                default="true"
-+                oncommand="StarUI.panel.hidePopup();"/>
-+#endif
-+      </hbox>
-+    </panel>
-+
-+    <!-- UI tour experience -->
-+    <panel id="UITourTooltip"
-+           type="arrow"
-+           hidden="true"
-+           noautofocus="true"
-+           noautohide="true"
-+           align="start"
-+           orient="vertical"
-+           role="alert">
-+     <vbox>
-+      <hbox pack="end">
-+        <toolbarbutton id="UITourTooltipClose" class="close-icon"
-+                       tooltiptext="&uiTour.infoPanel.close;"/>
-+      </hbox>
-+      <hbox id="UITourTooltipBody">
-+        <vbox id="UITourTooltipIconContainer">
-+          <image id="UITourTooltipIcon"/>
-+        </vbox>
-+        <vbox flex="1">
-+          <label id="UITourTooltipTitle" flex="1"/>
-+          <description id="UITourTooltipDescription" flex="1"/>
-+        </vbox>
-+      </hbox>
-+      <hbox id="UITourTooltipButtons" flex="1" align="center"/>
-+     </vbox>
-+    </panel>
-+    <!-- type="default" forces frames to be created so that the panel's size can be determined -->
-+    <panel id="UITourHighlightContainer"
-+           type="default"
-+           hidden="true"
-+           noautofocus="true"
-+           noautohide="true"
-+           flip="none"
-+           consumeoutsideclicks="false"
-+           mousethrough="always">
-+      <box id="UITourHighlight"></box>
-+    </panel>
-+
-+    <panel id="abouthome-search-panel" orient="vertical" type="arrow" hidden="true"
-+           onclick="this.hidePopup()">
-+      <hbox id="abouthome-search-panel-manage"
-+            onclick="openPreferences('paneSearch')">
-+        <label>&changeSearchSettings.button;</label>
-+      </hbox>
-+    </panel>
-+
-+    <panel id="social-share-panel"
-+           class="social-panel"
-+           type="arrow"
-+           orient="vertical"
-+           onpopupshowing="SocialShare.onShowing()"
-+           onpopuphidden="SocialShare.onHidden()"
-+           hidden="true">
-+      <hbox class="social-share-toolbar">
-+        <toolbarbutton id="manage-share-providers" class="toolbarbutton share-provider-button"
-+                       tooltiptext="&social.addons.label;"
-+                       oncommand="BrowserOpenAddonsMgr('addons://list/service');
-+                                  this.parentNode.parentNode.hidePopup();"/>
-+        <arrowscrollbox id="social-share-provider-buttons" orient="horizontal" flex="1" pack="end">
-+          <toolbarbutton id="add-share-provider" class="toolbarbutton share-provider-button" type="radio"
-+                         group="share-providers" tooltiptext="&findShareServices.label;"
-+                         oncommand="SocialShare.showDirectory()"/>
-+        </arrowscrollbox>
-+      </hbox>
-+      <hbox id="share-container" flex="1"/>
-+    </panel>
-+
-+    <panel id="social-notification-panel"
-+           class="social-panel"
-+           type="arrow"
-+           hidden="true"
-+           noautofocus="true"/>
-+    <panel id="social-flyout-panel"
-+           class="social-panel"
-+           onpopupshown="SocialFlyout.onShown()"
-+           onpopuphidden="SocialFlyout.onHidden()"
-+           side="right"
-+           type="arrow"
-+           hidden="true"
-+           flip="slide"
-+           rolluponmousewheel="true"
-+           noautofocus="true"
-+           position="topcenter topright"/>
-+
-+    <panel id="loop-notification-panel"
-+           class="loop-panel social-panel"
-+           type="arrow"
-+           hidden="true"
-+           noautofocus="true"/>
-+
-+    <panel id="loop-panel"
-+           class="loop-panel social-panel"
-+           type="arrow"
-+           orient="horizontal"
-+           hidden="true"/>
-+
-+    <menupopup id="processHangOptions"
-+               onpopupshowing="ProcessHangMonitor.refreshMenu(window);">
-+      <menuitem id="processHangTerminateScript"
-+                oncommand="ProcessHangMonitor.terminateScript(window)"
-+                accesskey="&processHang.terminateScript.accessKey;"
-+                label="&processHang.terminateScript.label;"/>
-+      <menuitem id="processHangDebugScript"
-+                oncommand="ProcessHangMonitor.debugScript(window)"
-+                accesskey="&processHang.debugScript.accessKey;"
-+                label="&processHang.debugScript.label;"/>
-+      <menuitem id="processHangTerminatePlugin"
-+                oncommand="ProcessHangMonitor.terminatePlugin(window)"
-+                accesskey="&processHang.terminatePlugin.accessKey;"
-+                label="&processHang.terminatePlugin.label;"/>
-+      <menuitem id="processHangTerminateProcess"
-+                oncommand="ProcessHangMonitor.terminateProcess(window)"
-+                accesskey="&processHang.terminateProcess.accessKey;"
-+                label="&processHang.terminateProcess.label;"/>
-+    </menupopup>
-+
-+    <menupopup id="toolbar-context-menu"
-+               onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('viewToolbarsMenuSeparator'));">
-+      <menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
-+                accesskey="&customizeMenu.moveToPanel.accesskey;"
-+                label="&customizeMenu.moveToPanel.label;"
-+                contexttype="toolbaritem"
-+                class="customize-context-moveToPanel"/>
-+      <menuitem oncommand="gCustomizeMode.removeFromArea(document.popupNode)"
-+                accesskey="&customizeMenu.removeFromToolbar.accesskey;"
-+                label="&customizeMenu.removeFromToolbar.label;"
-+                contexttype="toolbaritem"
-+                class="customize-context-removeFromToolbar"/>
-+      <menuitem id="toolbar-context-reloadAllTabs"
-+                class="toolbaritem-tabsmenu"
-+                contexttype="tabbar"
-+                oncommand="gBrowser.reloadAllTabs();"
-+                label="&toolbarContextMenu.reloadAllTabs.label;"
-+                accesskey="&toolbarContextMenu.reloadAllTabs.accesskey;"/>
-+      <menuitem id="toolbar-context-bookmarkAllTabs"
-+                class="toolbaritem-tabsmenu"
-+                contexttype="tabbar"
-+                command="Browser:BookmarkAllTabs"
-+                label="&toolbarContextMenu.bookmarkAllTabs.label;"
-+                accesskey="&toolbarContextMenu.bookmarkAllTabs.accesskey;"/>
-+      <menuitem id="toolbar-context-undoCloseTab"
-+                class="toolbaritem-tabsmenu"
-+                contexttype="tabbar"
-+                label="&toolbarContextMenu.undoCloseTab.label;"
-+                accesskey="&toolbarContextMenu.undoCloseTab.accesskey;"
-+                observes="History:UndoCloseTab"/>
-+      <menuseparator/>
-+      <menuseparator id="viewToolbarsMenuSeparator"/>
-+      <!-- XXXgijs: we're using oncommand handler here to avoid the event being
-+                    redirected to the command element, thus preventing
-+                    listeners on the menupopup or further up the tree from
-+                    seeing the command event pass by. The observes attribute is
-+                    here so that the menuitem is still disabled and re-enabled
-+                    correctly. -->
-+      <menuitem oncommand="BrowserCustomizeToolbar()"
-+                observes="cmd_CustomizeToolbars"
-+                class="viewCustomizeToolbar"
-+                label="&viewCustomizeToolbar.label;"
-+                accesskey="&viewCustomizeToolbar.accesskey;"/>
-+    </menupopup>
-+
-+    <menupopup id="blockedPopupOptions"
-+               onpopupshowing="gPopupBlockerObserver.fillPopupList(event);"
-+               onpopuphiding="gPopupBlockerObserver.onPopupHiding(event);">
-+      <menuitem observes="blockedPopupAllowSite"/>
-+      <menuitem observes="blockedPopupEditSettings"/>
-+      <menuitem observes="blockedPopupDontShowMessage"/>
-+      <menuseparator observes="blockedPopupsSeparator"/>
-+    </menupopup>
-+
-+    <menupopup id="autohide-context"
-+           onpopupshowing="FullScreen.getAutohide(this.firstChild);">
-+      <menuitem type="checkbox" label="&fullScreenAutohide.label;"
-+                accesskey="&fullScreenAutohide.accesskey;"
-+                oncommand="FullScreen.setAutohide();"/>
-+      <menuseparator/>
-+      <menuitem label="&fullScreenExit.label;"
-+                accesskey="&fullScreenExit.accesskey;"
-+                oncommand="BrowserFullScreen();"/>
-+    </menupopup>
-+
-+    <menupopup id="contentAreaContextMenu" pagemenu="#page-menu-separator"
-+               onpopupshowing="if (event.target != this)
-+                                 return true;
-+                               gContextMenu = new nsContextMenu(this, event.shiftKey);
-+                               if (gContextMenu.shouldDisplay)
-+                                 updateEditUIVisibility();
-+                               return gContextMenu.shouldDisplay;"
-+               onpopuphiding="if (event.target != this)
-+                                return;
-+                              gContextMenu.hiding();
-+                              gContextMenu = null;
-+                              updateEditUIVisibility();">
-+#include browser-context.inc
-+    </menupopup>
-+
-+    <menupopup id="placesContext"/>
-+
-+    <panel id="ctrlTab-panel" class="KUI-panel" hidden="true" norestorefocus="true" level="top">
-+      <hbox>
-+        <button class="ctrlTab-preview" flex="1"/>
-+        <button class="ctrlTab-preview" flex="1"/>
-+        <button class="ctrlTab-preview" flex="1"/>
-+        <button class="ctrlTab-preview" flex="1"/>
-+        <button class="ctrlTab-preview" flex="1"/>
-+        <button class="ctrlTab-preview" flex="1"/>
-+      </hbox>
-+      <hbox pack="center">
-+        <button id="ctrlTab-showAll" class="ctrlTab-preview" noicon="true"/>
-+      </hbox>
-+    </panel>
-+
-+    <!-- Sync Panel -->
-+    <panel id="sync-start-panel" class="sync-panel" type="arrow" hidden="true"
-+           noautofocus="true" onclick="this.hidePopup();"
-+           flip="slide">
-+      <hbox class="sync-panel-outer">
-+        <image class="sync-panel-icon"/>
-+        <vbox class="sync-panel-inner">
-+          <description id="sync-start-panel-title"
-+                       value="&syncStartPanel2.heading;"/>
-+          <description id="sync-start-panel-subtitle"
-+                       value="&syncStartPanel2.subTitle;"/>
-+        </vbox>
-+      </hbox>
-+    </panel>
-+
-+    <!-- Bookmarks and history tooltip -->
-+    <tooltip id="bhTooltip"/>
-+
-+    <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
-+
-+    <tooltip id="back-button-tooltip">
-+      <label class="tooltip-label" value="&backButton.tooltip;"/>
-+#ifdef XP_MACOSX
-+      <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
-+#else
-+      <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
-+#endif
-+    </tooltip>
-+
-+    <tooltip id="forward-button-tooltip">
-+      <label class="tooltip-label" value="&forwardButton.tooltip;"/>
-+#ifdef XP_MACOSX
-+      <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
-+#else
-+      <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
-+#endif
-+    </tooltip>
-+
-+    <tooltip id="share-button-tooltip" onpopupshowing="SocialShare.createTooltip(event);">
-+      <label class="tooltip-label"/>
-+      <label class="tooltip-label"/>
-+    </tooltip>
-+
-+#include popup-notifications.inc
-+
-+#include ../../components/customizableui/content/panelUI.inc.xul
-+#include ../../components/controlcenter/content/panel.inc.xul
-+
-+    <hbox id="downloads-animation-container" mousethrough="always">
-+      <vbox id="downloads-notification-anchor">
-+        <vbox id="downloads-indicator-notification"/>
-+      </vbox>
-+    </hbox>
-+
-+    <hbox id="bookmarked-notification-container" mousethrough="always">
-+      <vbox id="bookmarked-notification-anchor">
-+        <vbox id="bookmarked-notification"/>
-+      </vbox>
-+      <vbox id="bookmarked-notification-dropmarker-anchor">
-+        <image id="bookmarked-notification-dropmarker-icon"/>
-+      </vbox>
-+    </hbox>
-+
-+    <tooltip id="dynamic-shortcut-tooltip"
-+             onpopupshowing="UpdateDynamicShortcutTooltipText(this);"/>
-+
-+    <menupopup id="emeNotificationsPopup">
-+      <menuitem id="emeNotificationsNotNow"
-+                label="&emeNotificationsNotNow.label;"
-+                acceskey="&emeNotificationsNotNow.accesskey;"
-+                oncommand="gEMEHandler.onNotNow(this);"/>
-+      <menuitem id="emeNotificationsDontAskAgain"
-+                label="&emeNotificationsDontAskAgain.label;"
-+                acceskey="&emeNotificationsDontAskAgain.accesskey;"
-+                oncommand="gEMEHandler.onDontAskAgain(this);"/>
-+    </menupopup>
-+  </popupset>
-+
-+#ifdef CAN_DRAW_IN_TITLEBAR
-+<vbox id="titlebar">
-+  <hbox id="titlebar-content">
-+    <spacer id="titlebar-spacer" flex="1"/>
-+    <hbox id="titlebar-buttonbox-container">
-+#ifdef XP_WIN
-+      <hbox id="private-browsing-indicator-titlebar">
-+        <hbox class="private-browsing-indicator"/>
-+      </hbox>
-+#endif
-+      <hbox id="titlebar-buttonbox">
-+        <toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
-+        <toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
-+        <toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
-+      </hbox>
-+    </hbox>
-+#ifdef XP_MACOSX
-+    <!-- OS X does not natively support RTL for its titlebar items, so we prevent this secondary
-+         buttonbox from reversing order in RTL by forcing an LTR direction. -->
-+    <hbox id="titlebar-secondary-buttonbox" dir="ltr">
-+      <hbox class="private-browsing-indicator"/>
-+      <hbox id="titlebar-fullscreen-button"/>
-+    </hbox>
-+#endif
-+  </hbox>
-+</vbox>
-+#endif
-+
-+<deck flex="1" id="tab-view-deck">
-+<vbox flex="1" id="browser-panel">
-+
-+  <toolbox id="navigator-toolbox" mode="icons">
-+    <!-- Menu -->
-+    <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
-+             defaultset="menubar-items"
-+             mode="icons" iconsize="small"
-+#ifdef MENUBAR_CAN_AUTOHIDE
-+             toolbarname="&menubarCmd.label;"
-+             accesskey="&menubarCmd.accesskey;"
-+#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
-+             autohide="true"
-+#endif
-+#endif
-+             context="toolbar-context-menu">
-+      <toolbaritem id="menubar-items" align="center">
-+# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
-+# hiddenWindow.xul.
-+#include browser-menubar.inc
-+      </toolbaritem>
-+
-+#ifdef CAN_DRAW_IN_TITLEBAR
-+#ifndef XP_MACOSX
-+      <hbox class="titlebar-placeholder" type="caption-buttons" ordinal="1000"
-+            id="titlebar-placeholder-on-menubar-for-caption-buttons" persist="width"
-+            skipintoolbarset="true"/>
-+#endif
-+#endif
-+    </toolbar>
-+
-+    <toolbar id="TabsToolbar"
-+             fullscreentoolbar="true"
-+             customizable="true"
-+             mode="icons"
-+             iconsize="small"
-+             aria-label="&tabsToolbar.label;"
-+             context="toolbar-context-menu"
-+             defaultset="tabbrowser-tabs,new-tab-button,alltabs-button"
-+             collapsed="true">
-+
-+#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
-+      <hbox id="private-browsing-indicator"
-+            skipintoolbarset="true"/>
-+#endif
-+
-+      <tabs id="tabbrowser-tabs"
-+            class="tabbrowser-tabs"
-+            tabbrowser="content"
-+            flex="1"
-+            setfocus="false"
-+            tooltip="tabbrowser-tab-tooltip"
-+            stopwatchid="FX_TAB_CLICK_MS">
-+        <tab class="tabbrowser-tab" selected="true" visuallyselected="true" fadein="true"/>
-+      </tabs>
-+
-+      <toolbarbutton id="new-tab-button"
-+                     class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                     label="&tabCmd.label;"
-+                     command="cmd_newNavigatorTab"
-+                     onclick="checkForMiddleClick(this, event);"
-+                     tooltip="dynamic-shortcut-tooltip"
-+                     ondrop="newTabButtonObserver.onDrop(event)"
-+                     ondragover="newTabButtonObserver.onDragOver(event)"
-+                     ondragenter="newTabButtonObserver.onDragOver(event)"
-+                     ondragexit="newTabButtonObserver.onDragExit(event)"
-+                     cui-areatype="toolbar"
-+                     removable="true"/>
-+
-+      <toolbarbutton id="alltabs-button"
-+                     class="toolbarbutton-1 chromeclass-toolbar-additional tabs-alltabs-button"
-+                     type="menu"
-+                     label="&listAllTabs.label;"
-+                     tooltiptext="&listAllTabs.label;"
-+                     removable="false">
-+        <menupopup id="alltabs-popup"
-+                   position="after_end">
-+          <menuitem id="menu_tabview"
-+                    class="menuitem-iconic"
-+                    key="key_tabview"
-+                    label="&viewTabGroups.label;"
-+                    command="Browser:ToggleTabView"
-+                    observes="tabviewGroupsNumber"/>
-+          <menuitem id="alltabs_undoCloseTab"
-+                    class="menuitem-iconic"
-+                    key="key_undoCloseTab"
-+                    label="&undoCloseTab.label;"
-+                    observes="History:UndoCloseTab"/>
-+          <menuseparator id="alltabs-popup-separator"/>
-+        </menupopup>
-+      </toolbarbutton>
-+
-+#if !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_QT)
-+      <hbox class="private-browsing-indicator" skipintoolbarset="true"/>
-+#endif
-+#ifdef CAN_DRAW_IN_TITLEBAR
-+      <hbox class="titlebar-placeholder" type="caption-buttons"
-+            id="titlebar-placeholder-on-TabsToolbar-for-captions-buttons" persist="width"
-+#ifndef XP_MACOSX
-+            ordinal="1000"
-+#endif
-+            skipintoolbarset="true"/>
-+
-+#ifdef XP_MACOSX
-+      <hbox class="titlebar-placeholder" type="fullscreen-button"
-+            id="titlebar-placeholder-on-TabsToolbar-for-fullscreen-button" persist="width"
-+            skipintoolbarset="true"/>
-+#endif
-+#endif
-+    </toolbar>
-+
-+    <!--
-+           CAVEAT EMPTOR
-+           Should you need to add items to the toolbar here, make sure to also add them
-+           to the default placements of buttons in CustomizableUI.jsm, so the
-+           customization code doesn't get confused.
-+      -->
-+    <toolbar id="nav-bar"
-+             aria-label="&navbarCmd.label;"
-+             fullscreentoolbar="true" mode="icons" customizable="true"
-+             iconsize="small"
-+#ifdef MOZ_DEV_EDITION
-+             defaultset="urlbar-container,search-container,developer-button,bookmarks-menu-button,pocket-button,downloads-button,home-button,loop-button"
-+#else
-+             defaultset="urlbar-container,search-container,bookmarks-menu-button,pocket-button,downloads-button,home-button,loop-button"
-+#endif
-+             customizationtarget="nav-bar-customization-target"
-+             overflowable="true"
-+             overflowbutton="nav-bar-overflow-button"
-+             overflowtarget="widget-overflow-list"
-+             overflowpanel="widget-overflow"
-+             context="toolbar-context-menu">
-+
-+      <hbox id="nav-bar-customization-target" flex="1">
-+        <toolbaritem id="urlbar-container" flex="400" persist="width"
-+                     removable="false"
-+                     class="chromeclass-location" overflows="false">
-+          <toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                         label="&backCmd.label;"
-+                         command="Browser:BackOrBackDuplicate"
-+                         onclick="checkForMiddleClick(this, event);"
-+                         tooltip="back-button-tooltip"
-+                         context="backForwardMenu"/>
-+          <hbox id="urlbar-wrapper" flex="1">
-+            <toolbarbutton id="forward-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                           label="&forwardCmd.label;"
-+                           command="Browser:ForwardOrForwardDuplicate"
-+                           onclick="checkForMiddleClick(this, event);"
-+                           tooltip="forward-button-tooltip"
-+                           context="backForwardMenu"/>
-+            <textbox id="urlbar" flex="1"
-+                     placeholder="&urlbar.placeholder2;"
-+                     type="autocomplete"
-+                     autocompletesearch="urlinline history"
-+                     autocompletesearchparam="enable-actions"
-+                     autocompletepopup="PopupAutoCompleteRichResult"
-+                     completeselectedindex="true"
-+                     shrinkdelay="250"
-+                     tabscrolling="true"
-+                     showcommentcolumn="true"
-+                     showimagecolumn="true"
-+                     enablehistory="true"
-+                     maxrows="6"
-+                     newlines="stripsurroundingwhitespace"
-+                     ontextentered="this.handleCommand(param);"
-+                     ontextreverted="return this.handleRevert();"
-+                     pageproxystate="invalid"
-+                     onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
-+                     onblur="setTimeout(() => { document.getElementById('identity-box').style.MozUserFocus = ''; }, 0);">
-+              <box id="notification-popup-box" hidden="true" align="center">
-+                <image id="default-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.defaultNotificationAnchor.label;"/>
-+                <!-- NB: the identity-notification-icon is used for persona-based auth and preffed
-+                     off by default. It hasn't been updated for some time and liable to being
-+                     removed.-->
-+                <image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
-+                <image id="geo-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.geolocationNotificationAnchor.label;"/>
-+                <image id="addons-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.addonsNotificationAnchor.label;"/>
-+                <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.indexedDBNotificationAnchor.label;"/>
-+                <image id="login-fill-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.loginFillNotificationAnchor.label;"/>
-+                <image id="password-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.passwordNotificationAnchor.label;"/>
-+                <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webappsNotificationAnchor.label;"/>
-+                <image id="plugins-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.pluginsNotificationAnchor.label;"/>
-+                <image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webNotsNotificationAnchor.label;"/>
-+                <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCShareDevicesNotificationAnchor.label;"/>
-+                <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCSharingDevicesNotificationAnchor.label;"/>
-+                <image id="webRTC-shareMicrophone-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCShareMicrophoneNotificationAnchor.label;"/>
-+                <image id="webRTC-sharingMicrophone-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCSharingMicrophoneNotificationAnchor.label;"/>
-+                <image id="webRTC-shareScreen-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCShareScreenNotificationAnchor.label;"/>
-+                <image id="webRTC-sharingScreen-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.webRTCSharingScreenNotificationAnchor.label;"/>
-+                <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.pointerLockNotificationAnchor.label;"/>
-+                <image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.servicesNotificationAnchor.label;"/>
-+                <image id="translate-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.translateNotificationAnchor.label;"/>
-+                <image id="translated-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.translatedNotificationAnchor.label;"/>
-+                <image id="eme-notification-icon" class="notification-anchor-icon" role="button"
-+                       aria-label="&urlbar.emeNotificationAnchor.label;"/>
-+              </box>
-+              <!-- Use onclick instead of normal popup= syntax since the popup
-+                   code fires onmousedown, and hence eats our favicon drag events.
-+                   We only add the identity-box button to the tab order when the location bar
-+                   has focus, otherwise pressing F6 focuses it instead of the location bar -->
-+              <box id="identity-box" role="button"
-+                   align="center"
-+                   aria-label="&urlbar.viewSiteInfo.label;"
-+                   onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
-+                   onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
-+                   ondragstart="gIdentityHandler.onDragStart(event);">
-+                <hbox id="identity-icons"
-+                      consumeanchor="identity-box">
-+                  <image id="tracking-protection-icon"/>
-+                  <image id="page-proxy-favicon"
-+                         onclick="PageProxyClickHandler(event);"
-+                         pageproxystate="invalid"/>
-+                </hbox>
-+                <hbox id="identity-icon-labels">
-+                  <label id="identity-icon-label" class="plain" flex="1"/>
-+                  <label id="identity-icon-country-label" class="plain"/>
-+                </hbox>
-+              </box>
-+              <box id="urlbar-display-box" align="center">
-+                <label class="urlbar-display urlbar-display-switchtab" value="&urlbar.switchToTab.label;"/>
-+              </box>
-+              <hbox id="urlbar-icons">
-+                <image id="page-report-button"
-+                       class="urlbar-icon"
-+                       hidden="true"
-+                       tooltiptext="&pageReportIcon.tooltip;"
-+                       onclick="gPopupBlockerObserver.onReportButtonClick(event);"/>
-+                <image id="reader-mode-button"
-+                       class="urlbar-icon"
-+                       hidden="true"
-+                       onclick="ReaderParent.buttonClick(event);"/>
-+              </hbox>
-+              <hbox id="userContext-icons">
-+                <label id="userContext-label"/>
-+                <image id="userContext-indicator"/>
-+              </hbox>
-+              <toolbarbutton id="urlbar-go-button"
-+                             class="chromeclass-toolbar-additional"
-+                             onclick="gURLBar.handleCommand(event);"
-+                             tooltiptext="&goEndCap.tooltip;"/>
-+              <toolbarbutton id="urlbar-reload-button"
-+                             class="chromeclass-toolbar-additional"
-+                             command="Browser:ReloadOrDuplicate"
-+                             onclick="checkForMiddleClick(this, event);"
-+                             tooltiptext="&reloadButton.tooltip;"/>
-+              <toolbarbutton id="urlbar-stop-button"
-+                             class="chromeclass-toolbar-additional"
-+                             command="Browser:Stop"
-+                             tooltiptext="&stopButton.tooltip;"/>
-+            </textbox>
-+          </hbox>
-+        </toolbaritem>
-+
-+        <toolbaritem id="search-container" title="&searchItem.title;"
-+                     align="center" class="chromeclass-toolbar-additional panel-wide-item"
-+                     cui-areatype="toolbar"
-+                     flex="100" persist="width" removable="true">
-+          <searchbar id="searchbar" flex="1"/>
-+        </toolbaritem>
-+
-+        <toolbarbutton id="bookmarks-menu-button"
-+                       class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                       removable="true"
-+                       type="menu-button"
-+                       label="&bookmarksMenuButton.label;"
-+                       tooltip="dynamic-shortcut-tooltip"
-+                       anchor="dropmarker"
-+                       ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
-+                       ondragover="PlacesMenuDNDHandler.onDragOver(event);"
-+                       ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
-+                       ondrop="PlacesMenuDNDHandler.onDrop(event);"
-+                       cui-areatype="toolbar"
-+                       oncommand="BookmarkingUI.onCommand(event);">
-+          <observes element="bookmarkThisPageBroadcaster" attribute="starred"/>
-+          <observes element="bookmarkThisPageBroadcaster" attribute="buttontooltiptext"/>
-+          <menupopup id="BMB_bookmarksPopup"
-+                     class="cui-widget-panel cui-widget-panelview cui-widget-panelWithFooter PanelUI-subView"
-+                     placespopup="true"
-+                     context="placesContext"
-+                     openInTabs="children"
-+                     oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
-+                     onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
-+                     onpopupshowing="BookmarkingUI.onPopupShowing(event);
-+                                     BookmarkingUI.updatePocketItemVisibility('BMB_');
-+                                     BookmarkingUI.attachPlacesView(event, this);"
-+                     tooltip="bhTooltip" popupsinherittooltip="true">
-+            <menuitem id="BMB_viewBookmarksSidebar"
-+                      class="subviewbutton"
-+                      label="&viewBookmarksSidebar2.label;"
-+                      type="checkbox"
-+                      oncommand="SidebarUI.toggle('viewBookmarksSidebar');">
-+              <observes element="viewBookmarksSidebar" attribute="checked"/>
-+            </menuitem>
-+            <!-- NB: temporary solution for bug 985024, this should go away soon. -->
-+            <menuitem id="BMB_bookmarksShowAllTop"
-+                      class="menuitem-iconic subviewbutton"
-+                      label="&showAllBookmarks2.label;"
-+                      command="Browser:ShowAllBookmarks"
-+                      key="manBookmarkKb"/>
-+            <menuseparator/>
-+            <menuitem id="BMB_pocket"
-+                      class="menuitem-iconic bookmark-item subviewbutton"
-+                      label="&pocketMenuitem.label;"
-+                      oncommand="openUILink(Pocket.listURL, event);"/>
-+            <menuseparator id="BMB_pocketSeparator"/>
-+            <menuitem id="BMB_subscribeToPageMenuitem"
-+#ifndef XP_MACOSX
-+                      class="menuitem-iconic subviewbutton"
-+#else
-+                      class="subviewbutton"
-+#endif
-+                      label="&subscribeToPageMenuitem.label;"
-+                      oncommand="return FeedHandler.subscribeToFeed(null, event);"
-+                      onclick="checkForMiddleClick(this, event);"
-+                      observes="singleFeedMenuitemState"/>
-+            <menu id="BMB_subscribeToPageMenupopup"
-+#ifndef XP_MACOSX
-+                  class="menu-iconic subviewbutton"
-+#else
-+                  class="subviewbutton"
-+#endif
-+                  label="&subscribeToPageMenupopup.label;"
-+                  observes="multipleFeedsMenuState">
-+              <menupopup id="BMB_subscribeToPageSubmenuMenupopup"
-+                         onpopupshowing="return FeedHandler.buildFeedList(event.target);"
-+                         oncommand="return FeedHandler.subscribeToFeed(null, event);"
-+                         onclick="checkForMiddleClick(this, event);"/>
-+            </menu>
-+            <menuseparator/>
-+            <menu id="BMB_bookmarksToolbar"
-+                  class="menu-iconic bookmark-item subviewbutton"
-+                  label="&personalbarCmd.label;"
-+                  container="true">
-+              <menupopup id="BMB_bookmarksToolbarPopup"
-+                         placespopup="true"
-+                         context="placesContext"
-+                         onpopupshowing="if (!this.parentNode._placesView)
-+                                           new PlacesMenu(event, 'place:folder=TOOLBAR',
-+                                                          PlacesUIUtils.getViewForNode(this.parentNode.parentNode).options);">
-+                <menuitem id="BMB_viewBookmarksToolbar"
-+                          placesanonid="view-toolbar"
-+                          toolbarId="PersonalToolbar"
-+                          type="checkbox"
-+                          oncommand="onViewToolbarCommand(event)"
-+                          label="&viewBookmarksToolbar.label;"/>
-+                <menuseparator/>
-+                <!-- Bookmarks toolbar items -->
-+              </menupopup>
-+            </menu>
-+            <menu id="BMB_unsortedBookmarks"
-+                  class="menu-iconic bookmark-item subviewbutton"
-+                  label="&bookmarksMenuButton.unsorted.label;"
-+                  container="true">
-+              <menupopup id="BMB_unsortedBookmarksPopup"
-+                         placespopup="true"
-+                         context="placesContext"
-+                         onpopupshowing="if (!this.parentNode._placesView)
-+                                           new PlacesMenu(event, 'place:folder=UNFILED_BOOKMARKS',
-+                                                          PlacesUIUtils.getViewForNode(this.parentNode.parentNode).options);"/>
-+            </menu>
-+            <menuseparator/>
-+            <!-- Bookmarks menu items will go here -->
-+            <menuitem id="BMB_bookmarksShowAll"
-+                      class="subviewbutton panel-subview-footer"
-+                      label="&showAllBookmarks2.label;"
-+                      command="Browser:ShowAllBookmarks"
-+                      key="manBookmarkKb"/>
-+          </menupopup>
-+        </toolbarbutton>
-+
-+        <!-- This is a placeholder for the Downloads Indicator.  It is visible
-+             during the customization of the toolbar, in the palette, and before
-+             the Downloads Indicator overlay is loaded. -->
-+        <toolbarbutton id="downloads-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                       key="key_openDownloads"
-+                       oncommand="DownloadsIndicatorView.onCommand(event);"
-+                       ondrop="DownloadsIndicatorView.onDrop(event);"
-+                       ondragover="DownloadsIndicatorView.onDragOver(event);"
-+                       ondragenter="DownloadsIndicatorView.onDragOver(event);"
-+                       label="&downloads.label;"
-+                       removable="true"
-+                       cui-areatype="toolbar"
-+                       tooltip="dynamic-shortcut-tooltip"/>
-+
-+        <toolbarbutton id="home-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                       removable="true"
-+                       label="&homeButton.label;"
-+                       ondragover="homeButtonObserver.onDragOver(event)"
-+                       ondragenter="homeButtonObserver.onDragOver(event)"
-+                       ondrop="homeButtonObserver.onDrop(event)"
-+                       ondragexit="homeButtonObserver.onDragExit(event)"
-+                       key="goHome"
-+                       onclick="BrowserGoHome(event);"
-+                       cui-areatype="toolbar"
-+                       aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
-+      </hbox>
-+
-+      <toolbarbutton id="nav-bar-overflow-button"
-+                     class="toolbarbutton-1 chromeclass-toolbar-additional overflow-button"
-+                     skipintoolbarset="true"
-+                     tooltiptext="&navbarOverflow.label;"/>
-+
-+      <toolbaritem id="PanelUI-button"
-+                   class="chromeclass-toolbar-additional"
-+                   removable="false">
-+        <toolbarbutton id="PanelUI-menu-button"
-+                       class="toolbarbutton-1 badged-button"
-+                       consumeanchor="PanelUI-button"
-+                       label="&brandShortName;"
-+                       tooltiptext="&appmenu.tooltip;"/>
-+      </toolbaritem>
-+
-+      <hbox id="window-controls" hidden="true" pack="end" skipintoolbarset="true"
-+            ordinal="1000">
-+        <toolbarbutton id="minimize-button"
-+                       tooltiptext="&fullScreenMinimize.tooltip;"
-+                       oncommand="window.minimize();"/>
-+
-+        <toolbarbutton id="restore-button"
-+#ifdef XP_MACOSX
-+# Prior to 10.7 there wasn't a native fullscreen button so we use #restore-button
-+# to exit fullscreen and want it to behave like other toolbar buttons.
-+                       class="toolbarbutton-1"
-+#endif
-+                       tooltiptext="&fullScreenRestore.tooltip;"
-+                       oncommand="BrowserFullScreen();"/>
-+
-+        <toolbarbutton id="close-button"
-+                       tooltiptext="&fullScreenClose.tooltip;"
-+                       oncommand="BrowserTryToCloseWindow();"/>
-+      </hbox>
-+    </toolbar>
-+
-+    <toolbarset id="customToolbars" context="toolbar-context-menu"/>
-+
-+    <toolbar id="PersonalToolbar"
-+             mode="icons" iconsize="small"
-+             class="chromeclass-directories"
-+             context="toolbar-context-menu"
-+             defaultset="personal-bookmarks"
-+             toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
-+             collapsed="true"
-+             customizable="true">
-+      <toolbaritem id="personal-bookmarks"
-+                   title="&bookmarksToolbarItem.label;"
-+                   cui-areatype="toolbar"
-+                   removable="true">
-+        <toolbarbutton id="bookmarks-toolbar-placeholder"
-+                       class="toolbarbutton-1"
-+                       mousethrough="never"
-+                       label="&bookmarksToolbarItem.label;"
-+                       oncommand="PlacesToolbarHelper.onPlaceholderCommand();"/>
-+        <hbox flex="1"
-+              id="PlacesToolbar"
-+              context="placesContext"
-+              onclick="BookmarksEventHandler.onClick(event, this._placesView);"
-+              oncommand="BookmarksEventHandler.onCommand(event, this._placesView);"
-+              tooltip="bhTooltip"
-+              popupsinherittooltip="true">
-+          <hbox flex="1">
-+            <hbox id="PlacesToolbarDropIndicatorHolder" align="center" collapsed="true">
-+              <image id="PlacesToolbarDropIndicator"
-+                     mousethrough="always"
-+                     collapsed="true"/>
-+            </hbox>
-+            <scrollbox orient="horizontal"
-+                       id="PlacesToolbarItems"
-+                       flex="1"/>
-+            <toolbarbutton type="menu"
-+                           id="PlacesChevron"
-+                           class="chevron"
-+                           mousethrough="never"
-+                           collapsed="true"
-+                           tooltiptext="&bookmarksToolbarChevron.tooltip;"
-+                           onpopupshowing="document.getElementById('PlacesToolbar')
-+                                                   ._placesView._onChevronPopupShowing(event);">
-+              <menupopup id="PlacesChevronPopup"
-+                         placespopup="true"
-+                         tooltip="bhTooltip" popupsinherittooltip="true"
-+                         context="placesContext"/>
-+            </toolbarbutton>
-+          </hbox>
-+        </hbox>
-+      </toolbaritem>
-+    </toolbar>
-+
-+    <!-- This is a shim which will go away ASAP. See bug 749804 for details -->
-+    <toolbar id="addon-bar" toolbar-delegate="nav-bar" mode="icons" iconsize="small"
-+             customizable="true">
-+      <hbox id="addonbar-closebutton"/>
-+      <statusbar id="status-bar"/>
-+    </toolbar>
-+
-+    <toolbarpalette id="BrowserToolbarPalette">
-+
-+# Update primaryToolbarButtons in browser/themes/shared/browser.inc when adding
-+# or removing default items with the toolbarbutton-1 class.
-+
-+      <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+#ifdef XP_MACOSX
-+                     command="cmd_print"
-+                     tooltip="dynamic-shortcut-tooltip"
-+#else
-+                     command="cmd_printPreview"
-+                     tooltiptext="&printButton.tooltip;"
-+#endif
-+                     label="&printButton.label;"/>
-+
-+
-+      <toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                     label="&newNavigatorCmd.label;"
-+                     command="key_newNavigator"
-+                     tooltip="dynamic-shortcut-tooltip"
-+                     ondrop="newWindowButtonObserver.onDrop(event)"
-+                     ondragover="newWindowButtonObserver.onDragOver(event)"
-+                     ondragenter="newWindowButtonObserver.onDragOver(event)"
-+                     ondragexit="newWindowButtonObserver.onDragExit(event)"/>
-+
-+      <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                     observes="View:FullScreen"
-+                     type="checkbox"
-+                     label="&fullScreenCmd.label;"
-+                     tooltip="dynamic-shortcut-tooltip"/>
-+
-+#ifdef MOZ_SERVICES_SYNC
-+      <toolbarbutton id="sync-button"
-+                     class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                     label="&syncToolbarButton.label;"
-+                     oncommand="gSyncUI.handleToolbarButton()"/>
-+#endif
-+
-+      <toolbarbutton id="tabview-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-+                     label="&tabGroupsButton.label;"
-+                     command="Browser:ToggleTabView"
-+                     tooltip="dynamic-shortcut-tooltip"
-+                     observes="tabviewGroupsNumber"/>
-+    </toolbarpalette>
-+  </toolbox>
-+
-+  <hbox id="fullscr-toggler" hidden="true"/>
-+
-+  <deck id="content-deck" flex="1">
-+    <hbox flex="1" id="browser">
-+      <vbox id="browser-border-start" hidden="true" layer="true"/>
-+      <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
-+        <sidebarheader id="sidebar-header" align="center">
-+          <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
-+          <image id="sidebar-throbber"/>
-+          <toolbarbutton class="close-icon tabbable" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="SidebarUI.hide();"/>
-+        </sidebarheader>
-+        <browser id="sidebar" flex="1" autoscroll="false" disablehistory="true"
-+                  style="min-width: 14em; width: 18em; max-width: 36em;" tooltip="aHTMLTooltip"/>
-+      </vbox>
-+
-+      <splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" hidden="true"/>
-+      <vbox id="appcontent" flex="1">
-+        <notificationbox id="high-priority-global-notificationbox" notificationside="top"/>
-+        <tabbrowser id="content"
-+                    flex="1" contenttooltip="aHTMLTooltip"
-+                    tabcontainer="tabbrowser-tabs"
-+                    contentcontextmenu="contentAreaContextMenu"
-+                    autocompletepopup="PopupAutoComplete"
-+                    selectmenulist="ContentSelectDropdown"/>
-+        <chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
-+      </vbox>
-+      <splitter id="social-sidebar-splitter"
-+                class="chromeclass-extrachrome sidebar-splitter"
-+                observes="socialSidebarBroadcaster"/>
-+      <vbox id="social-sidebar-box"
-+            class="chromeclass-extrachrome"
-+            observes="socialSidebarBroadcaster"
-+            persist="width">
-+
-+        <sidebarheader id="social-sidebar-header" class="sidebar-header" align="center">
-+          <image id="social-sidebar-favico"/>
-+          <label id="social-sidebar-title" class="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
-+          <toolbarbutton id="social-sidebar-button"
-+                         class="toolbarbutton-1"
-+                         type="menu">
-+            <menupopup id="social-statusarea-popup" position="after_end">
-+              <menuitem class="social-toggle-sidebar-menuitem"
-+                        type="checkbox"
-+                        autocheck="false"
-+                        command="Social:ToggleSidebar"
-+                        label="&social.toggleSidebar.label;"
-+                        accesskey="&social.toggleSidebar.accesskey;"/>
-+              <menuitem class="social-toggle-notifications-menuitem"
-+                        type="checkbox"
-+                        autocheck="false"
-+                        command="Social:ToggleNotifications"
-+                        label="&social.toggleNotifications.label;"
-+                        accesskey="&social.toggleNotifications.accesskey;"/>
-+              <menuseparator/>
-+              <menuseparator class="social-provider-menu" hidden="true"/>
-+              <menuitem class="social-addons-menuitem" command="Social:Addons"
-+                        label="&social.addons.label;"/>
-+              <menuitem label="&social.learnMore.label;"
-+                        accesskey="&social.learnMore.accesskey;"
-+                        oncommand="SocialUI.showLearnMore();"/>
-+            </menupopup>
-+          </toolbarbutton>
-+        </sidebarheader>
-+
-+        <browser id="social-sidebar-browser"
-+                 type="content"
-+                 context="contentAreaContextMenu"
-+                 message="true"
-+                 messagemanagergroup="social"
-+                 disableglobalhistory="true"
-+                 tooltip="aHTMLTooltip"
-+                 popupnotificationanchor="social-sidebar-favico"
-+                 flex="1"
-+                 style="min-width: 14em; width: 18em; max-width: 36em;"/>
-+      </vbox>
-+      <vbox id="browser-border-end" hidden="true" layer="true"/>
-+    </hbox>
-+#include ../../components/customizableui/content/customizeMode.inc.xul
-+  </deck>
-+
-+  <html:div id="fullscreen-warning" hidden="true">
-+    <html:div id="fullscreen-domain-text">
-+      &fullscreenWarning.beforeDomain.label;
-+      <html:span id="fullscreen-domain"/>
-+      &fullscreenWarning.afterDomain.label;
-+    </html:div>
-+    <html:div id="fullscreen-generic-text">
-+      &fullscreenWarning.generic.label;
-+    </html:div>
-+    <html:button id="fullscreen-exit-button"
-+                 onclick="FullScreen.exitDomFullScreen();">
-+#ifdef XP_MACOSX
-+            &exitDOMFullscreenMac.button;
-+#else
-+            &exitDOMFullscreen.button;
-+#endif
-+    </html:button>
-+  </html:div>
-+
-+  <vbox id="browser-bottombox" layer="true">
-+    <notificationbox id="global-notificationbox" notificationside="bottom"/>
-+    <toolbar id="developer-toolbar"
-+             hidden="true">
-+#ifdef XP_MACOSX
-+          <toolbarbutton id="developer-toolbar-closebutton"
-+                         class="devtools-closebutton"
-+                         oncommand="DeveloperToolbar.hide();"
-+                         tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
-+#endif
-+          <stack class="gclitoolbar-stack-node" flex="1">
-+            <textbox class="gclitoolbar-input-node" rows="1"/>
-+            <hbox class="gclitoolbar-complete-node"/>
-+          </stack>
-+          <toolbarbutton id="developer-toolbar-toolbox-button"
-+                         class="developer-toolbar-button"
-+                         observes="devtoolsMenuBroadcaster_DevToolbox"
-+                         tooltiptext="&devToolbarToolsButton.tooltip;"/>
-+#ifndef XP_MACOSX
-+          <toolbarbutton id="developer-toolbar-closebutton"
-+                         class="devtools-closebutton"
-+                         oncommand="DeveloperToolbar.hide();"
-+                         tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
-+#endif
-+   </toolbar>
-+  </vbox>
-+
-+  <svg:svg height="0">
-+#include tab-shape.inc.svg
-+    <svg:clipPath id="urlbar-back-button-clip-path">
-+#ifndef XP_MACOSX
-+      <svg:path d="M -9,-4 l 0,1 a 15 15 0 0,1 0,30 l 0,1 l 10000,0 l 0,-32 l -10000,0 z" />
-+#else
-+      <svg:path d="M -11,-5 a 16 16 0 0 1 0,34 l 10000,0 l 0,-34 l -10000,0 z"/>
-+#endif
-+    </svg:clipPath>
-+#ifdef XP_WIN
-+    <svg:clipPath id="urlbar-back-button-clip-path-win10">
-+      <svg:path d="M -6,-2 l 0,1 a 15 15 0 0,1 0,30 l 0,1 l 10000,0 l 0,-32 l -10000,0 z" />
-+    </svg:clipPath>
-+#endif
-+  </svg:svg>
-+
-+</vbox>
-+# <iframe id="tab-view"> is dynamically appended as the 2nd child of #tab-view-deck.
-+#     Introducing the iframe dynamically, as needed, was found to be better than
-+#     starting with an empty iframe here in browser.xul from a Ts standpoint.
-+</deck>
-+
-+</window>
-diff --git a/browser/base/jar.mn b/browser/base/jar.mn
---- a/browser/base/jar.mn
-+++ b/browser/base/jar.mn
-@@ -70,16 +70,18 @@ browser.jar:
-         content/browser/aboutSocialError.xhtml        (content/aboutSocialError.xhtml)
-         content/browser/aboutProviderDirectory.xhtml  (content/aboutProviderDirectory.xhtml)
-         content/browser/aboutTabCrashed.css           (content/aboutTabCrashed.css)
-         content/browser/aboutTabCrashed.js            (content/aboutTabCrashed.js)
-         content/browser/aboutTabCrashed.xhtml         (content/aboutTabCrashed.xhtml)
- *       content/browser/browser.css                   (content/browser.css)
- *       content/browser/browser.js                    (content/browser.js)
- *       content/browser/browser.xul                   (content/browser.xul)
-+*       content/browser/browser-kde.xul               (content/browser-kde.xul)
-+%       override chrome://browser/content/browser.xul chrome://browser/content/browser-kde.xul desktop=kde
- *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
- *       content/browser/chatWindow.xul                (content/chatWindow.xul)
-         content/browser/tab-content.js                (content/tab-content.js)
-         content/browser/content.js                    (content/content.js)
-         content/browser/social-content.js             (content/social-content.js)
-         content/browser/defaultthemes/1.footer.jpg    (content/defaultthemes/1.footer.jpg)
-         content/browser/defaultthemes/1.header.jpg    (content/defaultthemes/1.header.jpg)
-         content/browser/defaultthemes/1.icon.jpg      (content/defaultthemes/1.icon.jpg)
-diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp
---- a/browser/components/build/nsModule.cpp
-+++ b/browser/components/build/nsModule.cpp
-@@ -8,17 +8,17 @@
- #include "nsBrowserCompsCID.h"
- #include "DirectoryProvider.h"
- 
- #if defined(XP_WIN)
- #include "nsWindowsShellService.h"
- #elif defined(XP_MACOSX)
- #include "nsMacShellService.h"
- #elif defined(MOZ_WIDGET_GTK)
--#include "nsGNOMEShellService.h"
-+#include "nsUnixShellService.h"
- #endif
- 
- #if defined(XP_WIN)
- #include "nsIEHistoryEnumerator.h"
- #include "nsEdgeReadingListExtractor.h"
- #endif
- 
- #include "rdf.h"
-@@ -32,18 +32,16 @@ using namespace mozilla::browser;
- 
- /////////////////////////////////////////////////////////////////////////////
- 
- NS_GENERIC_FACTORY_CONSTRUCTOR(DirectoryProvider)
- #if defined(XP_WIN)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
- #elif defined(XP_MACOSX)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
--#elif defined(MOZ_WIDGET_GTK)
--NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
- #endif
- 
- #if defined(XP_WIN)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsEdgeReadingListExtractor)
- #endif
- 
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
-@@ -63,17 +61,17 @@ NS_DEFINE_NAMED_CID(NS_EDGEREADINGLISTEX
- NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
- #endif
- 
- static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
-     { &kNS_BROWSERDIRECTORYPROVIDER_CID, false, nullptr, DirectoryProviderConstructor },
- #if defined(XP_WIN)
-     { &kNS_SHELLSERVICE_CID, false, nullptr, nsWindowsShellServiceConstructor },
- #elif defined(MOZ_WIDGET_GTK)
--    { &kNS_SHELLSERVICE_CID, false, nullptr, nsGNOMEShellServiceConstructor },
-+    { &kNS_SHELLSERVICE_CID, false, nullptr, nsUnixShellServiceConstructor },
- #endif
-     { &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor },
-     { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create },
- #if defined(XP_WIN)
-     { &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor },
-     { &kNS_EDGEREADINGLISTEXTRACTOR_CID, false, nullptr, nsEdgeReadingListExtractorConstructor },
- #elif defined(XP_MACOSX)
-     { &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor },
-diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js
---- a/browser/components/preferences/in-content/main.js
-+++ b/browser/components/preferences/in-content/main.js
-@@ -14,16 +14,22 @@ var gMainPane = {
-   init: function ()
-   {
-     function setEventListener(aId, aEventType, aCallback)
-     {
-       document.getElementById(aId)
-               .addEventListener(aEventType, aCallback.bind(gMainPane));
-     }
- 
-+    var env = Components.classes["@mozilla.org/process/environment;1"]
-+                          .getService(Components.interfaces.nsIEnvironment);
-+    var kde_session = 0;
-+    if (env.get('KDE_FULL_SESSION') == "true")
-+        kde_session = 1;
-+
- #ifdef HAVE_SHELL_SERVICE
-     this.updateSetDefaultBrowser();
- #ifdef XP_WIN
-     // In Windows 8 we launch the control panel since it's the only
-     // way to get all file type association prefs. So we don't know
-     // when the user will select the default.  We refresh here periodically
-     // in case the default changes.  On other Windows OS's defaults can also
-     // be set while the prefs are open.
-@@ -711,16 +717,27 @@ var gMainPane = {
-    */
-   setDefaultBrowser: function()
-   {
-     let shellSvc = getShellService();
-     if (!shellSvc)
-       return;
-     try {
-       shellSvc.setDefaultBrowser(true, false);
-+      if (kde_session == 1) {
-+        var shellObj = Components.classes["@mozilla.org/file/local;1"]
-+                                   .createInstance(Components.interfaces.nsILocalFile);
-+        shellObj.initWithPath("/usr/bin/kwriteconfig");
-+        var process = Components.classes["@mozilla.org/process/util;1"]
-+                                  .createInstance(Components.interfaces.nsIProcess);
-+        process.init(shellObj);
-+        var args = ["--file", "kdeglobals", "--group", "General", "--key",
-+            "BrowserApplication", "firefox"];
-+        process.run(false, args, args.length);
-+      }
-     } catch (ex) {
-       Cu.reportError(ex);
-       return;
-     }
-     let selectedIndex =
-       shellSvc.isDefaultBrowser(false, true) ? 1 : 0;
-     document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
-   }
-diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.build
---- a/browser/components/shell/moz.build
-+++ b/browser/components/shell/moz.build
-@@ -30,16 +30,18 @@ if CONFIG['OS_ARCH'] == 'WINNT':
-     ]
- elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-     SOURCES += [
-         'nsMacShellService.cpp',
-     ]
- elif CONFIG['MOZ_WIDGET_GTK']:
-     SOURCES += [
-         'nsGNOMEShellService.cpp',
-+	'nsKDEShellService.cpp',
-+	'nsUnixShellService.cpp',
-     ]
- 
- if SOURCES:
-     FINAL_LIBRARY = 'browsercomps'
- 
- EXTRA_COMPONENTS += [
-     'nsSetDefaultBrowser.js',
-     'nsSetDefaultBrowser.manifest',
-diff --git a/browser/components/shell/nsKDEShellService.cpp b/browser/components/shell/nsKDEShellService.cpp
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsKDEShellService.cpp
-@@ -0,0 +1,292 @@
-+/* -*- 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/. */
-+
-+#include "mozilla/ArrayUtils.h"
-+
-+#include "nsCOMPtr.h"
-+#include "nsKDEShellService.h"
-+#include "nsShellService.h"
-+#include "nsKDEUtils.h"
-+#include "nsIPrefService.h"
-+#include "nsIProcess.h"
-+#include "nsIFile.h"
-+#include "nsServiceManagerUtils.h"
-+#include "nsComponentManagerUtils.h"
-+#include "nsIMutableArray.h"
-+#include "nsISupportsPrimitives.h"
-+#include "nsArrayUtils.h"
-+
-+using namespace mozilla;
-+
-+nsresult
-+nsKDEShellService::Init()
-+{
-+    if( !nsKDEUtils::kdeSupport())
-+        return NS_ERROR_NOT_AVAILABLE;
-+    return NS_OK;
-+}
-+
-+NS_IMPL_ISUPPORTS(nsKDEShellService, nsIShellService)
-+
-+NS_IMETHODIMP
-+nsKDEShellService::IsDefaultBrowser(bool aStartupCheck,
-+                                    bool aForAllTypes,
-+                                    bool* aIsDefaultBrowser)
-+{
-+    *aIsDefaultBrowser = false;
-+    if (aStartupCheck)
-+        mCheckedThisSession = true;
-+
-+    nsCOMPtr<nsIMutableArray> command = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if (!command)
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> str = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    if (!str)
-+        return NS_ERROR_FAILURE;
-+
-+    str->SetData( NS_LITERAL_CSTRING( "ISDEFAULTBROWSER" ));
-+    command->AppendElement( str, false );
-+
-+    if( nsKDEUtils::command( command ))
-+        *aIsDefaultBrowser = true;
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::SetDefaultBrowser(bool aClaimAllTypes,
-+                                     bool aForAllUsers)
-+{
-+    nsCOMPtr<nsIMutableArray> command = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if (!command)
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> cmdstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    nsCOMPtr<nsISupportsCString> paramstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    if (!cmdstr || !paramstr)
-+        return NS_ERROR_FAILURE;
-+
-+    cmdstr->SetData( NS_LITERAL_CSTRING( "SETDEFAULTBROWSER" ));
-+    command->AppendElement( cmdstr, false );
-+
-+    paramstr->SetData( aClaimAllTypes ? NS_LITERAL_CSTRING( "ALLTYPES" ) : NS_LITERAL_CSTRING( "NORMAL" ));
-+    command->AppendElement( paramstr, false );
-+
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::GetShouldSkipCheckDefaultBrowser(bool* aResult)
-+{
-+  NS_ENSURE_ARG_POINTER(aResult);
-+
-+  nsresult rv;
-+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-+  if (NS_FAILED(rv)) {
-+    return rv;
-+  }
-+
-+  rv = prefs->GetBoolPref(PREF_SKIPDEFAULTBROWSERCHECK, aResult);
-+  if (NS_FAILED(rv)) {
-+    return rv;
-+  }
-+  if (*aResult) {
-+    // Only skip the default browser check once. The next attempt in
-+    // a new session should proceed.
-+    return prefs->SetBoolPref(PREF_SKIPDEFAULTBROWSERCHECK, false);
-+  }
-+
-+  int32_t defaultBrowserCheckCount;
-+  rv = prefs->GetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT,
-+                         &defaultBrowserCheckCount);
-+  if (NS_FAILED(rv)) {
-+    return rv;
-+  }
-+  if (defaultBrowserCheckCount < 4) {
-+    *aResult = false;
-+    return prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT,
-+                             defaultBrowserCheckCount + 1);
-+  }
-+
-+  // Disable the default browser check after three attempts.
-+  // Don't modify PREF_CHECKDEFAULTBROWSER since that is a
-+  // user-initiated action and it shouldn't get re-enabled
-+  // if it has been user disabled.
-+  *aResult = true;
-+  return rv;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::GetShouldCheckDefaultBrowser(bool* aResult)
-+{
-+  // If we've already checked, the browser has been started and this is a
-+  // new window open, and we don't want to check again.
-+  if (mCheckedThisSession) {
-+    *aResult = false;
-+    return NS_OK;
-+  }
-+
-+  nsresult rv;
-+#ifndef RELEASE_BUILD
-+  bool skipDefaultBrowserCheck;
-+  rv = GetShouldSkipCheckDefaultBrowser(&skipDefaultBrowserCheck);
-+  if (NS_FAILED(rv)) {
-+    return rv;
-+  }
-+  if (skipDefaultBrowserCheck) {
-+    *aResult = false;
-+    return rv;
-+  }
-+#endif
-+
-+  nsCOMPtr<nsIPrefBranch> prefs;
-+  nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
-+  if (pserve)
-+    pserve->GetBranch("", getter_AddRefs(prefs));
-+
-+  if (prefs)
-+    prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
-+
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck)
-+{
-+  nsCOMPtr<nsIPrefBranch> prefs;
-+  nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
-+  if (pserve)
-+    pserve->GetBranch("", getter_AddRefs(prefs));
-+
-+  if (prefs)
-+    prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
-+
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::GetCanSetDesktopBackground(bool* aResult)
-+{
-+  *aResult = true;
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::SetDesktopBackground(nsIDOMElement* aElement,
-+                                          PRInt32 aPosition)
-+{
-+    return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
-+{
-+    return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::SetDesktopBackgroundColor(PRUint32 aColor)
-+{
-+    return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::OpenApplication(PRInt32 aApplication)
-+{
-+    nsCOMPtr<nsIMutableArray> command = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if (!command)
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> str = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    if (!str)
-+        return NS_ERROR_FAILURE;
-+
-+    if( aApplication == APPLICATION_MAIL )
-+        str->SetData( NS_LITERAL_CSTRING( "OPENMAIL" ));
-+    else if( aApplication == APPLICATION_NEWS )
-+        str->SetData( NS_LITERAL_CSTRING( "OPENNEWS" ));
-+    else
-+        return NS_ERROR_NOT_IMPLEMENTED;
-+
-+    command->AppendElement( str, false );
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::OpenApplicationWithURI(nsIFile* aApplication, const nsACString& aURI)
-+{
-+    nsCOMPtr<nsIMutableArray> command = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if (!command)
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> cmdstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    nsCOMPtr<nsISupportsCString> appstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    nsCOMPtr<nsISupportsCString> uristr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    if (!cmdstr || !appstr || !uristr)
-+        return NS_ERROR_FAILURE;
-+
-+    cmdstr->SetData( NS_LITERAL_CSTRING( "RUN" ));
-+    command->AppendElement( cmdstr, false );
-+    nsAutoCString app;
-+    nsresult rv = aApplication->GetNativePath( app );
-+    NS_ENSURE_SUCCESS( rv, rv );
-+    appstr->SetData( app );
-+    command->AppendElement( appstr, false );
-+    uristr->SetData( aURI );
-+    command->AppendElement( uristr, false );
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
-+}
-+
-+NS_IMETHODIMP
-+nsKDEShellService::GetDefaultFeedReader(nsIFile** _retval)
-+{
-+    *_retval = nullptr;
-+
-+    nsCOMPtr<nsIMutableArray> command = do_CreateInstance( NS_ARRAY_CONTRACTID );
-+    if( !command )
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> str = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID );
-+    if( !str )
-+        return NS_ERROR_FAILURE;
-+
-+    str->SetData( NS_LITERAL_CSTRING( "GETDEFAULTFEEDREADER" ));
-+    command->AppendElement( str, false );
-+
-+    nsCOMPtr<nsIArray> output;
-+    if( !nsKDEUtils::command( command, getter_AddRefs( output ) ) )
-+        return NS_ERROR_FAILURE;
-+
-+    PRUint32 length;
-+    output->GetLength( &length );
-+    if( length != 1 )
-+        return NS_ERROR_FAILURE;
-+
-+    nsCOMPtr<nsISupportsCString> resstr = do_QueryElementAt( output, 0 );
-+    if( !resstr )
-+        return NS_ERROR_FAILURE;
-+
-+    nsAutoCString path;
-+    resstr->GetData( path );
-+    if (path.IsEmpty())
-+        return NS_ERROR_FAILURE;
-+
-+    nsresult rv;
-+    nsCOMPtr<nsIFile> defaultReader =
-+        do_CreateInstance("@mozilla.org/file/local;1", &rv);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+
-+    rv = defaultReader->InitWithNativePath(path);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+
-+    bool exists;
-+    rv = defaultReader->Exists(&exists);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    if (!exists)
-+        return NS_ERROR_FAILURE;
-+
-+    NS_ADDREF(*_retval = defaultReader);
-+    return NS_OK;
-+}
-diff --git a/browser/components/shell/nsKDEShellService.h b/browser/components/shell/nsKDEShellService.h
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsKDEShellService.h
-@@ -0,0 +1,29 @@
-+/* -*- 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/. */
-+
-+#ifndef nskdeshellservice_h____
-+#define nskdeshellservice_h____
-+
-+#include "nsIShellService.h"
-+#include "nsStringAPI.h"
-+#include "mozilla/Attributes.h"
-+
-+class nsKDEShellService final : public nsIShellService
-+{
-+public:
-+  nsKDEShellService() : mCheckedThisSession(false) { }
-+
-+  NS_DECL_ISUPPORTS
-+  NS_DECL_NSISHELLSERVICE
-+
-+  nsresult Init();
-+
-+private:
-+  ~nsKDEShellService() {}
-+
-+  bool mCheckedThisSession;
-+};
-+
-+#endif // nskdeshellservice_h____
-diff --git a/browser/components/shell/nsUnixShellService.cpp b/browser/components/shell/nsUnixShellService.cpp
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsUnixShellService.cpp
-@@ -0,0 +1,22 @@
-+/* -*- 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/. */
-+
-+
-+#include "nsUnixShellService.h"
-+#include "nsGNOMEShellService.h"
-+#include "nsKDEShellService.h"
-+#include "nsKDEUtils.h"
-+#include "mozilla/ModuleUtils.h"
-+
-+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
-+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsKDEShellService, Init)
-+
-+NS_METHOD
-+nsUnixShellServiceConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
-+{
-+    if( nsKDEUtils::kdeSupport())
-+        return nsKDEShellServiceConstructor( aOuter, aIID, aResult );
-+    return nsGNOMEShellServiceConstructor( aOuter, aIID, aResult );
-+}
-diff --git a/browser/components/shell/nsUnixShellService.h b/browser/components/shell/nsUnixShellService.h
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsUnixShellService.h
-@@ -0,0 +1,15 @@
-+/* -*- 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/. */
-+
-+
-+#ifndef nsunixshellservice_h____
-+#define nsunixshellservice_h____
-+
-+#include "nsIShellService.h"
-+
-+NS_METHOD
-+nsUnixShellServiceConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult);
-+
-+#endif // nsunixshellservice_h____
-diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
---- a/browser/installer/package-manifest.in
-+++ b/browser/installer/package-manifest.in
-@@ -709,16 +709,17 @@
- @RESPATH@/defaults/autoconfig/prefcalls.js
- @RESPATH@/browser/defaults/profile/prefs.js
- @RESPATH@/browser/defaults/permissions
- 
- ; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325)
- ; Technically this is an app pref file, but we are keeping it in the original
- ; gre location for now.
- @RESPATH@/defaults/pref/channel-prefs.js
-+@BINPATH@/defaults/pref/kde.js
- 
- ; Services (gre) prefs
- #ifdef MOZ_SERVICES_NOTIFICATIONS
- @RESPATH@/defaults/pref/services-notifications.js
- #endif
- #ifdef MOZ_SERVICES_SYNC
- @RESPATH@/defaults/pref/services-sync.js
- #endif
diff --git a/helpers/DATA/firefox/mozilla-kde.patch b/helpers/DATA/firefox/mozilla-kde.patch
deleted file mode 100644
index 6816da49c375e6613103437215fb471f4a1cf125..0000000000000000000000000000000000000000
--- a/helpers/DATA/firefox/mozilla-kde.patch
+++ /dev/null
@@ -1,3780 +0,0 @@
-# HG changeset patch
-# Parent  d9c9ae52f0338a60d1626d9209248341815e597a
-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/Makefile.in b/modules/libpref/Makefile.in
---- a/modules/libpref/Makefile.in
-+++ b/modules/libpref/Makefile.in
-@@ -21,13 +21,15 @@ endif
- ifdef MOZ_SERVICES_HEALTHREPORT
- ifneq (android,$(MOZ_WIDGET_TOOLKIT))
- grepref_files += $(topsrcdir)/services/healthreport/healthreport-prefs.js
- else
- grepref_files += $(topsrcdir)/mobile/android/chrome/content/healthreport-prefs.js
- endif
- endif
- 
-+LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
-+
- greprefs.js: $(grepref_files)
- 	$(call py_action,preprocessor,$(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) $^ -o $@)
- 
- libs:: greprefs.js
- 	$(INSTALL) $^ $(DIST)/bin/
-diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
---- a/modules/libpref/Preferences.cpp
-+++ b/modules/libpref/Preferences.cpp
-@@ -30,16 +30,17 @@
- #include "nsIZipReader.h"
- #include "nsPrefBranch.h"
- #include "nsXPIDLString.h"
- #include "nsCRT.h"
- #include "nsCOMArray.h"
- #include "nsXPCOMCID.h"
- #include "nsAutoPtr.h"
- #include "nsPrintfCString.h"
-+#include "nsKDEUtils.h"
- 
- #include "nsQuickSort.h"
- #include "PLDHashTable.h"
- 
- #include "prefapi.h"
- #include "prefread.h"
- #include "prefapi_private_data.h"
- 
-@@ -1148,16 +1149,34 @@ pref_LoadPrefsInDir(nsIFile* aDir, char 
- 
- static nsresult pref_LoadPrefsInDirList(const char *listId)
- {
-   nsresult rv;
-   nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
-   if (NS_FAILED(rv))
-     return rv;
- 
-+  // make sure we load these special files after all the others
-+  static const char* specialFiles[] = {
-+#if defined(XP_UNIX)
-+    ""
-+#endif
-+  };
-+
-+  if (nsKDEUtils::kdeSession()) {
-+    for(int i = 0;
-+        i < MOZ_ARRAY_LENGTH(specialFiles);
-+        ++i ) {
-+      if (*specialFiles[ i ] == '\0') {
-+        specialFiles[ i ] = "kde.js";
-+        break;
-+      }
-+    }
-+  }
-+
-   nsCOMPtr<nsISimpleEnumerator> list;
-   dirSvc->Get(listId,
-               NS_GET_IID(nsISimpleEnumerator),
-               getter_AddRefs(list));
-   if (!list)
-     return NS_OK;
- 
-   bool hasMore;
-@@ -1173,17 +1192,17 @@ static nsresult pref_LoadPrefsInDirList(
- 
-     nsAutoCString leaf;
-     path->GetNativeLeafName(leaf);
- 
-     // Do we care if a file provided by this process fails to load?
-     if (Substring(leaf, leaf.Length() - 4).EqualsLiteral(".xpi"))
-       ReadExtensionPrefs(path);
-     else
--      pref_LoadPrefsInDir(path, nullptr, 0);
-+      pref_LoadPrefsInDir(path, specialFiles, MOZ_ARRAY_LENGTH(specialFiles));
-   }
-   return NS_OK;
- }
- 
- static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name)
- {
-   nsZipItemPtr<char> manifest(jarReader, name, true);
-   NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE);
-@@ -1277,26 +1296,38 @@ static nsresult pref_InitInitialObjects(
-   /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */
-   static const char* specialFiles[] = {
- #if defined(XP_MACOSX)
-     "macprefs.js"
- #elif defined(XP_WIN)
-     "winpref.js"
- #elif defined(XP_UNIX)
-     "unix.js"
-+    , "" // placeholder for KDE  (empty is otherwise harmless)
- #if defined(VMS)
-     , "openvms.js"
- #elif defined(_AIX)
-     , "aix.js"
- #endif
- #elif defined(XP_BEOS)
-     "beos.js"
- #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";
-+        break;
-+      }
-+    }
-+  }
-+
-   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.
-   RefPtr<nsZipArchive> appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
-   // GetReader(mozilla::Omnijar::APP) returns null when $app == $gre, in which
-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
-@@ -211,16 +211,17 @@ class Flags(OrderedDict):
-         'contentaccessible': Flag,
-         'os': StringFlag,
-         'osversion': VersionFlag,
-         'abi': StringFlag,
-         'platform': Flag,
-         'xpcnativewrappers': Flag,
-         'tablet': Flag,
-         'process': StringFlag,
-+        'desktop': StringFlag,
-     }
-     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
-@@ -33,16 +33,17 @@ class ManifestEntry(object):
-         'application',
-         'platformversion',
-         'os',
-         'osversion',
-         'abi',
-         'xpcnativewrappers',
-         'tablet',
-         'process',
-+        'desktop',
-     ]
- 
-     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
-@@ -65,15 +65,16 @@ if not CONFIG['MOZ_SUITE']:
-         'nsDownloadManagerUI.js',
-         'nsDownloadManagerUI.manifest',
-     ]
- 
- FINAL_LIBRARY = 'xul'
- 
- LOCAL_INCLUDES += [
-     '../protobuf',
--    '/ipc/chromium/src'
-+    '/ipc/chromium/src',
-+    '/toolkit/xre'
- ]
- 
- DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
- DEFINES['GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER'] = True
- 
- CXXFLAGS += CONFIG['TK_CFLAGS']
-diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp
---- a/toolkit/components/downloads/nsDownloadManager.cpp
-+++ b/toolkit/components/downloads/nsDownloadManager.cpp
-@@ -51,16 +51,20 @@
- #ifdef XP_WIN
- #include <shlobj.h>
- #include "nsWindowsHelpers.h"
- #ifdef DOWNLOAD_SCANNER
- #include "nsDownloadScanner.h"
- #endif
- #endif
- 
-+#if defined(XP_UNIX) && !defined(XP_MACOSX)
-+#include "nsKDEUtils.h"
-+#endif
-+
- #ifdef XP_MACOSX
- #include <CoreFoundation/CoreFoundation.h>
- #endif
- 
- #ifdef MOZ_WIDGET_ANDROID
- #include "AndroidBridge.h"
- #endif
- 
-@@ -2714,16 +2718,25 @@ nsDownload::SetState(DownloadState aStat
-       nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID));
- 
-       // Master pref to control this function.
-       bool showTaskbarAlert = true;
-       if (pref)
-         pref->GetBoolPref(PREF_BDM_SHOWALERTONCOMPLETE, &showTaskbarAlert);
- 
-       if (showTaskbarAlert) {
-+        if( nsKDEUtils::kdeSupport()) {
-+          nsTArray<nsCString> command;
-+          command.AppendElement( NS_LITERAL_CSTRING( "DOWNLOADFINISHED" ));
-+          nsAutoString displayName;
-+          GetDisplayName( displayName );
-+          command.AppendElement( nsAutoCString( ToNewUTF8String( displayName )));
-+          nsKDEUtils::command( command );
-+        } else {
-+        // begin non-KDE block
-         int32_t alertInterval = 2000;
-         if (pref)
-           pref->GetIntPref(PREF_BDM_SHOWALERTINTERVAL, &alertInterval);
- 
-         int64_t alertIntervalUSec = alertInterval * PR_USEC_PER_MSEC;
-         int64_t goat = PR_Now() - mStartTime;
-         showTaskbarAlert = goat > alertIntervalUSec;
- 
-@@ -2754,16 +2767,17 @@ nsDownload::SetState(DownloadState aStat
-                   NS_LITERAL_STRING(DOWNLOAD_MANAGER_ALERT_ICON), title,
-                   message, !removeWhenDone,
-                   mPrivate ? NS_LITERAL_STRING("private") : NS_LITERAL_STRING("non-private"),
-                   mDownloadManager, EmptyString(), NS_LITERAL_STRING("auto"),
-                   EmptyString(), EmptyString(), nullptr, mPrivate);
-             }
-         }
-       }
-+      }
- 
- #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
-       nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget);
-       nsCOMPtr<nsIFile> file;
-       nsAutoString path;
- 
-       if (fileURL &&
-           NS_SUCCEEDED(fileURL->GetFile(getter_AddRefs(file))) &&
-diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn
---- a/toolkit/content/jar.mn
-+++ b/toolkit/content/jar.mn
-@@ -64,29 +64,33 @@ toolkit.jar:
-    content/global/viewZoomOverlay.js
- *+ content/global/bindings/autocomplete.xml    (widgets/autocomplete.xml)
-    content/global/bindings/browser.xml         (widgets/browser.xml)
-    content/global/bindings/button.xml          (widgets/button.xml)
-    content/global/bindings/checkbox.xml        (widgets/checkbox.xml)
-    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)
- *+ content/global/bindings/findbar.xml         (widgets/findbar.xml)
-    content/global/bindings/general.xml         (widgets/general.xml)
-    content/global/bindings/groupbox.xml        (widgets/groupbox.xml)
- *+ content/global/bindings/listbox.xml         (widgets/listbox.xml)
-    content/global/bindings/menu.xml            (widgets/menu.xml)
-    content/global/bindings/menulist.xml        (widgets/menulist.xml)
-    content/global/bindings/notification.xml    (widgets/notification.xml)
-    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/remote-browser.xml  (widgets/remote-browser.xml)
-    content/global/bindings/resizer.xml         (widgets/resizer.xml)
-    content/global/bindings/richlistbox.xml     (widgets/richlistbox.xml)
-    content/global/bindings/scale.xml           (widgets/scale.xml)
-    content/global/bindings/scrollbar.xml       (widgets/scrollbar.xml)
-    content/global/bindings/scrollbox.xml       (widgets/scrollbox.xml)
-diff --git a/toolkit/content/widgets/dialog-kde.xml b/toolkit/content/widgets/dialog-kde.xml
-new file mode 100644
---- /dev/null
-+++ b/toolkit/content/widgets/dialog-kde.xml
-@@ -0,0 +1,460 @@
-+<?xml version="1.0"?>
-+<!-- 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/. -->
-+
-+
-+<bindings id="dialogBindings"
-+          xmlns="http://www.mozilla.org/xbl"
-+          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-+          xmlns:xbl="http://www.mozilla.org/xbl">
-+  
-+  <binding id="dialog" extends="chrome://global/content/bindings/general.xml#root-element">
-+    <resources>
-+      <stylesheet src="chrome://global/skin/dialog.css"/>
-+    </resources>
-+    <content>
-+      <xul:vbox class="box-inherit dialog-content-box" flex="1">
-+        <children/>
-+      </xul:vbox>
-+          
-+      <xul:hbox class="dialog-button-box" anonid="buttons"
-+                xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
-+#ifdef XP_UNIX_GNOME
-+                >
-+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
-+        <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
-+                >
-+	<xul:button dlgtype="help" class="dialog-button" hidden="true"/>
-+	<xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
-+	<xul:spacer anonid="spacer" flex="1"/>
-+	<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"/>
-+        <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="help" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
-+#endif
-+      </xul:hbox>
-+    </content>
-+
-+    <implementation>
-+      <field name="_mStrBundle">null</field>
-+      <field name="_closeHandler">(function(event) {
-+        if (!document.documentElement.cancelDialog())
-+          event.preventDefault();
-+      })</field>
-+
-+      <property name="buttons"
-+                onget="return this.getAttribute('buttons');"
-+                onset="this._configureButtons(val); return val;"/>
-+
-+      <property name="defaultButton">
-+        <getter>
-+        <![CDATA[
-+          if (this.hasAttribute("defaultButton"))
-+            return this.getAttribute("defaultButton");
-+          else // default to the accept button
-+            return "accept";
-+        ]]>
-+        </getter>
-+        <setter>
-+        <![CDATA[
-+          this._setDefaultButton(val);
-+          return val;
-+        ]]>
-+        </setter>
-+      </property>
-+
-+      <method name="acceptDialog">
-+        <body>
-+        <![CDATA[
-+          return this._doButtonCommand("accept");
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="cancelDialog">
-+        <body>
-+        <![CDATA[
-+          return this._doButtonCommand("cancel");
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="getButton">
-+        <parameter name="aDlgType"/>
-+        <body>
-+        <![CDATA[
-+          return this._buttons[aDlgType];
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="moveToAlertPosition">
-+        <body>
-+        <![CDATA[
-+          // hack. we need this so the window has something like its final size
-+          if (window.outerWidth == 1) {
-+            dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n");
-+            sizeToContent();
-+          }
-+
-+          if (opener) {
-+            var xOffset = (opener.outerWidth - window.outerWidth) / 2;
-+            var yOffset = opener.outerHeight / 5;
-+
-+            var newX = opener.screenX + xOffset;
-+            var newY = opener.screenY + yOffset;
-+          } else {
-+            newX = (screen.availWidth - window.outerWidth) / 2;
-+            newY = (screen.availHeight - window.outerHeight) / 2;
-+          }
-+
-+          // ensure the window is fully onscreen (if smaller than the screen)
-+          if (newX < screen.availLeft)
-+            newX = screen.availLeft + 20;
-+          if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth))
-+            newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20;
-+
-+          if (newY < screen.availTop)
-+            newY = screen.availTop + 20;
-+          if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight))
-+            newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60;
-+
-+          window.moveTo( newX, newY );
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="centerWindowOnScreen">
-+        <body>
-+        <![CDATA[
-+          var xOffset = screen.availWidth/2 - window.outerWidth/2;
-+          var yOffset = screen.availHeight/2 - window.outerHeight/2; //(opener.outerHeight *2)/10;
-+  
-+          xOffset = xOffset > 0 ? xOffset : 0;
-+          yOffset = yOffset > 0 ? yOffset : 0;
-+          window.moveTo(xOffset, yOffset);
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <constructor>
-+      <![CDATA[
-+        this._configureButtons(this.buttons);
-+
-+        // listen for when window is closed via native close buttons
-+        window.addEventListener("close", this._closeHandler, false);
-+
-+        // for things that we need to initialize after onload fires
-+        window.addEventListener("load", this.postLoadInit, false);
-+
-+        window.moveToAlertPosition = this.moveToAlertPosition;
-+        window.centerWindowOnScreen = this.centerWindowOnScreen;
-+      ]]>
-+      </constructor>
-+
-+      <method name="postLoadInit">
-+        <parameter name="aEvent"/>
-+        <body>
-+        <![CDATA[
-+          function focusInit() {
-+            const dialog = document.documentElement;
-+            const defaultButton = dialog.getButton(dialog.defaultButton);
-+            // give focus to the first focusable element in the dialog
-+            if (!document.commandDispatcher.focusedElement) {
-+              document.commandDispatcher.advanceFocusIntoSubtree(dialog);
-+
-+              var focusedElt = document.commandDispatcher.focusedElement;
-+              if (focusedElt) {
-+                var initialFocusedElt = focusedElt;
-+                while (focusedElt.localName == "tab" ||
-+                       focusedElt.getAttribute("noinitialfocus") == "true") {
-+                  document.commandDispatcher.advanceFocusIntoSubtree(focusedElt);
-+                  focusedElt = document.commandDispatcher.focusedElement;
-+                  if (focusedElt == initialFocusedElt)
-+                    break;
-+                }
-+
-+                if (initialFocusedElt.localName == "tab") {
-+                  if (focusedElt.hasAttribute("dlgtype")) {
-+                    // We don't want to focus on anonymous OK, Cancel, etc. buttons,
-+                    // so return focus to the tab itself
-+                    initialFocusedElt.focus();
-+                  }
-+                }
-+#ifndef XP_MACOSX
-+                else if (focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
-+                  defaultButton.focus();
-+                }
-+#endif
-+              }
-+            }
-+
-+            try {
-+              if (defaultButton)
-+                window.notifyDefaultButtonLoaded(defaultButton);
-+            } catch (e) { }
-+          }
-+
-+          // Give focus after onload completes, see bug 103197.
-+          setTimeout(focusInit, 0);
-+        ]]>
-+        </body>
-+      </method>                
-+
-+      <property name="mStrBundle">
-+        <getter>
-+        <![CDATA[
-+          if (!this._mStrBundle) {
-+            // need to create string bundle manually instead of using <xul:stringbundle/>
-+            // see bug 63370 for details
-+            this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
-+                                         .getService(Components.interfaces.nsIStringBundleService)
-+                                         .createBundle("chrome://global/locale/dialog.properties");
-+          }
-+          return this._mStrBundle;
-+        ]]></getter>
-+      </property>
-+      
-+      <method name="_configureButtons">
-+        <parameter name="aButtons"/>
-+        <body>
-+        <![CDATA[
-+          // by default, get all the anonymous button elements
-+          var buttons = {};
-+          this._buttons = buttons;
-+          buttons.accept = document.getAnonymousElementByAttribute(this, "dlgtype", "accept");
-+          buttons.cancel = document.getAnonymousElementByAttribute(this, "dlgtype", "cancel");
-+          buttons.extra1 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra1");
-+          buttons.extra2 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra2");
-+          buttons.help = document.getAnonymousElementByAttribute(this, "dlgtype", "help");
-+          buttons.disclosure = document.getAnonymousElementByAttribute(this, "dlgtype", "disclosure");
-+
-+          // look for any overriding explicit button elements
-+          var exBtns = this.getElementsByAttribute("dlgtype", "*");
-+          var dlgtype;
-+          var i;
-+          for (i = 0; i < exBtns.length; ++i) {
-+            dlgtype = exBtns[i].getAttribute("dlgtype");
-+            buttons[dlgtype].hidden = true; // hide the anonymous button
-+            buttons[dlgtype] = exBtns[i];
-+          }
-+
-+          // add the label and oncommand handler to each button
-+          for (dlgtype in buttons) {
-+            var button = buttons[dlgtype];
-+            button.addEventListener("command", this._handleButtonCommand, true);
-+
-+            // don't override custom labels with pre-defined labels on explicit buttons
-+            if (!button.hasAttribute("label")) {
-+              // dialog attributes override the default labels in dialog.properties
-+              if (this.hasAttribute("buttonlabel"+dlgtype)) {
-+                button.setAttribute("label", this.getAttribute("buttonlabel"+dlgtype));
-+                if (this.hasAttribute("buttonaccesskey"+dlgtype))
-+                  button.setAttribute("accesskey", this.getAttribute("buttonaccesskey"+dlgtype));
-+              } else if (dlgtype != "extra1" && dlgtype != "extra2") {
-+                button.setAttribute("label", this.mStrBundle.GetStringFromName("button-"+dlgtype));
-+                var accessKey = this.mStrBundle.GetStringFromName("accesskey-"+dlgtype);
-+                if (accessKey)
-+                  button.setAttribute("accesskey", accessKey);
-+              }
-+            }
-+            // allow specifying alternate icons in the dialog header
-+            if (!button.hasAttribute("icon")) {
-+              // if there's an icon specified, use that
-+              if (this.hasAttribute("buttonicon"+dlgtype))
-+                button.setAttribute("icon", this.getAttribute("buttonicon"+dlgtype));
-+              // otherwise set defaults
-+              else
-+                switch (dlgtype) {
-+                  case "accept":
-+                    button.setAttribute("icon","accept");
-+                    break;
-+                  case "cancel":
-+                    button.setAttribute("icon","cancel");
-+                    break;
-+                  case "disclosure":
-+                    button.setAttribute("icon","properties");
-+                    break;
-+                  case "help":
-+                    button.setAttribute("icon","help");
-+                    break;
-+                  default:
-+                    break;
-+                }
-+            }
-+          }
-+
-+          // ensure that hitting enter triggers the default button command
-+          this.defaultButton = this.defaultButton;
-+          
-+          // if there is a special button configuration, use it
-+          if (aButtons) {
-+            // expect a comma delimited list of dlgtype values
-+            var list = aButtons.split(",");
-+
-+            // mark shown dlgtypes as true
-+            var shown = { accept: false, cancel: false, help: false,
-+                          disclosure: false, extra1: false, extra2: false };
-+            for (i = 0; i < list.length; ++i)
-+              shown[list[i].replace(/ /g, "")] = true;
-+
-+            // hide/show the buttons we want
-+            for (dlgtype in buttons) 
-+              buttons[dlgtype].hidden = !shown[dlgtype];
-+
-+#ifdef XP_WIN
-+#           show the spacer on Windows only when the extra2 button is present
-+            var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
-+            spacer.removeAttribute("hidden");
-+            spacer.setAttribute("flex", shown["extra2"]?"1":"0");
-+#endif
-+
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="_setDefaultButton">
-+        <parameter name="aNewDefault"/>
-+        <body>
-+        <![CDATA[
-+          // remove the default attribute from the previous default button, if any
-+          var oldDefaultButton = this.getButton(this.defaultButton);
-+          if (oldDefaultButton)
-+            oldDefaultButton.removeAttribute("default");
-+
-+          var newDefaultButton = this.getButton(aNewDefault);
-+          if (newDefaultButton) {
-+            this.setAttribute("defaultButton", aNewDefault);
-+            newDefaultButton.setAttribute("default", "true");
-+          }
-+          else {
-+            this.setAttribute("defaultButton", "none");
-+            if (aNewDefault != "none")
-+              dump("invalid new default button: " +  aNewDefault + ", assuming: none\n");
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="_handleButtonCommand">
-+        <parameter name="aEvent"/>
-+        <body>
-+        <![CDATA[
-+          return document.documentElement._doButtonCommand(
-+                                        aEvent.target.getAttribute("dlgtype"));
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="_doButtonCommand">
-+        <parameter name="aDlgType"/>
-+        <body>
-+        <![CDATA[
-+          var button = this.getButton(aDlgType);
-+          if (!button.disabled) {
-+            var noCancel = this._fireButtonEvent(aDlgType);
-+            if (noCancel) {
-+              if (aDlgType == "accept" || aDlgType == "cancel") {
-+                var closingEvent = new CustomEvent("dialogclosing", {
-+                  bubbles: true,
-+                  detail: { button: aDlgType },
-+                });
-+                this.dispatchEvent(closingEvent);
-+                window.close();
-+              }
-+            }
-+            return noCancel;
-+          }
-+          return true;
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="_fireButtonEvent">
-+        <parameter name="aDlgType"/>
-+        <body>
-+        <![CDATA[
-+          var event = document.createEvent("Events");
-+          event.initEvent("dialog"+aDlgType, true, true);
-+          
-+          // handle dom event handlers
-+          var noCancel = this.dispatchEvent(event);
-+          
-+          // handle any xml attribute event handlers
-+          var handler = this.getAttribute("ondialog"+aDlgType);
-+          if (handler != "") {
-+            var fn = new Function("event", handler);
-+            var returned = fn(event);
-+            if (returned == false)
-+              noCancel = false;
-+          }
-+          
-+          return noCancel;
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="_hitEnter">
-+        <parameter name="evt"/>
-+        <body>
-+        <![CDATA[
-+          if (evt.defaultPrevented)
-+            return;
-+
-+          var btn = this.getButton(this.defaultButton);
-+          if (btn)
-+            this._doButtonCommand(this.defaultButton);
-+        ]]>
-+        </body>
-+      </method>
-+
-+    </implementation>
-+    
-+    <handlers>
-+      <handler event="keypress" keycode="VK_RETURN"
-+               group="system" action="this._hitEnter(event);"/>
-+      <handler event="keypress" keycode="VK_ESCAPE" group="system">
-+        if (!event.defaultPrevented)
-+          this.cancelDialog();
-+      </handler>
-+#ifdef XP_MACOSX
-+      <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/>
-+#else
-+      <handler event="focus" phase="capturing">
-+        var btn = this.getButton(this.defaultButton);
-+        if (btn)
-+          btn.setAttribute("default", event.originalTarget == btn || !(event.originalTarget instanceof Components.interfaces.nsIDOMXULButtonElement));
-+      </handler>
-+#endif
-+    </handlers>
-+
-+  </binding>
-+
-+  <binding id="dialogheader">
-+    <resources>
-+      <stylesheet src="chrome://global/skin/dialog.css"/>
-+    </resources>
-+    <content>
-+      <xul:label class="dialogheader-title" xbl:inherits="value=title,crop" crop="right" flex="1"/>
-+      <xul:label class="dialogheader-description" xbl:inherits="value=description"/>
-+    </content>
-+  </binding>
-+
-+</bindings>
-diff --git a/toolkit/content/widgets/preferences-kde.xml b/toolkit/content/widgets/preferences-kde.xml
-new file mode 100644
---- /dev/null
-+++ b/toolkit/content/widgets/preferences-kde.xml
-@@ -0,0 +1,1403 @@
-+<?xml version="1.0"?>
-+
-+<!DOCTYPE bindings [
-+  <!ENTITY % preferencesDTD SYSTEM "chrome://global/locale/preferences.dtd">
-+  %preferencesDTD;
-+  <!ENTITY % globalKeysDTD SYSTEM "chrome://global/locale/globalKeys.dtd">
-+  %globalKeysDTD;
-+]>
-+
-+<bindings id="preferencesBindings"
-+          xmlns="http://www.mozilla.org/xbl"
-+          xmlns:xbl="http://www.mozilla.org/xbl"
-+          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-+
-+#
-+# = Preferences Window Framework
-+#
-+#   The syntax for use looks something like:
-+#
-+#   <prefwindow>
-+#     <prefpane id="prefPaneA">
-+#       <preferences>
-+#         <preference id="preference1" name="app.preference1" type="bool" onchange="foo();"/>
-+#         <preference id="preference2" name="app.preference2" type="bool" useDefault="true"/>
-+#       </preferences>
-+#       <checkbox label="Preference" preference="preference1"/>
-+#     </prefpane>
-+#   </prefwindow>
-+#
-+
-+  <binding id="preferences">
-+    <implementation implements="nsIObserver">
-+      <method name="_constructAfterChildren">
-+      <body>
-+      <![CDATA[
-+      // This method will be called after each one of the child
-+      // <preference> elements is constructed. Its purpose is to propagate
-+      // the values to the associated form elements
-+
-+      var elements = this.getElementsByTagName("preference");
-+      for (let element of elements) {
-+        if (!element._constructed) {
-+          return;
-+        }
-+      }
-+      for (let element of elements) {
-+        element.updateElements();
-+      }
-+      ]]>
-+      </body>
-+      </method>
-+      <method name="observe">
-+        <parameter name="aSubject"/>
-+        <parameter name="aTopic"/>
-+        <parameter name="aData"/>
-+        <body>
-+        <![CDATA[
-+          for (var i = 0; i < this.childNodes.length; ++i) {
-+            var preference = this.childNodes[i];
-+            if (preference.name == aData) {
-+              preference.value = preference.valueFromPreferences;
-+            }
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="fireChangedEvent">
-+        <parameter name="aPreference"/>
-+        <body>
-+        <![CDATA[
-+          // Value changed, synthesize an event
-+          try {
-+            var event = document.createEvent("Events");
-+            event.initEvent("change", true, true);
-+            aPreference.dispatchEvent(event);
-+          }
-+          catch (e) {
-+            Components.utils.reportError(e);
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <field name="service">
-+        Components.classes["@mozilla.org/preferences-service;1"]
-+                  .getService(Components.interfaces.nsIPrefService);
-+      </field>
-+      <field name="rootBranch">
-+        Components.classes["@mozilla.org/preferences-service;1"]
-+                  .getService(Components.interfaces.nsIPrefBranch);
-+      </field>
-+      <field name="defaultBranch">
-+        this.service.getDefaultBranch("");
-+      </field>
-+      <field name="rootBranchInternal">
-+        Components.classes["@mozilla.org/preferences-service;1"]
-+                  .getService(Components.interfaces.nsIPrefBranchInternal);
-+      </field>
-+      <property name="type" readonly="true">
-+        <getter>
-+          <![CDATA[
-+            return document.documentElement.type || "";
-+          ]]>
-+        </getter>
-+      </property>
-+      <property name="instantApply" readonly="true">
-+        <getter>
-+          <![CDATA[
-+            var doc = document.documentElement;
-+            return this.type == "child" ? doc.instantApply
-+                                        : doc.instantApply || this.rootBranch.getBoolPref("browser.preferences.instantApply");
-+          ]]>
-+        </getter>
-+      </property>
-+    </implementation>
-+  </binding>
-+
-+  <binding id="preference">
-+    <implementation>
-+      <constructor>
-+      <![CDATA[
-+        this._constructed = true;
-+
-+        // if the element has been inserted without the name attribute set,
-+        // we have nothing to do here
-+        if (!this.name)
-+          return;
-+
-+        this.preferences.rootBranchInternal
-+            .addObserver(this.name, this.preferences, false);
-+        // In non-instant apply mode, we must try and use the last saved state
-+        // from any previous opens of a child dialog instead of the value from
-+        // preferences, to pick up any edits a user may have made. 
-+
-+        var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
-+                    .getService(Components.interfaces.nsIScriptSecurityManager);
-+        if (this.preferences.type == "child" && 
-+            !this.instantApply && window.opener &&
-+            secMan.isSystemPrincipal(window.opener.document.nodePrincipal)) {
-+          var pdoc = window.opener.document;
-+
-+          // Try to find a preference element for the same preference.
-+          var preference = null;
-+          var parentPreferences = pdoc.getElementsByTagName("preferences");
-+          for (var k = 0; (k < parentPreferences.length && !preference); ++k) {
-+            var parentPrefs = parentPreferences[k]
-+                                    .getElementsByAttribute("name", this.name);
-+            for (var l = 0; (l < parentPrefs.length && !preference); ++l) {
-+              if (parentPrefs[l].localName == "preference")
-+                preference = parentPrefs[l];
-+            }
-+          }
-+
-+          // Don't use the value setter here, we don't want updateElements to be prematurely fired.
-+          this._value = preference ? preference.value : this.valueFromPreferences;
-+        }
-+        else
-+          this._value = this.valueFromPreferences;
-+        this.preferences._constructAfterChildren();
-+      ]]>
-+      </constructor>
-+      <destructor>
-+        this.preferences.rootBranchInternal
-+            .removeObserver(this.name, this.preferences);
-+      </destructor>
-+      <field name="_constructed">false</field>
-+      <property name="instantApply">
-+        <getter>
-+          return this.getAttribute("instantApply") == "true" || this.preferences.instantApply;
-+        </getter>
-+      </property>
-+
-+      <property name="preferences" onget="return this.parentNode"/>
-+      <property name="name" onget="return this.getAttribute('name');">
-+        <setter>
-+          if (val == this.name)
-+            return val;
-+            
-+          this.preferences.rootBranchInternal
-+              .removeObserver(this.name, this.preferences);
-+          this.setAttribute('name', val);
-+          this.preferences.rootBranchInternal
-+              .addObserver(val, this.preferences, false);
-+              
-+          return val;
-+        </setter>
-+      </property>
-+      <property name="type" onget="return this.getAttribute('type');"
-+                            onset="this.setAttribute('type', val); return val;"/>
-+      <property name="inverted" onget="return this.getAttribute('inverted') == 'true';"
-+                                onset="this.setAttribute('inverted', val); return val;"/>
-+      <property name="readonly" onget="return this.getAttribute('readonly') == 'true';"
-+                                onset="this.setAttribute('readonly', val); return val;"/>
-+
-+      <field name="_value">null</field>
-+      <method name="_setValue">
-+        <parameter name="aValue"/>
-+        <body>
-+        <![CDATA[
-+          if (this.value !== aValue) {
-+            this._value = aValue;
-+            if (this.instantApply)
-+              this.valueFromPreferences = aValue;
-+            this.preferences.fireChangedEvent(this);
-+          }
-+          return aValue;
-+        ]]>
-+        </body>
-+      </method>
-+      <property name="value" onget="return this._value" onset="return this._setValue(val);"/>
-+      
-+      <property name="locked">
-+        <getter>
-+          return this.preferences.rootBranch.prefIsLocked(this.name);
-+        </getter>
-+      </property>
-+      
-+      <property name="disabled">
-+        <getter>
-+          return this.getAttribute("disabled") == "true";
-+        </getter>
-+        <setter>
-+        <![CDATA[
-+          if (val) 
-+            this.setAttribute("disabled", "true");
-+          else
-+            this.removeAttribute("disabled");
-+
-+          if (!this.id)
-+            return val;
-+
-+          var elements = document.getElementsByAttribute("preference", this.id);
-+          for (var i = 0; i < elements.length; ++i) {
-+            elements[i].disabled = val;
-+            
-+            var labels = document.getElementsByAttribute("control", elements[i].id);
-+            for (var j = 0; j < labels.length; ++j)
-+              labels[j].disabled = val;
-+          }
-+            
-+          return val;
-+        ]]>
-+        </setter>
-+      </property>
-+      
-+      <property name="tabIndex">
-+        <getter>
-+          return parseInt(this.getAttribute("tabindex"));
-+        </getter>
-+        <setter>
-+        <![CDATA[
-+          if (val) 
-+            this.setAttribute("tabindex", val);
-+          else
-+            this.removeAttribute("tabindex");
-+
-+          if (!this.id)
-+            return val;
-+
-+          var elements = document.getElementsByAttribute("preference", this.id);
-+          for (var i = 0; i < elements.length; ++i) {
-+            elements[i].tabIndex = val;
-+            
-+            var labels = document.getElementsByAttribute("control", elements[i].id);
-+            for (var j = 0; j < labels.length; ++j)
-+              labels[j].tabIndex = val;
-+          }
-+            
-+          return val;
-+        ]]>
-+        </setter>
-+      </property>
-+
-+      <property name="hasUserValue">
-+        <getter>
-+        <![CDATA[
-+          return this.preferences.rootBranch.prefHasUserValue(this.name) &&
-+                 this.value !== undefined;
-+        ]]>
-+        </getter>
-+      </property>
-+      
-+      <method name="reset">
-+        <body>
-+          // defer reset until preference update
-+          this.value = undefined;
-+        </body>
-+      </method>
-+
-+      <field name="_useDefault">false</field>      
-+      <property name="defaultValue">
-+        <getter>
-+        <![CDATA[
-+          this._useDefault = true;
-+          var val = this.valueFromPreferences;
-+          this._useDefault = false;
-+          return val;
-+        ]]>
-+        </getter>
-+      </property>
-+      
-+      <property name="_branch">
-+        <getter>
-+          return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch;
-+        </getter>
-+      </property>
-+      
-+      <field name="batching">false</field>
-+      
-+      <method name="_reportUnknownType">
-+        <body>
-+        <![CDATA[
-+          var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-+                                         .getService(Components.interfaces.nsIConsoleService);
-+          var msg = "<preference> with id='" + this.id + "' and name='" + 
-+                    this.name + "' has unknown type '" + this.type + "'.";
-+          consoleService.logStringMessage(msg);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <property name="valueFromPreferences">
-+        <getter>
-+        <![CDATA[
-+          try {
-+            // Force a resync of value with preferences.
-+            switch (this.type) {
-+            case "int":
-+              return this._branch.getIntPref(this.name);
-+            case "bool":
-+              var val = this._branch.getBoolPref(this.name);
-+              return this.inverted ? !val : val;
-+            case "wstring":
-+              return this._branch
-+                         .getComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString)
-+                         .data;
-+            case "string":
-+            case "unichar":
-+              return this._branch
-+                         .getComplexValue(this.name, Components.interfaces.nsISupportsString)
-+                         .data;
-+            case "fontname":
-+              var family = this._branch
-+                               .getComplexValue(this.name, Components.interfaces.nsISupportsString)
-+                               .data;
-+              var fontEnumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
-+                                             .createInstance(Components.interfaces.nsIFontEnumerator);
-+              return fontEnumerator.getStandardFamilyName(family);
-+            case "file":
-+              var f = this._branch
-+                          .getComplexValue(this.name, Components.interfaces.nsILocalFile);
-+              return f;
-+            default:
-+              this._reportUnknownType();
-+            }
-+          }
-+          catch (e) { }
-+          return null;
-+        ]]>
-+        </getter>
-+        <setter>
-+        <![CDATA[
-+          // Exit early if nothing to do.
-+          if (this.readonly || this.valueFromPreferences == val)
-+            return val;
-+
-+          // The special value undefined means 'reset preference to default'.
-+          if (val === undefined) {
-+            this.preferences.rootBranch.clearUserPref(this.name);
-+            return val;
-+          }
-+
-+          // Force a resync of preferences with value.
-+          switch (this.type) {
-+          case "int":
-+            this.preferences.rootBranch.setIntPref(this.name, val);
-+            break;
-+          case "bool":
-+            this.preferences.rootBranch.setBoolPref(this.name, this.inverted ? !val : val);
-+            break;
-+          case "wstring":
-+            var pls = Components.classes["@mozilla.org/pref-localizedstring;1"]
-+                                .createInstance(Components.interfaces.nsIPrefLocalizedString);
-+            pls.data = val;
-+            this.preferences.rootBranch
-+                .setComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString, pls);
-+            break;
-+          case "string":
-+          case "unichar":
-+          case "fontname":
-+            var iss = Components.classes["@mozilla.org/supports-string;1"]
-+                                .createInstance(Components.interfaces.nsISupportsString);
-+            iss.data = val;
-+            this.preferences.rootBranch
-+                .setComplexValue(this.name, Components.interfaces.nsISupportsString, iss);
-+            break;
-+          case "file":
-+            var lf;
-+            if (typeof(val) == "string") {
-+              lf = Components.classes["@mozilla.org/file/local;1"]
-+                             .createInstance(Components.interfaces.nsILocalFile);
-+              lf.persistentDescriptor = val;
-+              if (!lf.exists())
-+                lf.initWithPath(val);
-+            }
-+            else 
-+              lf = val.QueryInterface(Components.interfaces.nsILocalFile);
-+            this.preferences.rootBranch
-+                .setComplexValue(this.name, Components.interfaces.nsILocalFile, lf);
-+            break;
-+          default:
-+            this._reportUnknownType();
-+          }
-+          if (!this.batching)
-+            this.preferences.service.savePrefFile(null);
-+          return val;
-+        ]]>
-+        </setter>
-+      </property>
-+      
-+      <method name="setElementValue">
-+        <parameter name="aElement"/>
-+        <body>
-+        <![CDATA[
-+          if (this.locked)
-+            aElement.disabled = true;
-+
-+          if (!this.isElementEditable(aElement))
-+            return;
-+
-+          var rv = undefined;
-+          if (aElement.hasAttribute("onsyncfrompreference")) {
-+            // Value changed, synthesize an event
-+            try {
-+              var event = document.createEvent("Events");
-+              event.initEvent("syncfrompreference", true, true);
-+              var f = new Function ("event", 
-+                                    aElement.getAttribute("onsyncfrompreference"));
-+              rv = f.call(aElement, event);
-+            }
-+            catch (e) {
-+              Components.utils.reportError(e);
-+            }
-+          }
-+          var val = rv !== undefined ? rv : (this.instantApply ? this.valueFromPreferences : this.value);
-+          // if the preference is marked for reset, show default value in UI
-+          if (val === undefined)
-+            val = this.defaultValue;
-+
-+          /**
-+           * Initialize a UI element property with a value. Handles the case 
-+           * where an element has not yet had a XBL binding attached for it and
-+           * the property setter does not yet exist by setting the same attribute
-+           * on the XUL element using DOM apis and assuming the element's 
-+           * constructor or property getters appropriately handle this state. 
-+           */
-+          function setValue(element, attribute, value) {
-+            if (attribute in element) 
-+              element[attribute] = value;
-+            else
-+              element.setAttribute(attribute, value);
-+          }
-+          if (aElement.localName == "checkbox" ||
-+              aElement.localName == "listitem")
-+            setValue(aElement, "checked", val);
-+          else if (aElement.localName == "colorpicker")
-+            setValue(aElement, "color", val);
-+          else if (aElement.localName == "textbox") {
-+            // XXXmano Bug 303998: Avoid a caret placement issue if either the
-+            // preference observer or its setter calls updateElements as a result
-+            // of the input event handler.
-+            if (aElement.value !== val)
-+              setValue(aElement, "value", val);
-+          }
-+          else
-+            setValue(aElement, "value", val);
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="getElementValue">
-+        <parameter name="aElement"/>
-+        <body>
-+        <![CDATA[
-+          if (aElement.hasAttribute("onsynctopreference")) {
-+            // Value changed, synthesize an event
-+            try {
-+              var event = document.createEvent("Events");
-+              event.initEvent("synctopreference", true, true);
-+              var f = new Function ("event", 
-+                                    aElement.getAttribute("onsynctopreference"));
-+              var rv = f.call(aElement, event);
-+              if (rv !== undefined) 
-+                return rv;
-+            }
-+            catch (e) {
-+              Components.utils.reportError(e);
-+            }
-+          }
-+          
-+          /**
-+           * Read the value of an attribute from an element, assuming the 
-+           * attribute is a property on the element's node API. If the property
-+           * is not present in the API, then assume its value is contained in
-+           * an attribute, as is the case before a binding has been attached.
-+           */
-+          function getValue(element, attribute) {
-+            if (attribute in element)
-+              return element[attribute];
-+            return element.getAttribute(attribute);
-+          }
-+          if (aElement.localName == "checkbox" ||
-+              aElement.localName == "listitem")
-+            var value = getValue(aElement, "checked");
-+          else if (aElement.localName == "colorpicker")
-+            value = getValue(aElement, "color");
-+          else
-+            value = getValue(aElement, "value");
-+
-+          switch (this.type) {
-+          case "int":
-+            return parseInt(value, 10) || 0;
-+          case "bool":
-+            return typeof(value) == "boolean" ? value : value == "true";
-+          }
-+          return value;
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="isElementEditable">
-+        <parameter name="aElement"/>
-+        <body>
-+        <![CDATA[
-+          switch (aElement.localName) {
-+          case "checkbox":
-+          case "colorpicker":
-+          case "radiogroup":
-+          case "textbox":
-+          case "listitem":
-+          case "listbox":
-+          case "menulist":
-+            return true;
-+          }
-+          return aElement.getAttribute("preference-editable") == "true";
-+        ]]> 
-+        </body>
-+      </method>
-+      
-+      <method name="updateElements">
-+        <body>
-+        <![CDATA[
-+          if (!this.id)
-+            return;
-+
-+          // This "change" event handler tracks changes made to preferences by 
-+          // sources other than the user in this window. 
-+          var elements = document.getElementsByAttribute("preference", this.id);
-+          for (var i = 0; i < elements.length; ++i) 
-+            this.setElementValue(elements[i]);
-+        ]]>
-+        </body>
-+      </method>
-+    </implementation>
-+    
-+    <handlers>
-+      <handler event="change">
-+        this.updateElements();
-+      </handler>
-+    </handlers>
-+  </binding>
-+
-+  <binding id="prefwindow"
-+           extends="chrome://global/content/bindings/dialog.xml#dialog">
-+    <resources>
-+      <stylesheet src="chrome://global/skin/preferences.css"/>
-+    </resources>
-+    <content dlgbuttons="accept,cancel" persist="lastSelected screenX screenY"
-+             closebuttonlabel="&preferencesCloseButton.label;"
-+             closebuttonaccesskey="&preferencesCloseButton.accesskey;"
-+             role="dialog"
-+#ifdef XP_WIN
-+             title="&preferencesDefaultTitleWin.title;">
-+#else
-+             title="&preferencesDefaultTitleMac.title;">
-+#endif
-+      <xul:windowdragbox orient="vertical">
-+        <xul:radiogroup anonid="selector" orient="horizontal" class="paneSelector chromeclass-toolbar"
-+                        role="listbox"/> <!-- Expose to accessibility APIs as a listbox -->
-+      </xul:windowdragbox>
-+      <xul:hbox flex="1" class="paneDeckContainer">
-+        <xul:deck anonid="paneDeck" flex="1">
-+          <children includes="prefpane"/>
-+        </xul:deck>
-+      </xul:hbox>
-+      <xul:hbox anonid="dlg-buttons" class="prefWindow-dlgbuttons" pack="end">
-+#ifndef XP_UNIX
-+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
-+        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
-+        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
-+        <xul:spacer anonid="spacer" flex="1"/>
-+        <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
-+        <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
-+#else
-+        <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="help" class="dialog-button" hidden="true" icon="help"/>
-+        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
-+#endif
-+      </xul:hbox>
-+      <xul:hbox>
-+        <children/>
-+      </xul:hbox>
-+    </content>
-+    <implementation implements="nsITimerCallback">
-+      <constructor>
-+      <![CDATA[
-+        if (this.type != "child") {
-+          if (!this._instantApplyInitialized) {
-+            let psvc = Components.classes["@mozilla.org/preferences-service;1"]
-+                                 .getService(Components.interfaces.nsIPrefBranch);
-+            this.instantApply = psvc.getBoolPref("browser.preferences.instantApply");
-+          }
-+          if (this.instantApply) {
-+            var docElt = document.documentElement;
-+            var acceptButton = docElt.getButton("accept");
-+            acceptButton.hidden = true;
-+            var cancelButton  = docElt.getButton("cancel");
-+#ifdef XP_MACOSX
-+            // no buttons on Mac except Help
-+            cancelButton.hidden = true;
-+            // Move Help button to the end
-+            document.getAnonymousElementByAttribute(this, "anonid", "spacer").hidden = true;         
-+            // Also, don't fire onDialogAccept on enter
-+            acceptButton.disabled = true;
-+#else
-+            // morph the Cancel button into the Close button
-+            cancelButton.setAttribute ("icon", "close");
-+            cancelButton.label = docElt.getAttribute("closebuttonlabel");
-+            cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey");
-+#endif
-+          }
-+        }
-+        this.setAttribute("animated", this._shouldAnimate ? "true" : "false");
-+        var panes = this.preferencePanes;
-+
-+        var lastPane = null;
-+        if (this.lastSelected) {
-+          lastPane = document.getElementById(this.lastSelected);
-+          if (!lastPane) {
-+            this.lastSelected = "";
-+          }
-+        }
-+
-+        var paneToLoad;
-+        if ("arguments" in window && window.arguments[0] && document.getElementById(window.arguments[0]) && document.getElementById(window.arguments[0]).nodeName == "prefpane") {
-+          paneToLoad = document.getElementById(window.arguments[0]);
-+          this.lastSelected = paneToLoad.id;
-+        }
-+        else if (lastPane)
-+          paneToLoad = lastPane;
-+        else
-+          paneToLoad = panes[0];
-+
-+        for (var i = 0; i < panes.length; ++i) {
-+          this._makePaneButton(panes[i]);
-+          if (panes[i].loaded) {
-+            // Inline pane content, fire load event to force initialization.
-+            this._fireEvent("paneload", panes[i]);
-+          }
-+        }
-+        this.showPane(paneToLoad);
-+
-+        if (panes.length == 1)
-+          this._selector.setAttribute("collapsed", "true");
-+      ]]>
-+      </constructor>
-+
-+      <destructor>
-+      <![CDATA[
-+        // Release timers to avoid reference cycles.
-+        if (this._animateTimer) {
-+          this._animateTimer.cancel();
-+          this._animateTimer = null;
-+        }
-+        if (this._fadeTimer) {
-+          this._fadeTimer.cancel();
-+          this._fadeTimer = null;
-+        }
-+      ]]>
-+      </destructor>
-+
-+      <!-- Derived bindings can set this to true to cause us to skip
-+           reading the browser.preferences.instantApply pref in the constructor.
-+           Then they can set instantApply to their wished value. -->
-+      <field name="_instantApplyInitialized">false</field>
-+      <!-- Controls whether changed pref values take effect immediately. -->
-+      <field name="instantApply">false</field>
-+
-+      <property name="preferencePanes"
-+                onget="return this.getElementsByTagName('prefpane');"/>
-+
-+      <property name="type" onget="return this.getAttribute('type');"/>
-+      <property name="_paneDeck"
-+                onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'paneDeck');"/>
-+      <property name="_paneDeckContainer"
-+                onget="return document.getAnonymousElementByAttribute(this, 'class', 'paneDeckContainer');"/>
-+      <property name="_selector"
-+                onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'selector');"/>
-+      <property name="lastSelected" 
-+                onget="return this.getAttribute('lastSelected');">
-+        <setter>
-+          this.setAttribute("lastSelected", val); 
-+          document.persist(this.id, "lastSelected");
-+          return val;
-+        </setter>          
-+      </property>
-+      <property name="currentPane"
-+                onset="return this._currentPane = val;">
-+        <getter>
-+          if (!this._currentPane)
-+            this._currentPane = this.preferencePanes[0];
-+          
-+          return this._currentPane;
-+        </getter> 
-+      </property>
-+      <field name="_currentPane">null</field>
-+      
-+      
-+      <method name="_makePaneButton">
-+        <parameter name="aPaneElement"/>
-+        <body>
-+        <![CDATA[
-+          var radio = document.createElement("radio");
-+          radio.setAttribute("pane", aPaneElement.id);
-+          radio.setAttribute("label", aPaneElement.label);
-+          // Expose preference group choice to accessibility APIs as an unchecked list item
-+          // The parent group is exposed to accessibility APIs as a list
-+          if (aPaneElement.image)
-+            radio.setAttribute("src", aPaneElement.image);
-+          radio.style.listStyleImage = aPaneElement.style.listStyleImage;
-+          this._selector.appendChild(radio);
-+          return radio;
-+        ]]>
-+        </body>
-+      </method>
-+
-+      <method name="showPane">
-+        <parameter name="aPaneElement"/>
-+        <body>
-+        <![CDATA[
-+          if (!aPaneElement)
-+            return;
-+
-+          this._selector.selectedItem = document.getAnonymousElementByAttribute(this, "pane", aPaneElement.id);
-+          if (!aPaneElement.loaded) {
-+            let OverlayLoadObserver = function(aPane)
-+            {
-+              this._pane = aPane;
-+            }
-+            OverlayLoadObserver.prototype = { 
-+              _outer: this,
-+              observe: function (aSubject, aTopic, aData) 
-+              {
-+                this._pane.loaded = true;
-+                this._outer._fireEvent("paneload", this._pane);
-+                this._outer._selectPane(this._pane);
-+              }
-+            };
-+            
-+            var obs = new OverlayLoadObserver(aPaneElement);
-+            document.loadOverlay(aPaneElement.src, obs);
-+          }
-+          else
-+            this._selectPane(aPaneElement);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="_fireEvent">
-+        <parameter name="aEventName"/>
-+        <parameter name="aTarget"/>
-+        <body>
-+        <![CDATA[
-+          // Panel loaded, synthesize a load event. 
-+          try {
-+            var event = document.createEvent("Events");
-+            event.initEvent(aEventName, true, true);
-+            var cancel = !aTarget.dispatchEvent(event);
-+            if (aTarget.hasAttribute("on" + aEventName)) {
-+              var fn = new Function ("event", aTarget.getAttribute("on" + aEventName));
-+              var rv = fn.call(aTarget, event);
-+              if (rv == false)
-+                cancel = true;
-+            }
-+            return !cancel;  
-+          }
-+          catch (e) { 
-+            Components.utils.reportError(e);
-+          }
-+          return false;
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <field name="_initialized">false</field>
-+      <method name="_selectPane">
-+        <parameter name="aPaneElement"/>
-+        <body>
-+        <![CDATA[
-+#ifdef XP_MACOSX
-+          var paneTitle = aPaneElement.label;
-+          if (paneTitle != "")
-+            document.title = paneTitle;
-+#endif
-+          var helpButton = document.documentElement.getButton("help");
-+          if (aPaneElement.helpTopic)
-+            helpButton.hidden = false;
-+          else
-+            helpButton.hidden = true;
-+
-+          // Find this pane's index in the deck and set the deck's 
-+          // selectedIndex to that value to switch to it.
-+          var prefpanes = this.preferencePanes;
-+          for (var i = 0; i < prefpanes.length; ++i) {
-+            if (prefpanes[i] == aPaneElement) {
-+              this._paneDeck.selectedIndex = i;
-+              
-+              if (this.type != "child") {
-+                if (aPaneElement.hasAttribute("flex") && this._shouldAnimate &&
-+                    prefpanes.length > 1)
-+                  aPaneElement.removeAttribute("flex");
-+                // Calling sizeToContent after the first prefpane is loaded
-+                // will size the windows contents so style information is
-+                // available to calculate correct sizing.
-+                if (!this._initialized && prefpanes.length > 1) {
-+                  if (this._shouldAnimate)
-+                    this.style.minHeight = 0;
-+                  window.sizeToContent();
-+                }
-+
-+                var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0];
-+                oldPane.selected = !(aPaneElement.selected = true);
-+                this.lastSelected = aPaneElement.id;
-+                this.currentPane = aPaneElement;
-+                this._initialized = true;
-+
-+                // Only animate if we've switched between prefpanes
-+                if (this._shouldAnimate && oldPane.id != aPaneElement.id) {
-+                  aPaneElement.style.opacity = 0.0;
-+                  this.animate(oldPane, aPaneElement);
-+                }
-+                else if (!this._shouldAnimate && prefpanes.length > 1) {
-+                  var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height);
-+                  var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop);
-+                  verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom);
-+                  if (aPaneElement.contentHeight > targetHeight - verticalPadding) {
-+                    // To workaround the bottom border of a groupbox from being
-+                    // cutoff an hbox with a class of bottomBox may enclose it.
-+                    // This needs to include its padding to resize properly.
-+                    // See bug 394433
-+                    var bottomPadding = 0;
-+                    var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0];
-+                    if (bottomBox)
-+                      bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom);
-+                    window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight;
-+                  }
-+
-+                  // XXX rstrong - extend the contents of the prefpane to
-+                  // prevent elements from being cutoff (see bug 349098).
-+                  if (aPaneElement.contentHeight + verticalPadding < targetHeight)
-+                    aPaneElement._content.style.height = targetHeight - verticalPadding + "px";
-+                }
-+              }
-+              break;
-+            }
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <property name="_shouldAnimate">
-+        <getter>
-+        <![CDATA[
-+          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
-+                               .getService(Components.interfaces.nsIPrefBranch);
-+#ifdef XP_MACOSX
-+          var animate = true;
-+#else
-+          var animate = false;
-+#endif
-+          try {
-+            animate = psvc.getBoolPref("browser.preferences.animateFadeIn");
-+          }
-+          catch (e) { }
-+          return animate;
-+        ]]>
-+        </getter>
-+      </property>
-+      
-+      <method name="animate">
-+        <parameter name="aOldPane"/>
-+        <parameter name="aNewPane"/>
-+        <body>
-+        <![CDATA[
-+          // if we are already resizing, use currentHeight
-+          var oldHeight = this._currentHeight ? this._currentHeight : aOldPane.contentHeight;
-+          
-+          this._multiplier = aNewPane.contentHeight > oldHeight ? 1 : -1;
-+          var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight);
-+          this._animateRemainder = sizeDelta % this._animateIncrement;
-+
-+          this._setUpAnimationTimer(oldHeight);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <property name="_sizeIncrement">
-+        <getter>
-+        <![CDATA[
-+          var lastSelectedPane = document.getElementById(this.lastSelected);
-+          var increment = this._animateIncrement * this._multiplier;
-+          var newHeight = this._currentHeight + increment;
-+          if ((this._multiplier > 0 && this._currentHeight >= lastSelectedPane.contentHeight) ||
-+              (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight))
-+            return 0;
-+          
-+          if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) ||
-+              (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight))
-+            increment = this._animateRemainder * this._multiplier;
-+          return increment;
-+        ]]>
-+        </getter>
-+      </property>
-+      
-+      <method name="notify">
-+        <parameter name="aTimer"/>
-+        <body>
-+        <![CDATA[
-+          if (!document)
-+            aTimer.cancel();
-+          
-+          if (aTimer == this._animateTimer) {
-+            var increment = this._sizeIncrement;
-+            if (increment != 0) {
-+              window.innerHeight += increment;
-+              this._currentHeight += increment;
-+            }
-+            else {
-+              aTimer.cancel();
-+              this._setUpFadeTimer();
-+            }
-+          } else if (aTimer == this._fadeTimer) {
-+            var elt = document.getElementById(this.lastSelected);
-+            var newOpacity = parseFloat(window.getComputedStyle(elt, "").opacity) + this._fadeIncrement;
-+            if (newOpacity < 1.0)
-+              elt.style.opacity = newOpacity;
-+            else {
-+              aTimer.cancel();
-+              elt.style.opacity = 1.0;
-+            }
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="_setUpAnimationTimer">
-+        <parameter name="aStartHeight"/>
-+        <body>
-+        <![CDATA[
-+          if (!this._animateTimer) 
-+            this._animateTimer = Components.classes["@mozilla.org/timer;1"]
-+                                           .createInstance(Components.interfaces.nsITimer);
-+          else
-+            this._animateTimer.cancel();
-+          this._currentHeight = aStartHeight;
-+          
-+          this._animateTimer.initWithCallback(this, this._animateDelay, 
-+                                              Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="_setUpFadeTimer">
-+        <body>
-+        <![CDATA[
-+          if (!this._fadeTimer) 
-+            this._fadeTimer = Components.classes["@mozilla.org/timer;1"]
-+                                        .createInstance(Components.interfaces.nsITimer);
-+          else
-+            this._fadeTimer.cancel();
-+          
-+          this._fadeTimer.initWithCallback(this, this._fadeDelay, 
-+                                           Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <field name="_animateTimer">null</field>
-+      <field name="_fadeTimer">null</field>
-+      <field name="_animateDelay">15</field>
-+      <field name="_animateIncrement">40</field>
-+      <field name="_fadeDelay">5</field>
-+      <field name="_fadeIncrement">0.40</field>
-+      <field name="_animateRemainder">0</field>
-+      <field name="_currentHeight">0</field>
-+      <field name="_multiplier">0</field>
-+
-+      <method name="addPane">
-+        <parameter name="aPaneElement"/>
-+        <body>
-+        <![CDATA[
-+          this.appendChild(aPaneElement);
-+          
-+          // Set up pane button
-+          this._makePaneButton(aPaneElement);
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <method name="openSubDialog">
-+        <parameter name="aURL"/>
-+        <parameter name="aFeatures"/>
-+        <parameter name="aParams"/>
-+        <body>
-+          return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams);
-+        </body>
-+      </method>
-+      
-+      <method name="openWindow">
-+        <parameter name="aWindowType"/>
-+        <parameter name="aURL"/>
-+        <parameter name="aFeatures"/>
-+        <parameter name="aParams"/>
-+        <body>
-+        <![CDATA[
-+          var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-+                             .getService(Components.interfaces.nsIWindowMediator);
-+          var win = aWindowType ? wm.getMostRecentWindow(aWindowType) : null;
-+          if (win) {
-+            if ("initWithParams" in win)
-+              win.initWithParams(aParams);
-+            win.focus();
-+          }
-+          else {
-+            var features = "resizable,dialog=no,centerscreen" + (aFeatures != "" ? ("," + aFeatures) : "");
-+            var parentWindow = (this.instantApply || !window.opener || window.opener.closed) ? window : window.opener;
-+            win = parentWindow.openDialog(aURL, "_blank", features, aParams);
-+          }
-+          return win;
-+        ]]>
-+        </body>
-+      </method>
-+    </implementation>
-+    <handlers>
-+      <handler event="dialogaccept">
-+      <![CDATA[
-+        if (!this._fireEvent("beforeaccept", this)){
-+          return false;
-+        }
-+
-+        var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
-+                    .getService(Components.interfaces.nsIScriptSecurityManager);
-+        if (this.type == "child" && window.opener &&
-+            secMan.isSystemPrincipal(window.opener.document.nodePrincipal)) {
-+          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
-+                               .getService(Components.interfaces.nsIPrefBranch);
-+          var pdocEl = window.opener.document.documentElement;
-+          if (pdocEl.instantApply) {
-+            var panes = this.preferencePanes;
-+            for (var i = 0; i < panes.length; ++i)
-+              panes[i].writePreferences(true);
-+          }
-+          else {
-+            // Clone all the preferences elements from the child document and
-+            // insert them into the pane collection of the parent. 
-+            var pdoc = window.opener.document;
-+            if (pdoc.documentElement.localName == "prefwindow") {
-+              var currentPane = pdoc.documentElement.currentPane;
-+              var id = window.location.href + "#childprefs";
-+              var childPrefs = pdoc.getElementById(id);
-+              if (!childPrefs) {
-+                var childPrefs = pdoc.createElement("preferences");
-+                currentPane.appendChild(childPrefs);
-+                childPrefs.id = id;
-+              }
-+              var panes = this.preferencePanes;
-+              for (var i = 0; i < panes.length; ++i) {
-+                var preferences = panes[i].preferences;
-+                for (var j = 0; j < preferences.length; ++j) {
-+                  // Try to find a preference element for the same preference.
-+                  var preference = null;
-+                  var parentPreferences = pdoc.getElementsByTagName("preferences");
-+                  for (var k = 0; (k < parentPreferences.length && !preference); ++k) {
-+                    var parentPrefs = parentPreferences[k]
-+                                         .getElementsByAttribute("name", preferences[j].name);
-+                    for (var l = 0; (l < parentPrefs.length && !preference); ++l) {
-+                      if (parentPrefs[l].localName == "preference")
-+                        preference = parentPrefs[l];
-+                    }
-+                  }
-+                  if (!preference) {
-+                    // No matching preference in the parent window.
-+                    preference = pdoc.createElement("preference");
-+                    childPrefs.appendChild(preference);
-+                    preference.name     = preferences[j].name;
-+                    preference.type     = preferences[j].type;
-+                    preference.inverted = preferences[j].inverted;
-+                    preference.readonly = preferences[j].readonly;
-+                    preference.disabled = preferences[j].disabled;
-+                  }
-+                  preference.value = preferences[j].value;
-+                }
-+              }
-+            }
-+          }
-+        }
-+        else {
-+          var panes = this.preferencePanes;
-+          for (var i = 0; i < panes.length; ++i)
-+            panes[i].writePreferences(false);
-+
-+          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
-+                               .getService(Components.interfaces.nsIPrefService);
-+          psvc.savePrefFile(null);
-+        }
-+
-+        return true;
-+      ]]>
-+      </handler>
-+      <handler event="command">
-+        if (event.originalTarget.hasAttribute("pane")) {
-+          var pane = document.getElementById(event.originalTarget.getAttribute("pane"));
-+          this.showPane(pane);
-+        }
-+      </handler>
-+
-+      <handler event="keypress" key="&windowClose.key;" modifiers="accel" phase="capturing">
-+      <![CDATA[
-+        if (this.instantApply)
-+          window.close();
-+        event.stopPropagation();
-+        event.preventDefault();
-+      ]]>
-+      </handler>
-+
-+      <handler event="keypress"
-+#ifdef XP_MACOSX
-+               key="&openHelpMac.commandkey;" modifiers="accel"
-+#else
-+               keycode="&openHelp.commandkey;"
-+#endif
-+               phase="capturing">
-+      <![CDATA[
-+        var helpButton = this.getButton("help");
-+        if (helpButton.disabled || helpButton.hidden)
-+          return;
-+        this._fireEvent("dialoghelp", this);
-+        event.stopPropagation();
-+        event.preventDefault();
-+      ]]>
-+      </handler>
-+    </handlers>
-+  </binding>
-+  
-+  <binding id="prefpane">
-+    <resources>
-+      <stylesheet src="chrome://global/skin/preferences.css"/>
-+    </resources>
-+    <content>
-+      <xul:vbox class="content-box" xbl:inherits="flex">
-+        <children/>
-+      </xul:vbox>
-+    </content>
-+    <implementation>
-+      <method name="writePreferences">
-+        <parameter name="aFlushToDisk"/>
-+        <body>
-+        <![CDATA[
-+          // Write all values to preferences.
-+          if (this._deferredValueUpdateElements.size) {
-+            this._finalizeDeferredElements();
-+          }
-+
-+          var preferences = this.preferences;
-+          for (var i = 0; i < preferences.length; ++i) {
-+            var preference = preferences[i];
-+            preference.batching = true;
-+            preference.valueFromPreferences = preference.value;
-+            preference.batching = false;
-+          }
-+          if (aFlushToDisk) {
-+            var psvc = Components.classes["@mozilla.org/preferences-service;1"]
-+                                 .getService(Components.interfaces.nsIPrefService);
-+            psvc.savePrefFile(null);
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <property name="src" 
-+                onget="return this.getAttribute('src');"
-+                onset="this.setAttribute('src', val); return val;"/>
-+      <property name="selected" 
-+                onget="return this.getAttribute('selected') == 'true';"
-+                onset="this.setAttribute('selected', val); return val;"/>
-+      <property name="image" 
-+                onget="return this.getAttribute('image');"
-+                onset="this.setAttribute('image', val); return val;"/>
-+      <property name="label" 
-+                onget="return this.getAttribute('label');"
-+                onset="this.setAttribute('label', val); return val;"/>
-+      
-+      <property name="preferenceElements"
-+                onget="return this.getElementsByAttribute('preference', '*');"/>
-+      <property name="preferences"
-+                onget="return this.getElementsByTagName('preference');"/>
-+
-+      <property name="helpTopic">
-+        <getter>
-+        <![CDATA[
-+          // if there are tabs, and the selected tab provides a helpTopic, return that
-+          var box = this.getElementsByTagName("tabbox");
-+          if (box[0]) {
-+            var tab = box[0].selectedTab;
-+            if (tab && tab.hasAttribute("helpTopic"))
-+              return tab.getAttribute("helpTopic");
-+          }
-+
-+          // otherwise, return the helpTopic of the current panel
-+          return this.getAttribute("helpTopic");
-+        ]]>
-+        </getter>
-+      </property>
-+
-+      <field name="_loaded">false</field>
-+      <property name="loaded" 
-+                onget="return !this.src ? true : this._loaded;"
-+                onset="this._loaded = val; return val;"/>
-+      
-+      <method name="preferenceForElement">
-+        <parameter name="aElement"/>
-+        <body>
-+          return document.getElementById(aElement.getAttribute("preference"));
-+        </body>
-+      </method>
-+      
-+      <method name="getPreferenceElement">
-+        <parameter name="aStartElement"/>
-+        <body>
-+        <![CDATA[
-+          var temp = aStartElement;
-+          while (temp && temp.nodeType == Node.ELEMENT_NODE && 
-+                 !temp.hasAttribute("preference"))
-+            temp = temp.parentNode;
-+          return temp.nodeType == Node.ELEMENT_NODE ? temp : aStartElement;
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <field name="DeferredTask" readonly="true">
-+        let targetObj = {};
-+        Components.utils.import("resource://gre/modules/DeferredTask.jsm", targetObj);
-+        targetObj.DeferredTask;
-+      </field>
-+      <method name="_deferredValueUpdate">
-+        <parameter name="aElement"/>
-+        <body>
-+        <![CDATA[
-+          delete aElement._deferredValueUpdateTask;
-+          let preference = document.getElementById(aElement.getAttribute("preference"));
-+          let prefVal = preference.getElementValue(aElement);
-+          preference.value = prefVal;
-+          this._deferredValueUpdateElements.delete(aElement);
-+        ]]>
-+        </body>
-+      </method>
-+      <field name="_deferredValueUpdateElements">
-+        new Set();
-+      </field>
-+      <method name="_finalizeDeferredElements">
-+        <body>
-+        <![CDATA[
-+          for (let el of this._deferredValueUpdateElements) {
-+            if (el._deferredValueUpdateTask) {
-+              el._deferredValueUpdateTask.finalize();
-+            }
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      <method name="userChangedValue">
-+        <parameter name="aElement"/>
-+        <body>
-+        <![CDATA[
-+          let element = this.getPreferenceElement(aElement);
-+          if (element.hasAttribute("preference")) {
-+            if (element.getAttribute("delayprefsave") != "true") {
-+              var preference = document.getElementById(element.getAttribute("preference"));
-+              var prefVal = preference.getElementValue(element);
-+              preference.value = prefVal;
-+            } else {
-+              if (!element._deferredValueUpdateTask) {
-+                element._deferredValueUpdateTask = new this.DeferredTask(this._deferredValueUpdate.bind(this, element), 1000);
-+                this._deferredValueUpdateElements.add(element);
-+              } else {
-+                // Each time the preference is changed, restart the delay.
-+                element._deferredValueUpdateTask.disarm();
-+              }
-+              element._deferredValueUpdateTask.arm();
-+            }
-+          }
-+        ]]>
-+        </body>
-+      </method>
-+      
-+      <property name="contentHeight">
-+        <getter>
-+          var targetHeight = parseInt(window.getComputedStyle(this._content, "").height);
-+          targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop);
-+          targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom);
-+          return targetHeight;
-+        </getter>
-+      </property>
-+      <field name="_content">
-+        document.getAnonymousElementByAttribute(this, "class", "content-box");
-+      </field>
-+    </implementation>
-+    <handlers>
-+      <handler event="command">
-+        // This "command" event handler tracks changes made to preferences by 
-+        // the user in this window.
-+        if (event.sourceEvent)
-+          event = event.sourceEvent;
-+        this.userChangedValue(event.target);
-+      </handler>
-+      <handler event="select">
-+        // This "select" event handler tracks changes made to colorpicker 
-+        // preferences by the user in this window.
-+        if (event.target.localName == "colorpicker") 
-+          this.userChangedValue(event.target);
-+      </handler>
-+      <handler event="change">
-+        // This "change" event handler tracks changes made to preferences by 
-+        // the user in this window. 
-+        this.userChangedValue(event.target);
-+      </handler>
-+      <handler event="input">
-+        // This "input" event handler tracks changes made to preferences by 
-+        // the user in this window.
-+        this.userChangedValue(event.target);
-+      </handler>
-+      <handler event="paneload">
-+      <![CDATA[
-+        // Initialize all values from preferences.
-+        var elements = this.preferenceElements;
-+        for (var i = 0; i < elements.length; ++i) {
-+          try {
-+            var preference = this.preferenceForElement(elements[i]);
-+            preference.setElementValue(elements[i]);
-+          }
-+          catch (e) {
-+            dump("*** No preference found for " + elements[i].getAttribute("preference") + "\n");
-+          }
-+        }
-+      ]]>      
-+      </handler>
-+    </handlers>
-+  </binding>
-+          
-+  <binding id="panebutton" role="xul:listitem"
-+           extends="chrome://global/content/bindings/radio.xml#radio">
-+    <resources>
-+      <stylesheet src="chrome://global/skin/preferences.css"/>
-+    </resources>
-+    <content>
-+      <xul:image class="paneButtonIcon" xbl:inherits="src"/>
-+      <xul:label class="paneButtonLabel" xbl:inherits="value=label"/>
-+    </content>
-+  </binding>
-+
-+</bindings>
-+
-+# -*- Mode: Java; 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
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+#
-+# This is PrefWindow 6. The Code Could Well Be Ready, Are You?
-+#
-+#    Historical References:
-+#    PrefWindow V   (February 1, 2003)
-+#    PrefWindow IV  (April 24, 2000)
-+#    PrefWindow III (January 6, 2000)
-+#    PrefWindow II  (???)
-+#    PrefWindow I   (June 4, 1999)
-+#
-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
-@@ -15,16 +15,17 @@
- #include "nsPrintfCString.h"
- #include "nsNetCID.h"
- #include "nsNetUtil.h"
- #include "nsISupportsPrimitives.h"
- #include "nsIGSettingsService.h"
- #include "nsInterfaceHashtable.h"
- #include "mozilla/Attributes.h"
- #include "nsIURI.h"
-+#include "nsKDEUtils.h"
- 
- class nsUnixSystemProxySettings final : public nsISystemProxySettings {
- public:
-   NS_DECL_ISUPPORTS
-   NS_DECL_NSISYSTEMPROXYSETTINGS
- 
-   nsUnixSystemProxySettings()
-     : mSchemeProxySettings(4)
-@@ -39,16 +40,17 @@ private:
-   nsCOMPtr<nsIGSettingsService> mGSettings;
-   nsCOMPtr<nsIGSettingsCollection> mProxySettings;
-   nsInterfaceHashtable<nsCStringHashKey, nsIGSettingsCollection> mSchemeProxySettings;
-   bool IsProxyMode(const char* aMode);
-   nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, nsACString& aResult);
-   nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult);
-   nsresult GetProxyFromGSettings(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult);
-   nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, nsACString& aResult);
-+  nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
- };
- 
- NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings)
- 
- NS_IMETHODIMP
- nsUnixSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly)
- {
-   // dbus prevents us from being threadsafe, but this routine should not block anyhow
-@@ -505,16 +507,19 @@ nsUnixSystemProxySettings::GetProxyFromG
- 
- nsresult
- nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec,
-                                           const nsACString & aScheme,
-                                           const nsACString & aHost,
-                                           const int32_t      aPort,
-                                           nsACString & aResult)
- {
-+  if (nsKDEUtils::kdeSupport())
-+    return GetProxyFromKDE(aScheme, aHost, aPort, aResult);
-+
-   if (mProxySettings) {
-     nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult);
-     if (NS_SUCCEEDED(rv))
-       return rv;
-   }
-   if (mGConf)
-     return GetProxyFromGConf(aScheme, aHost, aPort, aResult);
- 
-@@ -540,8 +545,34 @@ static const mozilla::Module::ContractID
- 
- static const mozilla::Module kUnixProxyModule = {
-   mozilla::Module::kVersion,
-   kUnixProxyCIDs,
-   kUnixProxyContracts
- };
- 
- NSMODULE_DEFN(nsUnixProxyModule) = &kUnixProxyModule;
-+
-+nsresult
-+nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
-+                                           const nsACString& aHost,
-+                                           PRInt32 aPort,
-+                                           nsACString& aResult)
-+{
-+  nsAutoCString url;
-+  url = aScheme;
-+  url += "://";
-+  url += aHost;
-+  if( aPort >= 0 )
-+  {
-+    url += ":";
-+    url += nsPrintfCString("%d", aPort);
-+  }
-+  nsTArray<nsCString> command;
-+  command.AppendElement( NS_LITERAL_CSTRING( "GETPROXY" ));
-+  command.AppendElement( url );
-+  nsTArray<nsCString> result;
-+  if( !nsKDEUtils::command( command, &result ) || result.Length() != 1 )
-+    return NS_ERROR_FAILURE;
-+  aResult = result[0];
-+  return NS_OK;
-+}
-+
-diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build
---- a/toolkit/xre/moz.build
-+++ b/toolkit/xre/moz.build
-@@ -48,17 +48,19 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'ui
- elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-     EXPORTS += ['nsQAppInstance.h']
-     SOURCES += [
-         '!moc_nsNativeAppSupportQt.cpp',
-         'nsNativeAppSupportQt.cpp',
-         'nsQAppInstance.cpp',
-     ]
- elif CONFIG['MOZ_ENABLE_GTK']:
-+    EXPORTS += ['nsKDEUtils.h']
-     UNIFIED_SOURCES += [
-+        'nsKDEUtils.cpp',
-         'nsNativeAppSupportUnix.cpp',
-     ]
- else:
-     UNIFIED_SOURCES += [
-         'nsNativeAppSupportDefault.cpp',
-     ]
- 
- if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
-diff --git a/toolkit/xre/nsKDEUtils.cpp b/toolkit/xre/nsKDEUtils.cpp
-new file mode 100644
---- /dev/null
-+++ b/toolkit/xre/nsKDEUtils.cpp
-@@ -0,0 +1,339 @@
-+/* -*- 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
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#include "nsKDEUtils.h"
-+#include "nsIWidget.h"
-+#include "nsISupportsPrimitives.h"
-+#include "nsIMutableArray.h"
-+#include "nsComponentManagerUtils.h"
-+#include "nsArrayUtils.h"
-+
-+#include <gtk/gtk.h>
-+
-+#include <limits.h>
-+#include <stdio.h>
-+#include <sys/wait.h>
-+#include <sys/resource.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()
-+    {
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "CHECK" ));
-+    command.AppendElement( 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;
-+    nsTArray<nsCString>* 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 );
-+        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 );
-+            }
-+        }
-+
-+    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, false );
-+        }
-+
-+    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())
-+        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
-+            {
-+            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 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
---- /dev/null
-+++ b/toolkit/xre/nsKDEUtils.h
-@@ -0,0 +1,48 @@
-+/* -*- 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/. */
-+
-+#ifndef nsKDEUtils_h__
-+#define nsKDEUtils_h__
-+
-+#include "nsStringGlue.h"
-+#include "nsTArray.h"
-+#include <stdio.h>
-+
-+typedef struct _GtkWindow GtkWindow;
-+
-+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 );
-+
-+    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/moz.build b/uriloader/exthandler/moz.build
---- a/uriloader/exthandler/moz.build
-+++ b/uriloader/exthandler/moz.build
-@@ -72,17 +72,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',
-     ]
- 
- if CONFIG['MOZ_ENABLE_GTK']:
-     UNIFIED_SOURCES += [
-+        'unix/nsCommonRegistry.cpp',
-         'unix/nsGNOMERegistry.cpp',
-+	'unix/nsKDERegistry.cpp',
-         'unix/nsMIMEInfoUnix.cpp',
-     ]
- elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
-     UNIFIED_SOURCES += [
-         'android/nsAndroidHandlerApp.cpp',
-         'android/nsExternalSharingAppService.cpp',
-         'android/nsExternalURLHandlerService.cpp',
-         'android/nsMIMEInfoAndroid.cpp',
-@@ -125,16 +127,17 @@ include('/ipc/chromium/chromium-config.m
- 
- FINAL_LIBRARY = 'xul'
- 
- LOCAL_INCLUDES += [
-     '/dom/base',
-     '/dom/ipc',
-     '/netwerk/base',
-     '/netwerk/protocol/http',
-+    '/toolkit/xre',
- ]
- 
- if CONFIG['MOZ_ENABLE_DBUS']:
-     CXXFLAGS += CONFIG['TK_CFLAGS']
-     CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
- 
- if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('qt', 'gtk2', 'gtk3'):
-     CXXFLAGS += CONFIG['TK_CFLAGS']
-diff --git a/uriloader/exthandler/unix/nsCommonRegistry.cpp b/uriloader/exthandler/unix/nsCommonRegistry.cpp
-new file mode 100644
---- /dev/null
-+++ b/uriloader/exthandler/unix/nsCommonRegistry.cpp
-@@ -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
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#include "nsCommonRegistry.h"
-+
-+#include "nsGNOMERegistry.h"
-+#include "nsKDERegistry.h"
-+#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 */ 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 );
-+}
-diff --git a/uriloader/exthandler/unix/nsCommonRegistry.h b/uriloader/exthandler/unix/nsCommonRegistry.h
-new file mode 100644
---- /dev/null
-+++ b/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
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#ifndef nsCommonRegistry_h__
-+#define nsCommonRegistry_h__
-+
-+#include "nsIURI.h"
-+#include "nsCOMPtr.h"
-+
-+class nsMIMEInfoBase;
-+
-+class nsCommonRegistry
-+{
-+ public:
-+  static bool 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);
-+};
-+
-+#endif
-diff --git a/uriloader/exthandler/unix/nsKDERegistry.cpp b/uriloader/exthandler/unix/nsKDERegistry.cpp
-new file mode 100644
---- /dev/null
-+++ b/uriloader/exthandler/unix/nsKDERegistry.cpp
-@@ -0,0 +1,88 @@
-+/* -*- 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/. */
-+
-+#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 */ bool
-+nsKDERegistry::HandlerExists(const char *aProtocolScheme)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "HANDLEREXISTS" ));
-+    command.AppendElement( nsAutoCString( aProtocolScheme ));
-+    return nsKDEUtils::command( command );
-+}
-+
-+/* static */ nsresult
-+nsKDERegistry::LoadURL(nsIURI *aURL)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "OPEN" ));
-+    nsCString url;
-+    aURL->GetSpec( url );
-+    command.AppendElement( url );
-+    bool rv = nsKDEUtils::command( command );
-+    if (!rv)
-+      return NS_ERROR_FAILURE;
-+
-+    return NS_OK;
-+}
-+
-+/* static */ void
-+nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
-+                                     nsAString& aDesc)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "GETAPPDESCFORSCHEME" ));
-+    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( NS_LITERAL_CSTRING( "GETFROMEXTENSION" ));
-+    command.AppendElement( aFileExt );
-+    return GetFromHelper( command );
-+}
-+
-+/* static */ already_AddRefed<nsMIMEInfoBase>
-+nsKDERegistry::GetFromType(const nsACString& aMIMEType)
-+{
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "GETFROMTYPE" ));
-+    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 ];
-+        mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
-+        mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
-+        return mimeInfo.forget();
-+        }
-+    return nullptr;
-+}
-diff --git a/uriloader/exthandler/unix/nsKDERegistry.h b/uriloader/exthandler/unix/nsKDERegistry.h
-new file mode 100644
---- /dev/null
-+++ b/uriloader/exthandler/unix/nsKDERegistry.h
-@@ -0,0 +1,34 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#ifndef nsKDERegistry_h__
-+#define nsKDERegistry_h__
-+
-+#include "nsIURI.h"
-+#include "nsCOMPtr.h"
-+#include "nsTArray.h"
-+
-+class nsMIMEInfoBase;
-+class nsAutoCString;
-+class nsCString;
-+
-+class nsKDERegistry
-+{
-+ public:
-+  static bool 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 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
-@@ -7,32 +7,35 @@
- #ifdef MOZ_WIDGET_QT
- #if (MOZ_ENABLE_CONTENTACTION)
- #include <contentaction/contentaction.h>
- #include "nsContentHandlerApp.h"
- #endif
- #endif
- 
- #include "nsMIMEInfoUnix.h"
--#include "nsGNOMERegistry.h"
-+#include "nsCommonRegistry.h"
- #include "nsIGIOService.h"
- #include "nsNetCID.h"
- #include "nsIIOService.h"
- #include "nsAutoPtr.h"
- #ifdef MOZ_ENABLE_DBUS
- #include "nsDBusHandlerApp.h"
- #endif
- #ifdef MOZ_WIDGET_QT
- #include "nsMIMEInfoQt.h"
- #endif
-+#if defined(XP_UNIX) && !defined(XP_MACOSX)
-+#include "nsKDEUtils.h"
-+#endif
- 
- nsresult
- nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
- {
--  nsresult rv = nsGNOMERegistry::LoadURL(aURI);
-+  nsresult rv = nsCommonRegistry::LoadURL(aURI);
- 
- #ifdef MOZ_WIDGET_QT
-   if (NS_FAILED(rv)) {
-     rv = nsMIMEInfoQt::LoadUriInternal(aURI);
-   }
- #endif
- 
-   return rv;
-@@ -45,24 +48,24 @@ nsMIMEInfoUnix::GetHasDefaultHandler(boo
-   // either /etc/mailcap or ${HOME}/.mailcap, in which case we don't want to
-   // give the GNOME answer.
-   if (mDefaultApplication)
-     return nsMIMEInfoImpl::GetHasDefaultHandler(_retval);
- 
-   *_retval = false;
- 
-   if (mClass == eProtocolInfo) {
--    *_retval = nsGNOMERegistry::HandlerExists(mSchemeOrType.get());
-+    *_retval = nsCommonRegistry::HandlerExists(mSchemeOrType.get());
-   } else {
--    RefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromType(mSchemeOrType);
-+    RefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromType(mSchemeOrType);
-     if (!mimeInfo) {
-       nsAutoCString ext;
-       nsresult rv = GetPrimaryExtension(ext);
-       if (NS_SUCCEEDED(rv)) {
--        mimeInfo = nsGNOMERegistry::GetFromExtension(ext);
-+        mimeInfo = nsCommonRegistry::GetFromExtension(ext);
-       }
-     }
-     if (mimeInfo)
-       *_retval = true;
-   }
- 
-   if (*_retval)
-     return NS_OK;
-@@ -97,16 +100,33 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
-     ContentAction::Action::defaultActionForFile(uri, QString(mSchemeOrType.get()));
-   if (action.isValid()) {
-     action.trigger();
-     return NS_OK;
-   }
-   return NS_ERROR_FAILURE;
- #endif
- 
-+  if( nsKDEUtils::kdeSupport()) {
-+    bool supports;
-+    if( NS_SUCCEEDED( GetHasDefaultHandler( &supports )) && supports ) {
-+      nsTArray<nsCString> command;
-+      command.AppendElement( NS_LITERAL_CSTRING( "OPEN" ));
-+      command.AppendElement( nativePath );
-+      command.AppendElement( NS_LITERAL_CSTRING( "MIMETYPE" ));
-+      command.AppendElement( mSchemeOrType );
-+      if( nsKDEUtils::command( command ))
-+        return NS_OK;
-+    }
-+    if (!mDefaultApplication)
-+      return NS_ERROR_FILE_NOT_FOUND;
-+
-+    return LaunchWithIProcess(mDefaultApplication, nativePath);
-+  }
-+
-   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 = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
-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
-@@ -10,17 +10,17 @@
- #if defined(MOZ_ENABLE_CONTENTACTION)
- #include <contentaction/contentaction.h>
- #include <QString>
- #endif
- 
- #include "nsOSHelperAppService.h"
- #include "nsMIMEInfoUnix.h"
- #ifdef MOZ_WIDGET_GTK
--#include "nsGNOMERegistry.h"
-+#include "nsCommonRegistry.h"
- #endif
- #include "nsISupports.h"
- #include "nsString.h"
- #include "nsReadableUtils.h"
- #include "nsUnicharUtils.h"
- #include "nsXPIDLString.h"
- #include "nsIURL.h"
- #include "nsIFileStreams.h"
-@@ -1146,26 +1146,26 @@ nsresult nsOSHelperAppService::OSProtoco
-     ContentAction::Action::defaultActionForScheme(QString(aProtocolScheme) + ':');
- 
-   if (action.isValid())
-     *aHandlerExists = true;
- #endif
- 
- #ifdef MOZ_WIDGET_GTK
-   // Check the GNOME registry for a protocol handler
--  *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme);
-+  *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme);
- #endif
- 
-   return NS_OK;
- }
- 
- NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
- {
- #ifdef MOZ_WIDGET_GTK
--  nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval);
-+  nsCommonRegistry::GetAppDescForScheme(aScheme, _retval);
-   return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK;
- #else
-   return NS_ERROR_NOT_AVAILABLE;
- #endif
- }
- 
- nsresult nsOSHelperAppService::GetFileTokenForPath(const char16_t * platformAppPath, nsIFile ** aFile)
- {
-@@ -1252,17 +1252,17 @@ nsOSHelperAppService::GetFromExtension(c
-                                          mime_types_description,
-                                          true);
- 
-   if (NS_FAILED(rv) || majorType.IsEmpty()) {
- 
- #ifdef MOZ_WIDGET_GTK
-     LOG(("Looking in GNOME registry\n"));
-     RefPtr<nsMIMEInfoBase> gnomeInfo =
--      nsGNOMERegistry::GetFromExtension(aFileExt);
-+      nsCommonRegistry::GetFromExtension(aFileExt);
-     if (gnomeInfo) {
-       LOG(("Got MIMEInfo from GNOME registry\n"));
-       return gnomeInfo.forget();
-     }
- #endif
- 
-     rv = LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt),
-                                   majorType,
-@@ -1373,17 +1373,17 @@ nsOSHelperAppService::GetFromType(const 
-   nsAutoString extensions, mime_types_description;
-   LookUpExtensionsAndDescription(majorType,
-                                  minorType,
-                                  extensions,
-                                  mime_types_description);
- 
- #ifdef MOZ_WIDGET_GTK
-   if (handler.IsEmpty()) {
--    RefPtr<nsMIMEInfoBase> gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType);
-+    RefPtr<nsMIMEInfoBase> gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType);
-     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
-@@ -86,16 +86,17 @@ else:
- include('/ipc/chromium/chromium-config.mozbuild')
- 
- FINAL_LIBRARY = 'xul'
- 
- LOCAL_INCLUDES += [
-     '/layout/generic',
-     '/layout/xul',
-     '/other-licenses/atk-1.0',
-+    '/toolkit/xre',
-     '/widget',
- ]
- 
- if CONFIG['MOZ_X11']:
-     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
-@@ -4,32 +4,34 @@
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- 
- #include "mozilla/Types.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- 
- #include <gtk/gtk.h>
-+#include <gdk/gdkx.h>
- 
- #include "nsGtkUtils.h"
- #include "nsIFileURL.h"
- #include "nsIURI.h"
- #include "nsIWidget.h"
- #include "nsIFile.h"
- #include "nsIStringBundle.h"
- 
- #include "nsArrayEnumerator.h"
- #include "nsMemory.h"
- #include "nsEnumeratorUtils.h"
- #include "nsNetUtil.h"
- #include "nsReadableUtils.h"
- #include "mozcontainer.h"
- 
- #include "nsFilePicker.h"
-+#include "nsKDEUtils.h"
- 
- using namespace mozilla;
- 
- #define MAX_PREVIEW_SIZE 180
- // bug 1184009
- #define MAX_PREVIEW_SOURCE_SIZE 4096
- 
- nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr;
-@@ -246,17 +248,19 @@ nsFilePicker::AppendFilters(int32_t aFil
-   return nsBaseFilePicker::AppendFilters(aFilterMask);
- }
- 
- 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;
-   }
- 
-   nsAutoCString filter, name;
-   CopyUTF16toUTF8(aFilter, filter);
-   CopyUTF16toUTF8(aTitle, name);
- 
-   mFilters.AppendElement(filter);
-   mFilterNames.AppendElement(name);
-@@ -371,16 +375,32 @@ nsFilePicker::Show(int16_t *aReturn)
- 
- NS_IMETHODIMP
- nsFilePicker::Open(nsIFilePickerShownCallback *aCallback)
- {
-   // 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()) {
-+    int16_t result;
-+    mCallback = aCallback;
-+    mRunning = true;
-+    kdeFileDialog(&result);
-+    if (mCallback) {
-+      mCallback->Done(result);
-+      mCallback = nullptr;
-+    } else {
-+      mResult = result;
-+    }
-+    mRunning = false;
-+    return NS_OK;
-+  }
-+
-   nsXPIDLCString title;
-   title.Adopt(ToNewUTF8String(mTitle));
- 
-   GtkWindow *parent_widget =
-     GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
- 
-   GtkFileChooserAction action = GetGtkFileChooserAction(mMode);
-   const gchar *accept_button = (action == GTK_FILE_CHOOSER_ACTION_SAVE)
-@@ -595,8 +615,235 @@ nsFilePicker::Done(GtkWidget* file_choos
-   if (mCallback) {
-     mCallback->Done(result);
-     mCallback = nullptr;
-   } else {
-     mResult = result;
-   }
-   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;
-+    }
-+
-+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(PRInt16 *aReturn)
-+    {
-+    NS_ENSURE_ARG_POINTER(aReturn);
-+
-+    if( mMode == modeOpen && mFilters.Length() == 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;
-+            }
-+        }
-+
-+  nsAutoCString directory;
-+  if (mDisplayDirectory) {
-+    mDisplayDirectory->GetNativePath(directory);
-+  } else if (mPrevDisplayDirectory) {
-+    mPrevDisplayDirectory->GetNativePath(directory);
-+  }
-+
-+    nsAutoCString 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 = ".";
-+
-+    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( NS_LITERAL_CSTRING( "MULTIPLE" ));
-+    if( PRInt32 xid = windowToXid( mParentWidget ))
-+        {
-+        command.AppendElement( NS_LITERAL_CSTRING( "PARENT" ));
-+        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 :-/
-+                {
-+                mFileURL = nsCString( "file://" );
-+                mFileURL.Append( output[ 0 ] );
-+                }
-+            }
-+  // 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);
-+    }
-+  }
-+        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(PRInt16 *aReturn)
-+    {
-+    NS_ENSURE_ARG_POINTER(aReturn);
-+
-+    nsXPIDLCString title;
-+    title.Adopt(ToNewUTF8String(mTitle));
-+
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING( "APPSDIALOG" ));
-+    command.AppendElement( title );
-+    if( PRInt32 xid = windowToXid( mParentWidget ))
-+        {
-+        command.AppendElement( NS_LITERAL_CSTRING( "PARENT" ));
-+        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;
-+    }
-+
-diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h
---- a/widget/gtk/nsFilePicker.h
-+++ b/widget/gtk/nsFilePicker.h
-@@ -69,14 +69,20 @@ protected:
-   nsString  mDefaultExtension;
- 
-   nsTArray<nsCString> mFilters;
-   nsTArray<nsCString> mFilterNames;
- 
- private:
-   static nsIFile *mPrevDisplayDirectory;
- 
-+  bool kdeRunning();
-+  bool getKdeRunning();
-+  NS_IMETHODIMP kdeFileDialog(PRInt16 *aReturn);
-+  NS_IMETHODIMP kdeAppsDialog(PRInt16 *aReturn);
-+  nsCString kdeMakeFilter( int index );
-+
- #if (MOZ_WIDGET_GTK == 3)
-   GtkFileChooserWidget *mFileChooserDelegate;
- #endif
- };
- 
- #endif
-diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp
---- a/xpcom/components/ManifestParser.cpp
-+++ b/xpcom/components/ManifestParser.cpp
-@@ -35,16 +35,17 @@
- 
- #include "nsIConsoleService.h"
- #include "nsIScriptError.h"
- #include "nsIXULAppInfo.h"
- #include "nsIXULRuntime.h"
- #ifdef MOZ_B2G_LOADER
- #include "mozilla/XPTInterfaceInfoManager.h"
- #endif
-+#include "nsKDEUtils.h"
- 
- #ifdef MOZ_B2G_LOADER
- #define XPTONLY_MANIFEST &nsComponentManagerImpl::XPTOnlyManifestManifest
- #define XPTONLY_XPT &nsComponentManagerImpl::XPTOnlyManifestXPT
- #else
- #define XPTONLY_MANIFEST nullptr
- #define XPTONLY_XPT nullptr
- #endif
-@@ -494,16 +495,17 @@ ParseManifest(NSLocationType aType, File
-   NS_NAMED_LITERAL_STRING(kRemoteEnabled, "remoteenabled");
-   NS_NAMED_LITERAL_STRING(kRemoteRequired, "remoterequired");
-   NS_NAMED_LITERAL_STRING(kApplication, "application");
-   NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
-   NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion");
-   NS_NAMED_LITERAL_STRING(kOs, "os");
-   NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
-   NS_NAMED_LITERAL_STRING(kABI, "abi");
-+  NS_NAMED_LITERAL_STRING(kDesktop, "desktop");
-   NS_NAMED_LITERAL_STRING(kProcess, "process");
- #if defined(MOZ_WIDGET_ANDROID)
-   NS_NAMED_LITERAL_STRING(kTablet, "tablet");
- #endif
- 
-   NS_NAMED_LITERAL_STRING(kMain, "main");
-   NS_NAMED_LITERAL_STRING(kContent, "content");
- 
-@@ -554,44 +556,49 @@ ParseManifest(NSLocationType aType, File
-         CopyUTF8toUTF16(s, abi);
-         abi.Insert(char16_t('_'), 0);
-         abi.Insert(osTarget, 0);
-       }
-     }
-   }
- 
-   nsAutoString osVersion;
-+  nsAutoString desktop;
- #if defined(XP_WIN)
- #pragma warning(push)
- #pragma warning(disable:4996) // VC12+ deprecates GetVersionEx
-   OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
-   if (GetVersionEx(&info)) {
-     nsTextFormatter::ssprintf(osVersion, MOZ_UTF16("%ld.%ld"),
-                               info.dwMajorVersion,
-                               info.dwMinorVersion);
-   }
-+  desktop = NS_LITERAL_STRING("win");
- #pragma warning(pop)
- #elif defined(MOZ_WIDGET_COCOA)
-   SInt32 majorVersion = nsCocoaFeatures::OSXVersionMajor();
-   SInt32 minorVersion = nsCocoaFeatures::OSXVersionMinor();
-   nsTextFormatter::ssprintf(osVersion, MOZ_UTF16("%ld.%ld"),
-                             majorVersion,
-                             minorVersion);
-+  desktop = NS_LITERAL_STRING("macosx");
- #elif defined(MOZ_WIDGET_GTK)
-   nsTextFormatter::ssprintf(osVersion, MOZ_UTF16("%ld.%ld"),
-                             gtk_major_version,
-                             gtk_minor_version);
-+  desktop = nsKDEUtils::kdeSession() ? NS_LITERAL_STRING("kde") : NS_LITERAL_STRING("gnome");
- #elif defined(MOZ_WIDGET_ANDROID)
-   bool isTablet = false;
-   if (mozilla::AndroidBridge::Bridge()) {
-     mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION",
-                                                            "RELEASE",
-                                                            osVersion);
-     isTablet = mozilla::widget::GeckoAppShell::IsTablet();
-   }
-+  desktop = NS_LITERAL_STRING("android");
- #endif
- 
-   if (XRE_IsContentProcess()) {
-     process = kContent;
-   } else {
-     process = kMain;
-   }
- 
-@@ -694,25 +701,27 @@ ParseManifest(NSLocationType aType, File
-     TriState stOsVersion = eUnspecified;
-     TriState stOs = eUnspecified;
-     TriState stABI = eUnspecified;
-     TriState stProcess = eUnspecified;
- #if defined(MOZ_WIDGET_ANDROID)
-     TriState stTablet = eUnspecified;
- #endif
-     int flags = 0;
-+    TriState stDesktop = eUnspecified;
- 
-     while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
-            ok) {
-       ToLowerCase(token);
-       NS_ConvertASCIItoUTF16 wtoken(token);
- 
-       if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
-           CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
-           CheckStringFlag(kABI, wtoken, abi, stABI) ||
-+          CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
-           CheckStringFlag(kProcess, wtoken, process, stProcess) ||
-           CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
-           CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
-           CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) {
-         continue;
-       }
- 
- #if defined(MOZ_WIDGET_ANDROID)
-@@ -762,16 +771,17 @@ ParseManifest(NSLocationType aType, File
-     }
- 
-     if (!ok ||
-         stApp == eBad ||
-         stAppVersion == eBad ||
-         stGeckoVersion == eBad ||
-         stOs == eBad ||
-         stOsVersion == eBad ||
-+        stDesktop == eBad ||
- #ifdef MOZ_WIDGET_ANDROID
-         stTablet == 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
-@@ -47,12 +47,13 @@ FINAL_LIBRARY = 'xul'
- GENERATED_INCLUDES += ['..']
- LOCAL_INCLUDES += [
-     '../base',
-     '../build',
-     '../ds',
-     '../reflect/xptinfo',
-     '/chrome',
-     '/modules/libjar',
-+    '/toolkit/xre'
- ]
- 
- if CONFIG['MOZ_WIDGET_GTK']:
-     CXXFLAGS += CONFIG['TK_CFLAGS']
-diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp
---- a/xpcom/io/nsLocalFileUnix.cpp
-+++ b/xpcom/io/nsLocalFileUnix.cpp
-@@ -47,16 +47,17 @@
- #include "prproces.h"
- #include "nsIDirectoryEnumerator.h"
- #include "nsISimpleEnumerator.h"
- #include "private/pprio.h"
- #include "prlink.h"
- 
- #ifdef MOZ_WIDGET_GTK
- #include "nsIGIOService.h"
-+#include "nsKDEUtils.h"
- #endif
- 
- #ifdef MOZ_WIDGET_COCOA
- #include <Carbon/Carbon.h>
- #include "CocoaFileUtils.h"
- #include "prmem.h"
- #include "plbase64.h"
- 
-@@ -1963,42 +1964,52 @@ nsLocalFile::SetPersistentDescriptor(con
-   return InitWithNativePath(aPersistentDescriptor);
- #endif
- }
- 
- NS_IMETHODIMP
- nsLocalFile::Reveal()
- {
- #ifdef MOZ_WIDGET_GTK
--  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
--  if (!giovfs) {
--    return NS_ERROR_FAILURE;
--  }
-+  nsAutoCString url;
- 
-   bool isDirectory;
-   if (NS_FAILED(IsDirectory(&isDirectory))) {
-     return NS_ERROR_FAILURE;
-   }
- 
-+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
-   if (isDirectory) {
--    return giovfs->ShowURIForInput(mPath);
-+    url = mPath;
-   } else if (NS_SUCCEEDED(giovfs->OrgFreedesktopFileManager1ShowItems(mPath))) {
-     return NS_OK;
-   } else {
-     nsCOMPtr<nsIFile> parentDir;
-     nsAutoCString dirPath;
-     if (NS_FAILED(GetParent(getter_AddRefs(parentDir)))) {
-       return NS_ERROR_FAILURE;
-     }
-     if (NS_FAILED(parentDir->GetNativePath(dirPath))) {
-       return NS_ERROR_FAILURE;
-     }
- 
--    return giovfs->ShowURIForInput(dirPath);
-+    url = dirPath;
-   }
-+
-+  if(nsKDEUtils::kdeSupport()) {
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING("REVEAL") );
-+    command.AppendElement( mPath );
-+    return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
-+  }
-+
-+  if (!giovfs)
-+    return NS_ERROR_FAILURE;
-+
-+  return giovfs->ShowURIForInput(url);
- #elif defined(MOZ_WIDGET_COCOA)
-   CFURLRef url;
-   if (NS_SUCCEEDED(GetCFURL(&url))) {
-     nsresult rv = CocoaFileUtils::RevealFileInFinder(url);
-     ::CFRelease(url);
-     return rv;
-   }
-   return NS_ERROR_FAILURE;
-@@ -2006,16 +2017,22 @@ nsLocalFile::Reveal()
-   return NS_ERROR_FAILURE;
- #endif
- }
- 
- NS_IMETHODIMP
- nsLocalFile::Launch()
- {
- #ifdef MOZ_WIDGET_GTK
-+  if( nsKDEUtils::kdeSupport()) {
-+    nsTArray<nsCString> command;
-+    command.AppendElement( NS_LITERAL_CSTRING("OPEN") );
-+    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->ShowURIForInput(mPath);
- #elif defined(MOZ_ENABLE_CONTENTACTION)
-   QUrl uri = QUrl::fromLocalFile(QString::fromUtf8(mPath.get()));