[Trisquel-devel] [PATCH] Added OpenSUSE patches for Abrowser KDE support.

Legimet legimet.calc at gmail.com
Fri Mar 28 02:19:51 CET 2014


Here is a patch adding KDE support to Abrowser (the relevant issue is at 
https://trisquel.info/en/issues/11035). Besides this patch, a package 
kmozillahelper is needed.

Legimet

---
 helpers/DATA/firefox/abrowser-kde.patch | 1789 +++++++++++++++
 helpers/DATA/firefox/mozilla-kde.patch  | 3707 
+++++++++++++++++++++++++++++++
 helpers/make-firefox                    |   14 +-
 3 files changed, 5509 insertions(+), 1 deletion(-)
 create mode 100644 helpers/DATA/firefox/abrowser-kde.patch
 create mode 100644 helpers/DATA/firefox/mozilla-kde.patch

diff --git a/helpers/DATA/firefox/abrowser-kde.patch 
b/helpers/DATA/firefox/abrowser-kde.patch
new file mode 100644
index 0000000..d076e73
--- /dev/null
+++ b/helpers/DATA/firefox/abrowser-kde.patch
@@ -0,0 +1,1789 @@
+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,1177 @@
++#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://browser/skin/devtools/common.css" 
type="text/css"?>
++<?xml-stylesheet href="chrome://browser/skin/" 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
++        titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
++        lightweightthemes="true"
++        lightweightthemesfooter="browser-bottombox"
++        windowtype="navigator:browser"
++        macanimationtype="document"
++        screenX="4" screenY="4"
++        fullscreenbutton="true"
++        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);"/>
++      <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);"/>
++      <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"/>
++
++    <!-- for search and content formfill/pw manager -->
++    <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" 
hidden="true"/>
++
++    <!-- for url bar autocomplete -->
++    <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" 
noautofocus="true" hidden="true"/>
++
++    <!-- for select dropdowns -->
++    <menupopup id="ContentSelectDropdown" rolluponmousewheel="true" 
hidden="true"/>
++
++    <!-- 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"
++           align="start"
++           orient="vertical"
++           role="alert">
++      <label id="UITourTooltipTitle" flex="1"/>
++      <description id="UITourTooltipDescription" flex="1"/>
++    </panel>
++    <html:div id="UITourHighlightContainer" style="position:relative">
++      <html:div id="UITourHighlight"></html:div>
++    </html:div>
++
++    <panel id="socialActivatedNotification"
++           type="arrow"
++           hidden="true"
++           align="start"
++           orient="horizontal"
++           role="alert">
++      <image id="social-activation-icon" class="popup-notification-icon"/>
++      <vbox flex="1">
++        <description id="social-activation-message" class="popup-
notification-description">&social.activated.description;</description>
++        <spacer flex="1"/>
++        <hbox pack="start" align="center" class="popup-notification-button-
container">
++          <label  id="social-undoactivation-button"
++                  class="text-link"
++                  value="&social.activated.undo.label;"
++                  accesskey="&social.activated.undo.accesskey;"
++                  onclick="SocialUI.undoActivation(this);"/>
++          <spacer flex="1"/>
++          <button id="social-activation-button"
++                  default="true"
++                  autofocus="autofocus"
++                  label="&social.ok.label;"
++                  accesskey="&social.ok.accesskey;"
++                  oncommand="SocialUI.activationPanel.hidePopup();"/>
++        </hbox>
++      </vbox>
++    </panel>
++
++    <panel id="social-share-panel"
++           class="social-panel"
++           type="arrow"
++           orient="horizontal"
++           onpopupshowing="SocialShare.onShowing()"
++           onpopuphidden="SocialShare.onHidden()"
++           hidden="true">
++      <vbox class="social-share-toolbar">
++        <vbox id="social-share-provider-buttons" flex="1"/>
++      </vbox>
++    </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"/>
++
++    <menupopup id="toolbar-context-menu"
++               onpopupshowing="onViewToolbarsPopupShowing(event);">
++      <menuseparator/>
++      <menuitem command="cmd_ToggleTabsOnTop"
++                type="checkbox"
++                label="&viewTabsOnTop.label;"
++                accesskey="&viewTabsOnTop.accesskey;"/>
++      <menuitem command="cmd_CustomizeToolbars"
++                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="start"
++               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"/>
++
++    <!-- Popup for site identity information -->
++    <panel id="identity-popup"
++           type="arrow"
++           hidden="true"
++           noautofocus="true"
++           onpopupshown="if (event.target == this)
++                           gIdentityHandler.onPopupShown(event);"
++           orient="vertical"
++           level="top">
++      <hbox id="identity-popup-container" align="top">
++        <image id="identity-popup-icon"/>
++        <vbox id="identity-popup-content-box">
++          <label id="identity-popup-brandName"
++                 class="identity-popup-label"
++                 value="&brandFullName;"/>
++          <label id="identity-popup-chromeLabel"
++                 class="identity-popup-label"/>
++          <label id="identity-popup-connectedToLabel"
++                 class="identity-popup-label"
++                 value="&identity.connectedTo;"/>
++          <label id="identity-popup-connectedToLabel2"
++                 class="identity-popup-label"
++                 value="&identity.unverifiedsite2;"/>
++          <description id="identity-popup-content-host"
++                       class="identity-popup-description"/>
++          <label id="identity-popup-runByLabel"
++                 class="identity-popup-label"
++                 value="&identity.runBy;"/>
++          <description id="identity-popup-content-owner"
++                       class="identity-popup-description"/>
++          <description id="identity-popup-content-supplemental"
++                       class="identity-popup-description"/>
++          <description id="identity-popup-content-verifier"
++                       class="identity-popup-description"/>
++          <hbox id="identity-popup-encryption" flex="1">
++            <vbox>
++              <image id="identity-popup-encryption-icon"/>
++            </vbox>
++            <description id="identity-popup-encryption-label" flex="1"
++                         class="identity-popup-description"/>
++          </hbox>
++          <vbox id="identity-popup-permissions">
++            <separator class="thin"/>
++            <label class="identity-popup-label header"
++                   value="&identity.permissions;"/>
++            <vbox id="identity-popup-permission-list" class="indent"/>
++          </vbox>
++        </vbox>
++      </hbox>
++      <!-- Footer button to open security page info -->
++      <hbox id="identity-popup-button-container" align="center">
++        <button id="identity-popup-help-icon"
++               oncommand="gIdentityHandler.handleHelpCommand(event);"
++               tooltiptext="&identity.help.tooltip;"/>
++        <spacer flex="1"/>
++        <button id="identity-popup-more-info-button"
++                label="&identity.moreInfoLinkText;"
++                oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
++      </hbox>
++    </panel>
++
++    <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>
++
++    <!-- Bookmarks and history tooltip -->
++    <tooltip id="bhTooltip"/>
++
++    <panel id="customizeToolbarSheetPopup"
++           noautohide="true"
++           sheetstyle="&dialog.dimensions;"/>
++
++    <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>
++
++#include popup-notifications.inc
++
++    <hbox id="downloads-animation-container" mousethrough="always">
++      <vbox id="downloads-notification-anchor">
++        <vbox id="downloads-indicator-notification"/>
++      </vbox>
++    </hbox>
++  </popupset>
++
++#ifdef CAN_DRAW_IN_TITLEBAR
++<vbox id="titlebar">
++  <hbox id="titlebar-content">
++#ifdef MENUBAR_CAN_AUTOHIDE
++    <hbox id="appmenu-button-container">
++      <button id="appmenu-button"
++              type="menu"
++              label="&brandShortName;"
++              style="-moz-user-focus: ignore;">
++#include browser-appmenu.inc
++      </button>
++    </hbox>
++#endif
++    <spacer id="titlebar-spacer" flex="1"/>
++    <hbox id="titlebar-buttonbox-container" align="start">
++      <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>
++  </hbox>
++</vbox>
++#endif
++
++<deck flex="1" id="tab-view-deck">
++<vbox flex="1" id="browser-panel">
++
++  <toolbox id="navigator-toolbox"
++           defaultmode="icons" mode="icons"
++           iconsize="large">
++    <!-- Menu -->
++    <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-
menubar" customizable="true"
++             defaultset="menubar-items"
++             mode="icons" iconsize="small" defaulticonsize="small"
++             lockiconsize="true"
++#ifdef MENUBAR_CAN_AUTOHIDE
++             toolbarname="&menubarCmd.label;"
++             accesskey="&menubarCmd.accesskey;"
++#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
++      <hbox class="titlebar-placeholder" type="appmenu-button" ordinal="0"/>
++      <hbox class="titlebar-placeholder" type="caption-buttons" 
ordinal="1000"/>
++#endif
++    </toolbar>
++
++    <toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
++             toolbarname="&navbarCmd.label;" 
accesskey="&navbarCmd.accesskey;"
++             fullscreentoolbar="true" mode="icons" customizable="true"
++             iconsize="large"
++             defaultset="unified-back-forward-button,urlbar-
container,reload-button,stop-button,search-container,webrtc-status-
button,bookmarks-menu-button,downloads-button,home-button,window-
controls"
++             context="toolbar-context-menu">
++
++      <toolbaritem id="unified-back-forward-button" class="chromeclass-
toolbar-additional"
++                   context="backForwardMenu" removable="true"
++                   forwarddisabled="true"
++                   title="&backForwardItem.title;">
++        <toolbarbutton id="back-button" class="toolbarbutton-1"
++                       label="&backCmd.label;"
++                       command="Browser:BackOrBackDuplicate"
++                       onclick="checkForMiddleClick(this, event);"
++                       tooltip="back-button-tooltip"/>
++        <toolbarbutton id="forward-button" class="toolbarbutton-1"
++                       label="&forwardCmd.label;"
++                       command="Browser:ForwardOrForwardDuplicate"
++                       onclick="checkForMiddleClick(this, event);"
++                       tooltip="forward-button-tooltip"/>
++        <dummyobservertarget hidden="true"
++                             onbroadcast="if (this.getAttribute('disabled') 
== 'true')
++                                            
this.parentNode.setAttribute('forwarddisabled', 'true');
++                                          else
++                                            
this.parentNode.removeAttribute('forwarddisabled');">
++          <observes element="Browser:ForwardOrForwardDuplicate" 
attribute="disabled"/>
++        </dummyobservertarget>
++      </toolbaritem>
++
++      <toolbaritem id="urlbar-container" align="center" flex="400" 
persist="width" combined="true"
++                   title="&locationItem.title;" class="chromeclass-location" 
removable="true">
++        <textbox id="urlbar" flex="1"
++                 placeholder="&urlbar.placeholder2;"
++                 type="autocomplete"
++                 autocompletesearch="urlinline history"
++                 autocompletesearchparam="enable-actions"
++                 autocompletepopup="PopupAutoCompleteRichResult"
++                 completeselectedindex="true"
++                 tabscrolling="true"
++                 showcommentcolumn="true"
++                 showimagecolumn="true"
++                 enablehistory="true"
++                 maxrows="6"
++                 newlines="stripsurroundingwhitespace"
++                 oninput="gBrowser.userTypedValue = this.value;"
++                 ontextentered="this.handleCommand(param);"
++                 ontextreverted="return this.handleRevert();"
++                 pageproxystate="invalid"
++                 onfocus="document.getElementById('identity-
box').style.MozUserFocus= 'normal'"
++                 onblur="setTimeout(function() 
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"/>
++            <image id="identity-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="geo-notification-icon" class="notification-anchor-
icon" role="button"/>
++            <image id="addons-notification-icon" class="notification-anchor-
icon" role="button"/>
++            <image id="indexedDB-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="password-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="webapps-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="plugins-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="web-notifications-notification-icon" 
class="notification-anchor-icon" role="button"/>
++            <image id="plugin-install-notification-icon" 
class="notification-anchor-icon" role="button"/>
++            <image id="mixed-content-blocked-notification-icon" 
class="notification-anchor-icon" role="button"/>
++            <image id="webRTC-shareDevices-notification-icon" 
class="notification-anchor-icon" role="button"/>
++            <image id="webRTC-sharingDevices-notification-icon" 
class="notification-anchor-icon" role="button"/>
++            <image id="pointerLock-notification-icon" class="notification-
anchor-icon" role="button"/>
++            <image id="servicesInstall-notification-icon" 
class="notification-anchor-icon" role="button"/>
++          </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"
++               onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
++               
onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
++               ondragstart="gIdentityHandler.onDragStart(event);">
++            <image id="page-proxy-favicon"
++                   onclick="PageProxyClickHandler(event);"
++                   pageproxystate="invalid"/>
++            <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 id="urlbar-display" 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="star-button"
++                   class="urlbar-icon"
++                   onclick="if (event.button === 0) 
BookmarkingUI.onCommand(event);"/>
++            <image id="go-button"
++                   class="urlbar-icon"
++                   tooltiptext="&goEndCap.tooltip;"
++                   onclick="gURLBar.handleCommand(event);"/>
++          </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>
++      </toolbaritem>
++
++      <toolbarbutton id="reload-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&reloadCmd.label;" removable="true"
++                     command="Browser:ReloadOrDuplicate"
++                     onclick="checkForMiddleClick(this, event);"
++                     tooltiptext="&reloadButton.tooltip;"/>
++
++      <toolbarbutton id="stop-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&stopCmd.label;" removable="true"
++                     command="Browser:Stop"
++                     tooltiptext="&stopButton.tooltip;"/>
++
++      <toolbaritem id="search-container" title="&searchItem.title;"
++                   align="center" class="chromeclass-toolbar-additional"
++                   flex="100" persist="width" removable="true">
++        <searchbar id="searchbar" flex="1"/>
++      </toolbaritem>
++
++      <toolbarbutton id="webrtc-status-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     type="menu"
++                     hidden="true"
++                     orient="horizontal"
++                     label="&webrtcIndicatorButton.label;"
++                     tooltiptext="&webrtcIndicatorButton.tooltip;">
++        <menupopup onpopupshowing="WebrtcIndicator.fillPopup(this);"
++                   onpopuphiding="WebrtcIndicator.clearPopup(this);"
++                   oncommand="WebrtcIndicator.menuCommand(event.target);"/>
++      </toolbarbutton>
++
++      <toolbarbutton id="bookmarks-menu-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     persist="class"
++                     removable="true"
++                     type="menu"
++                     label="&bookmarksMenuButton.label;"
++                     tooltiptext="&bookmarksMenuButton.tooltip;"
++                     ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
++                     ondragover="PlacesMenuDNDHandler.onDragOver(event);"
++                     ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
++                     ondrop="PlacesMenuDNDHandler.onDrop(event);">
++        <menupopup id="BMB_bookmarksPopup"
++                   placespopup="true"
++                   context="placesContext"
++                   openInTabs="children"
++                   oncommand="BookmarksEventHandler.onCommand(event, 
this.parentNode._placesView);"
++                   onclick="BookmarksEventHandler.onClick(event, 
this.parentNode._placesView);"
++                   onpopupshowing="BookmarkingUI.onPopupShowing(event);
++                                   if (!this.parentNode._placesView)
++                                     new PlacesMenu(event, 
'place:folder=BOOKMARKS_MENU');"
++                   tooltip="bhTooltip" popupsinherittooltip="true">
++          <menuitem id="BMB_viewBookmarksToolbar"
++                    placesanonid="view-toolbar"
++                    toolbarId="PersonalToolbar"
++                    type="checkbox"
++                    oncommand="onViewToolbarCommand(event)"
++                    label="&viewBookmarksToolbar.label;"/>
++          <menuseparator/>
++          <menuitem id="BMB_bookmarksShowAll"
++                    label="&showAllBookmarks2.label;"
++                    command="Browser:ShowAllBookmarks"
++                    key="manBookmarkKb"/>
++          <menuseparator/>
++          <menuitem id="BMB_bookmarkThisPage"
++#ifndef XP_MACOSX
++                    class="menuitem-iconic"
++#endif
++                    label="&bookmarkThisPageCmd.label;"
++                    command="Browser:AddBookmarkAs"
++                    key="addBookmarkAsKb"/>
++          <menuitem id="BMB_subscribeToPageMenuitem"
++#ifndef XP_MACOSX
++                    class="menuitem-iconic"
++#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"
++#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"
++                placesanonid="toolbar-autohide"
++                class="menu-iconic bookmark-item"
++                label="&personalbarCmd.label;"
++                container="true">
++            <menupopup id="BMB_bookmarksToolbarPopup"
++                       placespopup="true"
++                       context="placesContext"
++                       onpopupshowing="if (!this.parentNode._placesView)
++                                         new PlacesMenu(event, 
'place:folder=TOOLBAR');"/>
++          </menu>
++          <menuseparator/>
++          <!-- Bookmarks menu items -->
++          <menuseparator builder="end"
++                         class="hide-if-empty-places-result"/>
++          <menuitem id="BMB_unsortedBookmarks"
++                    label="&bookmarksMenuButton.unsorted.label;"
++                    
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
++                    class="menuitem-iconic"/>
++        </menupopup>
++      </toolbarbutton>
++
++      <toolbarbutton id="home-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     persist="class" removable="true"
++                     label="&homeButton.label;"
++                     ondragover="homeButtonObserver.onDragOver(event)"
++                     ondragenter="homeButtonObserver.onDragOver(event)"
++                     ondrop="homeButtonObserver.onDrop(event)"
++                     ondragexit="homeButtonObserver.onDragExit(event)"
++                     onclick="BrowserGoHome(event);"
++                     aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
++
++      <toolbarbutton id="social-share-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     hidden="true"
++                     label="&sharePageCmd.label;"
++                     tooltiptext="&sharePageCmd.label;"
++                     command="Social:SharePage"/>
++
++      <toolbaritem id="social-toolbar-item"
++                   class="chromeclass-toolbar-additional"
++                   removable="false"
++                   title="&socialToolbar.title;"
++                   hidden="true"
++                   skipintoolbarset="true"
++                   observes="socialActiveBroadcaster">
++        <toolbarbutton id="social-notification-icon" class="default-
notification-icon toolbarbutton-1 notification-anchor-icon"
++                   oncommand="PopupNotifications._reshowNotifications(this,
++                                document.getElementById('social-sidebar-
browser'));"/>
++        <toolbarbutton id="social-provider-button"
++                       class="toolbarbutton-1"
++                       type="menu">
++          <menupopup id="social-statusarea-popup">
++            <menuitem class="social-statusarea-user menuitem-iconic" 
pack="start" align="center"
++                      observes="socialBroadcaster_userDetails"
++                      oncommand="SocialUI.showProfile(); 
document.getElementById('social-statusarea-popup').hidePopup();">
++              <image class="social-statusarea-user-portrait"
++                     observes="socialBroadcaster_userDetails"/>
++              <vbox>
++                <label class="social-statusarea-loggedInStatus"
++                       observes="socialBroadcaster_userDetails"/>
++              </vbox>
++            </menuitem>
++#ifndef XP_WIN
++            <menuseparator class="social-statusarea-separator"/>
++#endif
++            <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;"/>
++            <menuitem class="social-toggle-menuitem" 
command="Social:Toggle"/>
++            <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>
++      </toolbaritem>
++
++      <hbox id="window-controls" hidden="true" pack="end">
++        <toolbarbutton id="minimize-button"
++                       tooltiptext="&fullScreenMinimize.tooltip;"
++                       oncommand="window.minimize();"/>
++
++        <toolbarbutton id="restore-button"
++                       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" defaulticonsize="small"
++             lockiconsize="true"
++             class="chromeclass-directories"
++             context="toolbar-context-menu"
++             defaultset="personal-bookmarks"
++             toolbarname="&personalbarCmd.label;" 
accesskey="&personalbarCmd.accesskey;"
++             collapsed="true"
++             customizable="true">
++      <toolbaritem flex="1" id="personal-bookmarks" 
title="&bookmarksItem.title;"
++                   removable="true">
++        <hbox flex="1"
++              id="PlacesToolbar"
++              context="placesContext"
++              onclick="BookmarksEventHandler.onClick(event, 
this._placesView);"
++              oncommand="BookmarksEventHandler.onCommand(event, 
this._placesView);"
++              tooltip="bhTooltip"
++              popupsinherittooltip="true">
++          <toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
++                         mousethrough="never"
++                         label="&bookmarksToolbarItem.label;"/>
++          <hbox flex="1">
++            <hbox align="center">
++              <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>
++
++#ifdef MENUBAR_CAN_AUTOHIDE
++#ifndef CAN_DRAW_IN_TITLEBAR
++#define APPMENU_ON_TABBAR
++#endif
++#endif
++
++
++    <toolbar id="TabsToolbar"
++             class="toolbar-primary"
++             fullscreentoolbar="true"
++             customizable="true"
++             mode="icons" lockmode="true"
++             iconsize="small" defaulticonsize="small" lockiconsize="true"
++             aria-label="&tabsToolbar.label;"
++             context="toolbar-context-menu"
++#ifdef APPMENU_ON_TABBAR
++             defaultset="appmenu-toolbar-button,tabbrowser-tabs,new-tab-
button,alltabs-button,tabs-closebutton"
++#else
++             defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabs-
closebutton"
++#endif
++             collapsed="true">
++
++#ifdef APPMENU_ON_TABBAR
++      <toolbarbutton id="appmenu-toolbar-button"
++                     class="chromeclass-toolbar-additional"
++                     type="menu"
++                     label="&brandShortName;"
++                     tooltiptext="&appMenuButton.tooltip;">
++#include browser-appmenu.inc
++      </toolbarbutton>
++#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" fadein="true"/>
++      </tabs>
++
++      <toolbarbutton id="new-tab-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     label="&tabCmd.label;"
++                     command="cmd_newNavigatorTab"
++                     onclick="checkForMiddleClick(this, event);"
++                     tooltiptext="&newTabButton.tooltip;"
++                     ondrop="newTabButtonObserver.onDrop(event)"
++                     ondragover="newTabButtonObserver.onDragOver(event)"
++                     ondragenter="newTabButtonObserver.onDragOver(event)"
++                     ondragexit="newTabButtonObserver.onDragExit(event)"
++                     removable="true"/>
++
++      <toolbarbutton id="alltabs-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional 
tabs-alltabs-button"
++                     type="menu"
++                     label="&listAllTabs.label;"
++                     tooltiptext="&listAllTabs.label;"
++                     removable="true">
++        <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"/>
++          <menuseparator id="alltabs-popup-separator"/>
++        </menupopup>
++      </toolbarbutton>
++
++      <toolbarbutton id="tabs-closebutton"
++                     class="close-button tabs-closebutton"
++                     command="cmd_close"
++                     label="&closeTab.label;"
++                     tooltiptext="&closeTab.label;"/>
++
++#ifdef CAN_DRAW_IN_TITLEBAR
++      <hbox class="titlebar-placeholder" type="appmenu-button" ordinal="0"/>
++      <hbox class="titlebar-placeholder" type="caption-buttons" 
ordinal="1000"/>
++#endif
++    </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"
++                     label="&printButton.label;" command="cmd_print"
++                     tooltiptext="&printButton.tooltip;"/>
++
++      <!-- 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"
++                     oncommand="DownloadsIndicatorView.onCommand(event);"
++                     ondrop="DownloadsIndicatorView.onDrop(event);"
++                     ondragover="DownloadsIndicatorView.onDragOver(event);"
++                     ondragenter="DownloadsIndicatorView.onDragOver(event);"
++                     label="&downloads.label;"
++                     tooltiptext="&downloads.tooltip;"/>
++
++      <toolbarbutton id="history-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     observes="viewHistorySidebar" 
label="&historyButton.label;"
++                     tooltiptext="&historyButton.tooltip;"/>
++
++      <toolbarbutton id="bookmarks-button" class="toolbarbutton-1 
chromeclass-toolbar-additional"
++                     observes="viewBookmarksSidebar"
++                     tooltiptext="&bookmarksButton.tooltip;"
++                     ondrop="bookmarksButtonObserver.onDrop(event)"
++                     ondragover="bookmarksButtonObserver.onDragOver(event)"
++                     ondragenter="bookmarksButtonObserver.onDragOver(event)"
++                     
ondragexit="bookmarksButtonObserver.onDragExit(event)"/>
++
++      <toolbarbutton id="new-window-button" class="toolbarbutton-1 
chromeclass-toolbar-additional"
++                     label="&newNavigatorCmd.label;"
++                     command="key_newNavigator"
++                     tooltiptext="&newWindowButton.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;"
++                     tooltiptext="&fullScreenButton.tooltip;"/>
++
++      <toolbaritem id="zoom-controls" class="chromeclass-toolbar-additional"
++                   title="&zoomControls.label;">
++        <toolbarbutton id="zoom-out-button" class="toolbarbutton-1"
++                       label="&fullZoomReduceCmd.label;"
++                       command="cmd_fullZoomReduce"
++                       tooltiptext="&zoomOutButton.tooltip;"/>
++        <toolbarbutton id="zoom-in-button" class="toolbarbutton-1"
++                       label="&fullZoomEnlargeCmd.label;"
++                       command="cmd_fullZoomEnlarge"
++                       tooltiptext="&zoomInButton.tooltip;"/>
++      </toolbaritem>
++
++      <toolbarbutton id="feed-button"
++                     type="menu"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     disabled="true"
++                     label="&feedButton.label;"
++                     tooltiptext="&feedButton.tooltip;"
++                     onclick="return FeedHandler.onFeedButtonClick(event);">
++        <menupopup position="after_end"
++                   id="feed-menu"
++                   onpopupshowing="return FeedHandler.buildFeedList(this);"
++                   oncommand="return FeedHandler.subscribeToFeed(null, 
event);"
++                   onclick="checkForMiddleClick(this, event);"/>
++      </toolbarbutton>
++
++      <toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&cutCmd.label;"
++                     command="cmd_cut"
++                     tooltiptext="&cutButton.tooltip;"/>
++
++      <toolbarbutton id="copy-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&copyCmd.label;"
++                     command="cmd_copy"
++                     tooltiptext="&copyButton.tooltip;"/>
++
++      <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&pasteCmd.label;"
++                     command="cmd_paste"
++                     tooltiptext="&pasteButton.tooltip;"/>
++
++#ifdef MOZ_SERVICES_SYNC
++      <toolbarbutton id="sync-button"
++                     class="toolbarbutton-1 chromeclass-toolbar-additional"
++                     label="&syncToolbarButton.label;"
++                     oncommand="gSyncUI.handleToolbarButton()"/>
++#endif
++
++      <toolbaritem id="navigator-throbber" title="&throbberItem.title;" 
align="center" pack="center"
++                   mousethrough="always">
++        <image/>
++      </toolbaritem>
++
++      <toolbarbutton id="tabview-button" class="toolbarbutton-1 chromeclass-
toolbar-additional"
++                     label="&tabGroupsButton.label;"
++                     command="Browser:ToggleTabView"
++                     tooltiptext="&tabGroupsButton.tooltip;"
++                     observes="tabviewGroupsNumber"/>
++    </toolbarpalette>
++  </toolbox>
++
++  <hbox id="fullscr-toggler" collapsed="true"/>
++
++  <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="tabs-closebutton" 
tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
++      </sidebarheader>
++      <browser id="sidebar" flex="1" autoscroll="false" 
disablehistory="true"
++                style="min-width: 14em; width: 18em; max-width: 36em;"/>
++    </vbox>
++
++    <splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-
splitter" hidden="true"/>
++    <vbox id="appcontent" flex="1">
++      <tabbrowser id="content"
++                  flex="1" contenttooltip="aHTMLTooltip"
++                  tabcontainer="tabbrowser-tabs"
++                  contentcontextmenu="contentAreaContextMenu"
++                  autocompletepopup="PopupAutoComplete"
++                  selectpopup="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">
++      <browser id="social-sidebar-browser"
++               type="content"
++               context="contentAreaContextMenu"
++               disableglobalhistory="true"
++               tooltip="aHTMLTooltip"
++               popupnotificationanchor="social-notification-icon"
++               flex="1"
++               style="min-width: 14em; width: 18em; max-width: 36em;"/>
++    </vbox>
++    <vbox id="browser-border-end" hidden="true" layer="true"/>
++  </hbox>
++
++  <hbox id="full-screen-warning-container" hidden="true" fadeout="true">
++    <hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to 
bug 579776. -->
++      <vbox id="full-screen-warning-message" align="center">
++        <description id="full-screen-domain-text"/>
++        <description class="full-screen-description" 
value="&fullscreenExitHint2.value;"/>
++        <vbox id="full-screen-approval-pane" align="center">
++          <hbox>
++#ifndef XP_UNIX
++            <button label="&fullscreenExitButton.label;"
++                    oncommand="FullScreen.setFullscreenAllowed(false);"
++                    class="full-screen-approval-button"/>
++            <button label="&fullscreenAllowButton.label;"
++                    oncommand="FullScreen.setFullscreenAllowed(true);"
++                    class="full-screen-approval-button"/>
++#else
++            <button label="&fullscreenAllowButton.label;"
++                    oncommand="FullScreen.setFullscreenAllowed(true);"
++                    class="full-screen-approval-button"/>
++            <button label="&fullscreenExitButton.label;"
++                    oncommand="FullScreen.setFullscreenAllowed(false);"
++                    class="full-screen-approval-button"/>
++#endif
++          </hbox>
++          <checkbox id="full-screen-remember-decision"/>
++        </vbox>
++      </vbox>
++    </hbox>
++  </hbox>
++
++  <vbox id="browser-bottombox" layer="true">
++    <notificationbox id="global-notificationbox"/>
++    <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>
++
++    <toolbar id="addon-bar"
++             toolbarname="&addonBarCmd.label;" 
accesskey="&addonBarCmd.accesskey;"
++             collapsed="true"
++             class="toolbar-primary chromeclass-toolbar"
++             context="toolbar-context-menu" toolboxid="navigator-toolbox"
++             mode="icons" iconsize="small" defaulticonsize="small"
++             lockiconsize="true"
++             defaultset="addonbar-closebutton,spring,status-bar"
++             customizable="true"
++             key="key_toggleAddonBar">
++      <toolbarbutton id="addonbar-closebutton"
++                     tooltiptext="&addonBarCloseButton.tooltip;"
++                     oncommand="setToolbarVisibility(this.parentNode, 
false);"/>
++      <statusbar id="status-bar" ordinal="1000"/>
++    </toolbar>
++  </vbox>
++
++#ifndef XP_UNIX
++  <svg:svg height="0">
++    <svg:clipPath id="windows-keyhole-forward-clip-path" 
clipPathUnits="objectBoundingBox">
++      <svg:path d="M 0,0 C 0.16,0.11 0.28,0.29 0.28,0.5 0.28,0.71 0.16,0.89 
0,1 L 1,1 1,0 0,0 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="windows-urlbar-back-button-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="M 0,0 0,7.8 C 2.5,11 4,14 4,18 4,22 2.5,25 0,28 l 0,22 
10000,0 0,-50 L 0,0 z"/>
++    </svg:clipPath>
++  </svg:svg>
++#endif
++#ifdef XP_MACOSX
++  <svg:svg height="0">
++    <svg:clipPath id="osx-keyhole-forward-clip-path" 
clipPathUnits="objectBoundingBox">
++      <svg:path d="M 0,0 C 0.15,0.12 0.25,0.3 0.25,0.5 0.25,0.7 0.15,0.88 
0,1 L 1,1 1,0 0,0 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="osx-urlbar-back-button-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="m 0,-5 0,4.03 C 3.6,1.8 6,6.1 6,11 6,16 3.6,20 0,23 l 
0,27 10000,0 0,-55 L 0,-5 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="osx-tab-ontop-left-curve-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="M 9,0 C 7.3,0 6,1.3 6,3 l 0,14 c 0,3 -2.2,5 -5,5 l -1,0 
0,1 12,0 0,-1 0,-19 0,-3 -3,0 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="osx-tab-ontop-right-curve-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="m 0,0 0,3 0,19 0,1 12,0 0,-1 -1,0 C 8.2,22 6,20 6,17 L 
6,3 C 6,1.3 4.7,0 3,0 L 0,0 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="osx-tab-onbottom-left-curve-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="m 0,0 0,1 1,0 c 2.8,0 5,2.2 5,5 l 0,14 c 0,2 1.3,3 3,3 l 
3,0 0,-3 L 12,1 12,0 0,0 z"/>
++    </svg:clipPath>
++    <svg:clipPath id="osx-tab-onbottom-right-curve-clip-path" 
clipPathUnits="userSpaceOnUse">
++      <svg:path d="m 0,0 0,1 0,19 0,3 3,0 c 1.7,0 3,-1 3,-3 L 6,6 C 6,3.2 
8.2,1 11,1 L 12,1 12,0 0,0 z"/>
++    </svg:clipPath>
++  </svg:svg>
++#endif
++
++</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
+@@ -53,16 +53,18 @@ browser.jar:
+ #endif
+         content/browser/aboutRobots-icon.png          (content/aboutRobots-
icon.png)
+         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-
widget-left.png)
+         content/browser/aboutSocialError.xhtml        
(content/aboutSocialError.xhtml)
+         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/content.js                    (content/content.js)
+         content/browser/newtab/newTab.xul             
(content/newtab/newTab.xul)
+ *       content/browser/newtab/newTab.js              
(content/newtab/newTab.js)
+         content/browser/newtab/newTab.css             
(content/newtab/newTab.css)
+         content/browser/newtab/preloaderContent.js    
(content/newtab/preloaderContent.js)
+ *       content/browser/pageinfo/pageInfo.xul         
(content/pageinfo/pageInfo.xul)
+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"
+ #endif
+ 
+ #include "rdf.h"
+ #include "nsFeedSniffer.h"
+@@ -31,18 +31,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)
+ #endif
+ 
+ NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
+ 
+@@ -60,17 +58,17 @@ NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUME
+ 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 },
+ #elif defined(XP_MACOSX)
+     { &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor },
+ #endif
+diff --git a/browser/components/preferences/advanced.js 
b/browser/components/preferences/advanced.js
+--- a/browser/components/preferences/advanced.js
++++ b/browser/components/preferences/advanced.js
+@@ -24,16 +24,22 @@ var gAdvancedPane = {
+     if (extraArgs && extraArgs["advancedTab"]){
+       advancedPrefs.selectedTab = 
document.getElementById(extraArgs["advancedTab"]);
+     } else {
+       var preference = 
document.getElementById("browser.preferences.advanced.selectedTabIndex");
+       if (preference.value !== null)
+         advancedPrefs.selectedIndex = preference.value;
+     }
+ 
++    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.
+@@ -903,14 +909,25 @@ var gAdvancedPane = {
+    * Set browser as the operating system default browser.
+    */
+   setDefaultBrowser: function()
+   {
+     let shellSvc = getShellService();
+     if (!shellSvc)
+       return;
+     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", "abrowser"];
++      process.run(false, args, args.length);
++    }
+     let selectedIndex =
+       shellSvc.isDefaultBrowser(false, true) ? 1 : 0;
+     document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
+   }
+ #endif
+ };
+diff --git a/browser/components/shell/src/Makefile.in 
b/browser/components/shell/src/Makefile.in
+--- a/browser/components/shell/src/Makefile.in
++++ b/browser/components/shell/src/Makefile.in
+@@ -2,10 +2,12 @@
+ # 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 $(topsrcdir)/config/rules.mk
+ 
+ CXXFLAGS += $(TK_CFLAGS)
+ 
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
++
+ clobber::
+ 	rm -f $(DIST)/lib/$(LIBRARY_NAME).lib
+diff --git a/browser/components/shell/src/moz.build 
b/browser/components/shell/src/moz.build
+--- a/browser/components/shell/src/moz.build
++++ b/browser/components/shell/src/moz.build
+@@ -10,16 +10,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/src/nsKDEShellService.cpp 
b/browser/components/shell/src/nsKDEShellService.cpp
+new file mode 100644
+--- /dev/null
++++ b/browser/components/shell/src/nsKDEShellService.cpp
+@@ -0,0 +1,234 @@
++/* -*- 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 "nsKDEShellService.h"
++#include "nsShellService.h"
++#include "nsKDEUtils.h"
++#include "nsCOMPtr.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"
++
++nsresult
++nsKDEShellService::Init()
++    {
++    if( !nsKDEUtils::kdeSupport())
++        return NS_ERROR_NOT_AVAILABLE;
++    return NS_OK;
++    }
++
++NS_IMPL_ISUPPORTS1(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::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;
++  }
++
++  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/src/nsKDEShellService.h 
b/browser/components/shell/src/nsKDEShellService.h
+new file mode 100644
+--- /dev/null
++++ b/browser/components/shell/src/nsKDEShellService.h
+@@ -0,0 +1,59 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
*/
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License 
Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" 
basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is Shell Service.
++ *
++ * The Initial Developer of the Original Code is mozilla.org.
++ * Portions created by the Initial Developer are Copyright (C) 2004
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable 
instead
++ * of those above. If you wish to allow use of your version of this file 
only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the 
notice
++ * and other provisions required by the GPL or the LGPL. If you do not 
delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef nskdeshellservice_h____
++#define nskdeshellservice_h____
++
++#include "nsIShellService.h"
++#include "nsStringAPI.h"
++
++class nsKDEShellService : public nsIShellService
++{
++public:
++  nsKDEShellService() : mCheckedThisSession(PR_FALSE) { }
++
++  NS_DECL_ISUPPORTS
++  NS_DECL_NSISHELLSERVICE
++
++  nsresult Init() NS_HIDDEN;
++
++private:
++  ~nsKDEShellService() {}
++
++  PRPackedBool mCheckedThisSession;
++};
++
++#endif // nskdeshellservice_h____
+diff --git a/browser/components/shell/src/nsUnixShellService.cpp 
b/browser/components/shell/src/nsUnixShellService.cpp
+new file mode 100644
+--- /dev/null
++++ b/browser/components/shell/src/nsUnixShellService.cpp
+@@ -0,0 +1,52 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
*/
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License 
Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" 
basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is Shell Service.
++ *
++ * The Initial Developer of the Original Code is mozilla.org.
++ * Portions created by the Initial Developer are Copyright (C) 2004
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable 
instead
++ * of those above. If you wish to allow use of your version of this file 
only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the 
notice
++ * and other provisions required by the GPL or the LGPL. If you do not 
delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "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/src/nsUnixShellService.h 
b/browser/components/shell/src/nsUnixShellService.h
+new file mode 100644
+--- /dev/null
++++ b/browser/components/shell/src/nsUnixShellService.h
+@@ -0,0 +1,45 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
*/
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License 
Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" 
basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is Shell Service.
++ *
++ * The Initial Developer of the Original Code is mozilla.org.
++ * Portions created by the Initial Developer are Copyright (C) 2004
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable 
instead
++ * of those above. If you wish to allow use of your version of this file 
only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the 
notice
++ * and other provisions required by the GPL or the LGPL. If you do not 
delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#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
+@@ -640,19 +640,21 @@
+ @BINPATH@/defaults/autoconfig/prefcalls.js
+ @BINPATH@/browser/defaults/profile/prefs.js
+ 
+ #ifndef LIBXUL_SDK
+ ; 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.
+ @BINPATH@/defaults/pref/channel-prefs.js
++ at BINPATH@/defaults/pref/kde.js
+ #else
+ ; For Fx-on-xr, channel-prefs lives with the app preferences. (Bug 762588)
+ @BINPATH@/@PREF_DIR@/channel-prefs.js
++ at BINPATH@/@PREF_DIR@/kde.js
+ #endif
+ 
+ ; Services (gre) prefs
+ #ifdef MOZ_SERVICES_NOTIFICATIONS
+ @BINPATH@/defaults/pref/services-notifications.js
+ #endif
+ #ifdef MOZ_SERVICES_SYNC
+ @BINPATH@/defaults/pref/services-sync.js
diff --git a/helpers/DATA/firefox/mozilla-kde.patch 
b/helpers/DATA/firefox/mozilla-kde.patch
new file mode 100644
index 0000000..01959d0
--- /dev/null
+++ b/helpers/DATA/firefox/mozilla-kde.patch
@@ -0,0 +1,3707 @@
+Description: Add KDE integration to Abrowser (toolkit parts)
+Author: Wolfgang Rosenauer <wolfgang at rosenauer.org>
+Author: Lubos Lunak <lunak at 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/src/Makefile.in 
b/modules/libpref/src/Makefile.in
+--- a/modules/libpref/src/Makefile.in
++++ b/modules/libpref/src/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) 
$(XULPPFLAGS) $^ -o $@)
+ 
+ libs:: greprefs.js
+ 	$(INSTALL) $^ $(DIST)/bin/
+diff --git a/modules/libpref/src/Preferences.cpp 
b/modules/libpref/src/Preferences.cpp
+--- a/modules/libpref/src/Preferences.cpp
++++ b/modules/libpref/src/Preferences.cpp
+@@ -27,16 +27,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 "pldhash.h"
+ 
+ #include "prefapi.h"
+ #include "prefread.h"
+ #include "prefapi_private_data.h"
+ 
+@@ -1115,16 +1116,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 < NS_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;
+@@ -1140,17 +1159,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).Equals(NS_LITERAL_CSTRING(".xpi")))
+       ReadExtensionPrefs(path);
+     else
+-      pref_LoadPrefsInDir(path, nullptr, 0);
++      pref_LoadPrefsInDir(path, specialFiles, 
NS_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);
+@@ -1244,28 +1263,40 @@ 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_OS2)
+     "os2pref.js"
+ #elif defined(XP_BEOS)
+     "beos.js"
+ #endif
+   };
+ 
++  if(nsKDEUtils::kdeSession()) { // TODO what if some setup actually 
requires the helper?
++    for(int i = 0;
++        i < NS_ARRAY_LENGTH(specialFiles);
++        ++i ) {
++      if( *specialFiles[ i ] == '\0' ) {
++        specialFiles[ i ] = "kde.js";
++        break;
++      }
++    }
++  }
++
+   rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, 
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.
+   nsRefPtr<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
+@@ -208,16 +208,17 @@ class Flags(OrderedDict):
+         'platformversion': VersionFlag,
+         'contentaccessible': Flag,
+         'os': StringFlag,
+         'osversion': VersionFlag,
+         'abi': StringFlag,
+         'platform': Flag,
+         'xpcnativewrappers': Flag,
+         'tablet': Flag,
++	'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
+@@ -30,16 +30,17 @@ class ManifestEntry(object):
+     allowed_flags = [
+         'application',
+         'platformversion',
+         'os',
+         'osversion',
+         'abi',
+         'xpcnativewrappers',
+         'tablet',
++	'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/Makefile.in 
b/toolkit/components/downloads/Makefile.in
+--- a/toolkit/components/downloads/Makefile.in
++++ b/toolkit/components/downloads/Makefile.in
+@@ -4,9 +4,10 @@
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+ include $(topsrcdir)/config/rules.mk
+ 
+ CXXFLAGS += $(TK_CFLAGS) -DGOOGLE_PROTOBUF_NO_RTTI
+ 
+ LOCAL_INCLUDES += \
+   -I$(srcdir)/../protobuf \
++  -I$(topsrcdir)/toolkit/xre \
+   $(NULL)
+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
+@@ -41,16 +41,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"
+ using namespace mozilla::widget::android;
+ #endif
+@@ -2687,16 +2691,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;
+ 
+@@ -2724,19 +2737,20 @@ nsDownload::SetState(DownloadState aStat
+               // because if it is, they'll click open the download manager 
and
+               // the items they downloaded will have been removed.
+               alerts->ShowAlertNotification(
+                   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(), nullptr);
+-            }
++          }
+         }
+       }
++      }
+ 
+ #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
+@@ -53,29 +53,33 @@ toolkit.jar:
+    content/global/viewZoomOverlay.js          (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,451 @@
++<?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
++                pack="end">
++	<xul:button dlgtype="help" class="dialog-button" hidden="true"/>
++	<xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++	<xul:spacer anonid="spacer" flex="1" hidden="true"/>
++	<xul:button dlgtype="accept" class="dialog-button" 
xbl:inherits="disabled=buttondisabledaccept"/>
++	<xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
++	<xul:button dlgtype="cancel" class="dialog-button"/>
++	<xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
++#else
++                pack="end">
++        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++        <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();
++          }
++
++          var xOffset = (opener.outerWidth - window.outerWidth) / 2;
++          var yOffset = opener.outerHeight / 5;
++
++          var newX = opener.screenX + xOffset;
++          var newY = opener.screenY + yOffset;
++
++          // 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")
++                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_ENTER"
++               group="system" action="this._hitEnter(event);"/>
++      <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,1332 @@
++<?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="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[
++        // 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. 
++        if (this.preferences.type == "child" && 
++            !this.instantApply && window.opener) {
++          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];
++            }
++          }
++          this._setValue(preference ? preference.value 
++                                    : this.valueFromPreferences, false);
++        }
++        else
++          this._setValue(this.valueFromPreferences, false);
++      ]]>
++      </constructor>
++      <destructor>
++        this.preferences.rootBranchInternal
++            .removeObserver(this.name, this.preferences);
++      </destructor>
++      
++      <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"/>
++        <parameter name="aUpdate"/>
++        <body>
++        <![CDATA[
++          if (aUpdate && this.value !== aValue) {
++            this._value = aValue;
++            if (this.instantApply)
++              this.valueFromPreferences = aValue;
++            this.preferences.fireChangedEvent(this);
++          }
++          else if (!aUpdate) {
++            this._value = aValue;
++            this.updateElements();
++          }
++          return aValue;
++        ]]>
++        </body>
++      </method>
++      <property name="value" onget="return this._value" onset="return 
this._setValue(val, true);"/>
++      
++      <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"
++#ifdef XP_UNIX_GNOME
++                >
++        <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"/>
++#elif XP_UNIX
++	        pack="end">
++        <xul:button dlgtype="help" class="dialog-button" hidden="true" 
icon="help"/>
++        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++        <xul:spacer anonid="spacer" flex="1"/>
++        <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
++        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
++        <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
++        <xul:button dlgtype="disclosure" class="dialog-button" 
hidden="true"/>
++	
++#else
++                pack="end">
++        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++        <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") {
++          var 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;
++            // 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>
++
++      <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;
++        
++        if (this.type == "child" && window.opener) {
++          var psvc = Components.classes["@mozilla.org/preferences-
service;1"]
++                               
.getService(Components.interfaces.nsIPrefBranch);
++          var instantApply = 
psvc.getBoolPref("browser.preferences.instantApply");
++          if (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);
++        }
++      ]]>
++      </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.
++          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>
++      
++      <method name="userChangedValue">
++        <parameter name="aElement"/>
++        <body>
++        <![CDATA[
++          var element = this.getPreferenceElement(aElement);
++          if (element.hasAttribute("preference")) {
++            var preference = 
document.getElementById(element.getAttribute("preference"));
++            var prefVal = preference.getElementValue(element);
++            preference.value = prefVal;
++          }
++        ]]>
++        </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
+@@ -14,16 +14,18 @@
+ #include "prenv.h"
+ #include "nsPrintfCString.h"
+ #include "nsNetUtil.h"
+ #include "nsISupportsPrimitives.h"
+ #include "nsIGSettingsService.h"
+ #include "nsInterfaceHashtable.h"
+ #include "mozilla/Attributes.h"
+ #include "nsIURI.h"
++#include "nsVoidArray.h"
++#include "nsKDEUtils.h"
+ 
+ class nsUnixSystemProxySettings MOZ_FINAL : public nsISystemProxySettings {
+ public:
+   NS_DECL_ISUPPORTS
+   NS_DECL_NSISYSTEMPROXYSETTINGS
+ 
+   nsUnixSystemProxySettings()
+     : mSchemeProxySettings(5)
+@@ -38,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_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
+ 
+ NS_IMETHODIMP
+ nsUnixSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly)
+ {
+   // dbus prevents us from being threadsafe, but this routine should not 
block anyhow
+@@ -504,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);
+ 
+@@ -539,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
+@@ -45,17 +45,19 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt
+         'nsNativeAppSupportQt.cpp',
+         'nsQAppInstance.cpp',
+     ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
+     SOURCES += [
+         'nsNativeAppSupportOS2.cpp',
+     ]
+ elif CONFIG['MOZ_ENABLE_GTK']:
++    EXPORTS += ['nsKDEUtils.h']
+     UNIFIED_SOURCES += [
++        'nsKDEUtils.cpp',
+         'nsNativeAppSupportUnix.cpp',
+     ]
+ else:
+     UNIFIED_SOURCES += [
+         'nsNativeAppSupportDefault.cpp',
+     ]
+ 
+ if CONFIG['MOZ_X11']:
+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, 
const GtkWindow* parent, nsTArray<nsCString>* output )
++    {
++    return self()->internalCommand( command, parent, true, output );
++    }
++
++bool nsKDEUtils::internalCommand( const nsTArray<nsCString>& command, 
const 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 && parent->group )
++            gtk_window_group_add_window( parent->group, GTK_WINDOW( window 
));
++        gtk_widget_realize( window );
++        gtk_widget_set_sensitive( window, TRUE );
++        gtk_grab_add( window );
++        GIOChannel* channel = g_io_channel_unix_new( fileno( data.file ));
++        g_io_add_watch( channel, static_cast< GIOCondition >( G_IO_IN | 
G_IO_ERR | G_IO_HUP ), kdeReadFunc, &data );
++        g_io_channel_unref( channel );
++        g_main_loop_run( data.loop );
++        g_main_loop_unref( data.loop );
++        gtk_grab_remove( window );
++        gtk_widget_destroy( window );
++        }
++    else
++        {
++        data.loop = NULL;
++        while( kdeReadFunc( NULL, static_cast< GIOCondition >( 0 ), &data ))
++            ;
++        }
++    return data.success;
++    }
++
++bool nsKDEUtils::startHelper()
++    {
++    if( helperRunning )
++        return true;
++    if( helperFailed )
++        return false;
++    helperFailed = true;
++    int fdcommand[ 2 ];
++    int fdreply[ 2 ];
++    if( pipe( fdcommand ) < 0 )
++        return false;
++    if( pipe( fdreply ) < 0 )
++        {
++        close( fdcommand[ 0 ] );
++        close( fdcommand[ 1 ] );
++        return false;
++        }
++    char* args[ 2 ] = { const_cast< char* >( KMOZILLAHELPER ), NULL };
++    switch( fork())
++        {
++        case -1:
++            {
++            close( fdcommand[ 0 ] );
++            close( fdcommand[ 1 ] );
++            close( fdreply[ 0 ] );
++            close( fdreply[ 1 ] );
++            return false;
++            }
++        case 0: // child
++            {
++            if( dup2( fdcommand[ 0 ], STDIN_FILENO ) < 0 )
++                _exit( 1 );
++            if( dup2( fdreply[ 1 ], STDOUT_FILENO ) < 0 )
++                _exit( 1 );
++            int maxfd = 1024; // close all other fds
++            struct rlimit rl;
++            if( getrlimit( RLIMIT_NOFILE, &rl ) == 0 )
++                maxfd = rl.rlim_max;
++            for( int i = 3;
++                 i < maxfd;
++                 ++i )
++                close( i );
++#ifdef DEBUG_KDE
++            execvp( KMOZILLAHELPER, args );
++#else
++            execv( KMOZILLAHELPER, args );
++#endif
++            _exit( 1 ); // failed
++            }
++        default: // parent
++            {
++            commandFile = fdopen( fdcommand[ 1 ], "w" );
++            replyFile = fdopen( fdreply[ 0 ], "r" );
++            close( fdcommand[ 0 ] );
++            close( fdreply[ 1 ] );
++            if( commandFile == NULL || replyFile == NULL )
++                {
++                closeHelper();
++                return false;
++                }
++            // ok, helper ready, getKdeRunning() will check if it works
++            }
++        }
++    helperFailed = false;
++    helperRunning = true;
++    return true;
++    }
++
++void nsKDEUtils::closeHelper()
++    {
++    if( commandFile != NULL )
++        fclose( commandFile ); // this will also make the helper quit
++    if( replyFile != NULL )
++        fclose( replyFile );
++    helperRunning = false;
++    }
++
++void nsKDEUtils::feedCommand( const 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 Abrowser). 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 Abrowser. 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, 
const 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, const 
GtkWindow* parent, bool isParent,
++            nsTArray<nsCString>* output );
++        FILE* commandFile;
++        FILE* replyFile;
++    };
++
++#endif // nsKDEUtils
+diff --git a/uriloader/exthandler/Makefile.in 
b/uriloader/exthandler/Makefile.in
+--- a/uriloader/exthandler/Makefile.in
++++ b/uriloader/exthandler/Makefile.in
+@@ -19,9 +19,10 @@ endif
+ ifdef MOZ_ENABLE_DBUS
+ LOCAL_INCLUDES   += $(TK_CFLAGS) $(MOZ_DBUS_CFLAGS)
+ endif
+ 
+ include $(topsrcdir)/config/rules.mk
+ 
+ ifneq (,$(filter qt gtk2 gtk3, $(MOZ_WIDGET_TOOLKIT)))
+ CXXFLAGS += $(TK_CFLAGS) $(MOZ_DBUS_GLIB_CFLAGS)
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+ endif
+diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build
+--- a/uriloader/exthandler/moz.build
++++ b/uriloader/exthandler/moz.build
+@@ -81,17 +81,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
+ else:
+     # These files can't be built in unified mode because they force NSPR 
logging.
+     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',
+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,54 @@
++/* -*- 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 "nsVoidArray.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,23 @@
++/* 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 "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);
++};
+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 ];
++        nsRefPtr<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,29 @@
++/* 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 "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);
++
++};
+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
+@@ -10,30 +10,33 @@
+ #include <QString>
+ #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 "nsIGnomeVFSService.h"
+ #include "nsAutoPtr.h"
+ #ifdef MOZ_ENABLE_DBUS
+ #include "nsDBusHandlerApp.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)) {
+     nsAutoCString spec;
+     aURI->GetAsciiSpec(spec);
+     if (QDesktopServices::openUrl(QUrl(spec.get()))) {
+       rv = NS_OK;
+     }
+@@ -48,22 +51,22 @@ nsMIMEInfoUnix::GetHasDefaultHandler(boo
+ {
+   // if mDefaultApplication is set, it means the application has been set 
from
+   // either /etc/mailcap or ${HOME}/.mailcap, in which case we don't want to
+   // give the GNOME answer.
+   if (mDefaultApplication)
+     return nsMIMEInfoImpl::GetHasDefaultHandler(_retval);
+ 
+   *_retval = false;
+-  nsRefPtr<nsMIMEInfoBase> mimeInfo = 
nsGNOMERegistry::GetFromType(mSchemeOrType);
++  nsRefPtr<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);
+   nsAutoCString uriSpec;
+   if (giovfs) {
+     // nsGIOMimeApp->Launch wants a URI string instead of local file
+     nsresult rv;
+     nsCOMPtr<nsIIOService> ioservice = 
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
+     NS_ENSURE_SUCCESS(rv, rv);
+     nsCOMPtr<nsIURI> uri;
+@@ -124,17 +144,17 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
+     /* Fallback to GnomeVFS */
+     nsCOMPtr<nsIGnomeVFSMimeApp> app;
+     if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(mSchemeOrType, 
getter_AddRefs(app))) && app)
+       return app->Launch(nativePath);
+   }
+ 
+   // If we haven't got an app we try to get a valid one by searching for the
+   // extension mapped type
+-  nsRefPtr<nsMIMEInfoBase> mimeInfo = 
nsGNOMERegistry::GetFromExtension(nativePath);
++  nsRefPtr<nsMIMEInfoBase> mimeInfo = 
nsCommonRegistry::GetFromExtension(nativePath);
+   if (mimeInfo) {
+     nsAutoCString type;
+     mimeInfo->GetType(type);
+     if (giovfs) {
+       nsCOMPtr<nsIGIOMimeApp> app;
+       if (NS_SUCCEEDED(giovfs->GetAppForMimeType(type, getter_AddRefs(app))) 
&& app)
+         return app->Launch(uriSpec);
+     } else if (gnomevfs) {
+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"
+@@ -1157,26 +1157,26 @@ nsresult nsOSHelperAppService::OSProtoco
+     ContentAction::Action::defaultActionForScheme(QString(aProtocolScheme) + 
':');
+ 
+   if (action.isValid())
+     *aHandlerExists = true;
+ #endif
+ 
+ #ifdef MOZ_WIDGET_GTK
+   // Check the GConf 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 PRUnichar * 
platformAppPath, nsIFile ** aFile)
+ {
+@@ -1263,17 +1263,17 @@ nsOSHelperAppService::GetFromExtension(c
+                                          mime_types_description,
+                                          true);
+ 
+   if (NS_FAILED(rv) || majorType.IsEmpty()) {
+     
+ #ifdef MOZ_WIDGET_GTK
+     LOG(("Looking in GNOME registry\n"));
+     nsRefPtr<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,
+@@ -1386,17 +1386,17 @@ nsOSHelperAppService::GetFromType(const 
+ #ifdef MOZ_WIDGET_GTK
+   nsRefPtr<nsMIMEInfoBase> gnomeInfo;
+   if (handler.IsEmpty()) {
+     // No useful data yet.  Check the GNOME registry.  Unfortunately, newer
+     // GNOME versions no longer have type-to-extension mappings, so we might
+     // get back a MIMEInfo without any extensions set.  In that case we'll 
have
+     // to look in our mime.types files for the extensions.    
+     LOG(("Looking in GNOME registry\n"));
+-    gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType);
++    gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType);
+     if (gnomeInfo && gnomeInfo->HasExtensions()) {
+       LOG(("Got MIMEInfo from GNOME registry, and it has extensions 
set\n"));
+       return gnomeInfo.forget();
+     }
+   }
+ #endif
+ 
+   // Now look up our extensions
+diff --git a/widget/gtk/Makefile.in b/widget/gtk/Makefile.in
+--- a/widget/gtk/Makefile.in
++++ b/widget/gtk/Makefile.in
+@@ -4,11 +4,13 @@
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+ include $(topsrcdir)/config/rules.mk
+ 
+ CFLAGS          += $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
+ CXXFLAGS        += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) \
+ 		               $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
+ 
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
++
+ CFLAGS          += $(TK_CFLAGS)
+ CXXFLAGS        += $(TK_CFLAGS)
+ 
+diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
+--- a/widget/gtk/nsFilePicker.cpp
++++ b/widget/gtk/nsFilePicker.cpp
+@@ -1,32 +1,34 @@
+ /* -*- 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/Types.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
+ 
+ nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr;
+ 
+ void
+@@ -226,17 +228,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);
+@@ -350,16 +354,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)
+@@ -538,8 +558,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
+@@ -66,11 +66,17 @@ protected:
+   nsString  mDefault;
+   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 );
+ };
+ 
+ #endif
+diff --git a/xpcom/components/Makefile.in b/xpcom/components/Makefile.in
+--- a/xpcom/components/Makefile.in
++++ b/xpcom/components/Makefile.in
+@@ -14,9 +14,10 @@ LOCAL_INCLUDES	= \
+ 	-I$(topsrcdir)/chrome/src \
+ 	-I$(topsrcdir)/modules/libjar \
+ 	$(NULL)
+ 
+ include $(topsrcdir)/config/rules.mk
+ 
+ ifdef MOZ_WIDGET_GTK
+ CXXFLAGS        += $(TK_CFLAGS)
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+ endif
+diff --git a/xpcom/components/ManifestParser.cpp 
b/xpcom/components/ManifestParser.cpp
+--- a/xpcom/components/ManifestParser.cpp
++++ b/xpcom/components/ManifestParser.cpp
+@@ -30,16 +30,17 @@
+ #include "nsTextFormatter.h"
+ #include "nsVersionComparator.h"
+ #include "nsXPCOMCIDInternal.h"
+ 
+ #include "nsIConsoleService.h"
+ #include "nsIScriptError.h"
+ #include "nsIXULAppInfo.h"
+ #include "nsIXULRuntime.h"
++#include "nsKDEUtils.h"
+ 
+ using namespace mozilla;
+ 
+ struct ManifestDirective
+ {
+   const char* directive;
+   int argc;
+ 
+@@ -397,16 +398,17 @@ ParseManifest(NSLocationType type, FileL
+   NS_NAMED_LITERAL_STRING(kPlatform, "platform");
+   NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
+   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");
+ #if defined(MOZ_WIDGET_ANDROID)
+   NS_NAMED_LITERAL_STRING(kTablet, "tablet");
+ #endif
+ 
+   // Obsolete
+   NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
+ 
+   nsAutoString appID;
+@@ -444,41 +446,46 @@ ParseManifest(NSLocationType type, FileL
+         CopyUTF8toUTF16(s, abi);
+         abi.Insert(PRUnichar('_'), 0);
+         abi.Insert(osTarget, 0);
+       }
+     }
+   }
+ 
+   nsAutoString osVersion;
++  nsAutoString desktop;
+ #if defined(XP_WIN)
+   OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
+   if (GetVersionEx(&info)) {
+     nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+                                          info.dwMajorVersion,
+                                          info.dwMinorVersion);
+   }
++  desktop = NS_LITERAL_STRING("win");
+ #elif defined(MOZ_WIDGET_COCOA)
+   SInt32 majorVersion, minorVersion;
+   if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
+       (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
+     nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+                                          majorVersion,
+                                          minorVersion);
+   }
++  desktop = NS_LITERAL_STRING("macosx");
+ #elif defined(MOZ_WIDGET_GTK)
+   nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+                                        gtk_major_version,
+                                        gtk_minor_version);
++  desktop = nsKDEUtils::kdeSession() ? NS_LITERAL_STRING("kde") : 
NS_LITERAL_STRING("gnome");
+ #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::android::GeckoAppShell::IsTablet();
+   }
++  desktop = NS_LITERAL_STRING("android");
+ #endif
+ 
+   // Because contracts must be registered after CIDs, we save and process 
them
+   // at the end.
+   nsTArray<CachedDirective> contracts;
+ 
+   char *token;
+   char *newline = buf;
+@@ -560,24 +567,26 @@ ParseManifest(NSLocationType type, FileL
+     TriState stOsVersion = eUnspecified;
+     TriState stOs = eUnspecified;
+     TriState stABI = eUnspecified;
+ #if defined(MOZ_WIDGET_ANDROID)
+     TriState stTablet = eUnspecified;
+ #endif
+     bool platform = false;
+     bool contentAccessible = false;
++    TriState stDesktop = eUnspecified;
+ 
+     while (nullptr != (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) ||
+           CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
+           CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
+           CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, 
stGeckoVersion))
+         continue;
+ 
+ #if defined(MOZ_WIDGET_ANDROID)
+       bool tablet = false;
+       if (CheckFlag(kTablet, wtoken, tablet)) {
+@@ -606,16 +615,17 @@ ParseManifest(NSLocationType type, FileL
+     }
+ 
+     if (!ok ||
+         stApp == eBad ||
+         stAppVersion == eBad ||
+         stGeckoVersion == eBad ||
+         stOs == eBad ||
+         stOsVersion == eBad ||
++        stDesktop == eBad ||
+ #ifdef MOZ_WIDGET_ANDROID
+         stTablet == eBad ||
+ #endif
+         stABI == eBad)
+       continue;
+ 
+     if (directive->regfunc) {
+       if (GeckoProcessType_Default != XRE_GetProcessType())
+diff --git a/xpcom/io/Makefile.in b/xpcom/io/Makefile.in
+--- a/xpcom/io/Makefile.in
++++ b/xpcom/io/Makefile.in
+@@ -1,8 +1,8 @@
+ # 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/.
+ 
+ MOZILLA_INTERNAL_API = 1
+ include $(topsrcdir)/config/rules.mk
+ 
+-LOCAL_INCLUDES	+= -I..
++LOCAL_INCLUDES	+= -I.. -I$(topsrcdir)/toolkit/xre
+diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp
+--- a/xpcom/io/nsLocalFileUnix.cpp
++++ b/xpcom/io/nsLocalFileUnix.cpp
+@@ -43,16 +43,17 @@
+ #include "nsIDirectoryEnumerator.h"
+ #include "nsISimpleEnumerator.h"
+ #include "private/pprio.h"
+ #include "prlink.h"
+ 
+ #ifdef MOZ_WIDGET_GTK
+ #include "nsIGIOService.h"
+ #include "nsIGnomeVFSService.h"
++#include "nsKDEUtils.h"
+ #endif
+ 
+ #ifdef MOZ_WIDGET_COCOA
+ #include <Carbon/Carbon.h>
+ #include "CocoaFileUtils.h"
+ #include "prmem.h"
+ #include "plbase64.h"
+ 
+@@ -1811,46 +1812,52 @@ nsLocalFile::SetPersistentDescriptor(con
+     return InitWithNativePath(aPersistentDescriptor);
+ #endif
+ }
+ 
+ NS_IMETHODIMP
+ nsLocalFile::Reveal()
+ {
+ #ifdef MOZ_WIDGET_GTK
+-    nsCOMPtr<nsIGIOService> giovfs = 
do_GetService(NS_GIOSERVICE_CONTRACTID);
+-    nsCOMPtr<nsIGnomeVFSService> gnomevfs = 
do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+-    if (!giovfs && !gnomevfs)
+-        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) {
+-        if (giovfs)
+-            return giovfs->ShowURIForInput(mPath);
+-        else 
+-            /* Fallback to GnomeVFS */
+-            return gnomevfs->ShowURIForInput(mPath);
++        url = mPath;
+     } else if (giovfs && 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;
+ 
+-        if (giovfs)
+-            return giovfs->ShowURIForInput(dirPath);
+-        else 
+-            return gnomevfs->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;
++    }
++
++    nsCOMPtr<nsIGnomeVFSService> gnomevfs = 
do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
++    if (!giovfs && !gnomevfs)
++      return NS_ERROR_FAILURE;
++
++    if (giovfs)
++      return giovfs->ShowURIForInput(url);
++    else
++      return gnomevfs->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;
+@@ -1858,16 +1865,23 @@ 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);
+     nsCOMPtr<nsIGnomeVFSService> gnomevfs = 
do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+     if (giovfs) {
+       return giovfs->ShowURIForInput(mPath);
+     } else if (gnomevfs) {
+       /* GnomeVFS fallback */
+       return gnomevfs->ShowURIForInput(mPath);
+     }
diff --git a/helpers/make-firefox b/helpers/make-firefox
index 5dab04b..ccb7151 100644
--- a/helpers/make-firefox
+++ b/helpers/make-firefox
@@ -17,7 +17,7 @@
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 
USA
 #
 
-VERSION=12
+VERSION=13
 
 . ./config
 
@@ -30,6 +30,18 @@ cat $DATA/settings.js >> debian/vendor-firefox.js
 #sed 's/Depends: lsb-release,/Depends: lsb-release, xul-ext-ubufox,/' -i 
debian/control.in
 #sed 's/iceweasel,/iceweasel, firefox, icecat,/' -i debian/control.in
 
+# KDE support
+cp $DATA/mozilla-kde.patch debian/patches/mozilla-kde.patch
+cp $DATA/abrowser-kde.patch debian/patches/abrowser-kde.patch
+cat << EOF >> debian/patches/series
+mozilla-kde.patch
+abrowser-kde.patch
+EOF
+cat << EOF >> debian/kde.js
+pref("browser.preferences.instantApply", false);
+EOF
+LINENUM=$(grep -n '# Prefs' abrowser.install.in | cut -d: -f1)
+sed -i ${LINENUM}'a debian/kde.js @MOZ_LIBDIR@/defaults/pref' 
abrowser.install.in
 
 sed '/mozilla.org\/legal/d' -i services/healthreport/healthreport-prefs.js
 cat << EOF >>services/healthreport/healthreport-prefs.js
-- 
1.7.9.5




More information about the Trisquel-devel mailing list