1
0
MozillaThunderbird/mozilla-kde.patch

2040 lines
72 KiB
Diff
Raw Normal View History

# HG changeset patch
# Parent d7a4d772ba2afb3ac43e2f2f234ffa55bcf50e70
Description: Add KDE integration to Firefox (toolkit parts)
Author: Wolfgang Rosenauer <wolfgang@rosenauer.org>
Author: Lubos Lunak <lunak@suse.com>
Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751
https://bugzilla.novell.com/show_bug.cgi?id=170055
Index: firefox-60.2.0/modules/libpref/Preferences.cpp
===================================================================
--- firefox-60.2.0.orig/modules/libpref/Preferences.cpp 2018-09-05 21:49:23.102829401 +0200
+++ firefox-60.2.0/modules/libpref/Preferences.cpp 2018-09-05 21:49:31.498872824 +0200
@@ -81,6 +81,7 @@
#include "PLDHashTable.h"
#include "plstr.h"
#include "prlink.h"
+#include "nsKDEUtils.h"
#ifdef XP_WIN
#include "windows.h"
@@ -3873,6 +3874,7 @@ Preferences::InitInitialObjects()
"winpref.js"
#elif defined(XP_UNIX)
"unix.js"
+ , "" // placeholder for KDE (empty is otherwise harmless)
#if defined(_AIX)
,
"aix.js"
@@ -3882,6 +3884,17 @@ Preferences::InitInitialObjects()
#endif
};
+ if(nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires the helper?
+ for(int i = 0;
+ i < MOZ_ARRAY_LENGTH(specialFiles);
+ ++i ) {
+ if( *specialFiles[ i ] == '\0' ) {
+ specialFiles[ i ] = "kde.js";
+ break;
+ }
+ }
+ }
+
rv = pref_LoadPrefsInDir(
defaultPrefDir, specialFiles, ArrayLength(specialFiles));
if (NS_FAILED(rv)) {
@@ -3940,7 +3953,7 @@ Preferences::InitInitialObjects()
}
// Do we care if a file provided by this process fails to load?
- pref_LoadPrefsInDir(path, nullptr, 0);
+ pref_LoadPrefsInDir(path, specialFiles, ArrayLength(specialFiles));
}
}
Index: firefox-60.2.0/modules/libpref/moz.build
===================================================================
--- firefox-60.2.0.orig/modules/libpref/moz.build 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/modules/libpref/moz.build 2018-09-05 21:49:31.498872824 +0200
@@ -32,6 +32,10 @@ UNIFIED_SOURCES += [
'Preferences.cpp',
]
+LOCAL_INCLUDES += [
+ '/toolkit/xre'
+]
+
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
Index: firefox-60.2.0/python/mozbuild/mozpack/chrome/flags.py
===================================================================
--- firefox-60.2.0.orig/python/mozbuild/mozpack/chrome/flags.py 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/python/mozbuild/mozpack/chrome/flags.py 2018-09-05 21:49:31.498872824 +0200
@@ -225,6 +225,7 @@ class Flags(OrderedDict):
'xpcnativewrappers': Flag,
'tablet': Flag,
'process': StringFlag,
+ 'desktop': StringFlag,
}
RE = re.compile(r'([!<>=]+)')
Index: firefox-60.2.0/python/mozbuild/mozpack/chrome/manifest.py
===================================================================
--- firefox-60.2.0.orig/python/mozbuild/mozpack/chrome/manifest.py 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/python/mozbuild/mozpack/chrome/manifest.py 2018-09-05 21:49:31.498872824 +0200
@@ -39,6 +39,7 @@ class ManifestEntry(object):
'tablet',
'process',
'contentaccessible',
+ 'desktop',
]
def __init__(self, base, *flags):
Index: firefox-60.2.0/toolkit/components/downloads/moz.build
===================================================================
--- firefox-60.2.0.orig/toolkit/components/downloads/moz.build 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/toolkit/components/downloads/moz.build 2018-09-05 21:49:31.498872824 +0200
@@ -46,5 +46,9 @@ if CONFIG['MOZ_PLACES']:
FINAL_LIBRARY = 'xul'
+LOCAL_INCLUDES += [
+ '/toolkit/xre'
+]
+
with Files('**'):
BUG_COMPONENT = ('Toolkit', 'Download Manager')
Index: firefox-60.2.0/toolkit/content/jar.mn
===================================================================
--- firefox-60.2.0.orig/toolkit/content/jar.mn 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/toolkit/content/jar.mn 2018-09-05 21:49:31.498872824 +0200
@@ -74,6 +74,8 @@ toolkit.jar:
content/global/bindings/datetimebox.xml (widgets/datetimebox.xml)
content/global/bindings/datetimebox.css (widgets/datetimebox.css)
* 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/filefield.xml (widgets/filefield.xml)
* content/global/bindings/findbar.xml (widgets/findbar.xml)
Index: firefox-60.2.0/toolkit/content/widgets/dialog-kde.xml
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/toolkit/content/widgets/dialog-kde.xml 2018-09-05 21:49:31.498872824 +0200
@@ -0,0 +1,478 @@
+<?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/. -->
+
+<!DOCTYPE bindings [
+ <!ENTITY % globalKeysDTD SYSTEM "chrome://global/locale/globalKeys.dtd">
+ %globalKeysDTD;
+]>
+
+<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">
+ <resources>
+ <stylesheet src="chrome://global/skin/dialog.css"/>
+ </resources>
+ <content>
+ <xul:vbox class="box-inherit dialog-content-box" flex="1">
+ <children/>
+ </xul:vbox>
+
+ <xul:hbox class="dialog-button-box" anonid="buttons"
+ xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
+#ifdef XP_UNIX_GNOME
+ >
+ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
+ <xul:spacer anonid="spacer" flex="1"/>
+ <xul:button dlgtype="cancel" class="dialog-button"/>
+ <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
+#elif XP_UNIX
+ >
+ <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+ <xul:spacer anonid="spacer" flex="1"/>
+ <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
+ <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="cancel" class="dialog-button"/>
+ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+#else
+ pack="end">
+ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+ <xul:spacer anonid="spacer" flex="1" hidden="true"/>
+ <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
+ <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="cancel" class="dialog-button"/>
+ <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+#endif
+ </xul:hbox>
+
+ <xul:keyset>
+ <xul:key phase="capturing" oncommand="document.documentElement.openHelp(event)"
+#ifdef XP_MACOSX
+ key="&openHelpMac.commandkey;" modifiers="accel"/>
+#else
+ keycode="&openHelp.commandkey;"/>
+#endif
+ </xul:keyset>
+
+ </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");
+ return "accept"; // default to the accept button
+ ]]>
+ </getter>
+ <setter>
+ <![CDATA[
+ this._setDefaultButton(val);
+ return val;
+ ]]>
+ </setter>
+ </property>
+
+ <method name="acceptDialog">
+ <body>
+ <![CDATA[
+ return this._doButtonCommand("accept");
+ ]]>
+ </body>
+ </method>
+
+ <method name="cancelDialog">
+ <body>
+ <![CDATA[
+ return this._doButtonCommand("cancel");
+ ]]>
+ </body>
+ </method>
+
+ <method name="getButton">
+ <parameter name="aDlgType"/>
+ <body>
+ <![CDATA[
+ return this._buttons[aDlgType];
+ ]]>
+ </body>
+ </method>
+
+ <method name="moveToAlertPosition">
+ <body>
+ <![CDATA[
+ // hack. we need this so the window has something like its final size
+ if (window.outerWidth == 1) {
+ dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n");
+ sizeToContent();
+ }
+
+ if (opener) {
+ var xOffset = (opener.outerWidth - window.outerWidth) / 2;
+ var yOffset = opener.outerHeight / 5;
+
+ var newX = opener.screenX + xOffset;
+ var newY = opener.screenY + yOffset;
+ } else {
+ newX = (screen.availWidth - window.outerWidth) / 2;
+ newY = (screen.availHeight - window.outerHeight) / 2;
+ }
+
+ // ensure the window is fully onscreen (if smaller than the screen)
+ if (newX < screen.availLeft)
+ newX = screen.availLeft + 20;
+ if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth))
+ newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20;
+
+ if (newY < screen.availTop)
+ newY = screen.availTop + 20;
+ if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight))
+ newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60;
+
+ window.moveTo( newX, newY );
+ ]]>
+ </body>
+ </method>
+
+ <method name="centerWindowOnScreen">
+ <body>
+ <![CDATA[
+ var xOffset = screen.availWidth / 2 - window.outerWidth / 2;
+ var yOffset = screen.availHeight / 2 - window.outerHeight / 2;
+
+ 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);
+
+ // for things that we need to initialize after onload fires
+ window.addEventListener("load", this.postLoadInit);
+
+ 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) {
+ if (focusedElt.getAttribute("noinitialfocus") == "true") {
+ focusedElt.blur();
+ }
+ 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();
+ }
+ } else if (!/Mac/.test(navigator.platform) &&
+ focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
+ defaultButton.focus();
+ }
+ }
+ }
+
+ try {
+ if (defaultButton)
+ window.notifyDefaultButtonLoaded(defaultButton);
+ } catch (e) { }
+ }
+
+ // Give focus after onload completes, see bug 103197.
+ setTimeout(focusInit, 0);
+ ]]>
+ </body>
+ </method>
+
+ <method name="openHelp">
+ <parameter name="event"/>
+ <body>
+ <![CDATA[
+ var helpButton = document.documentElement.getButton("help");
+ if (helpButton.disabled || helpButton.hidden)
+ return;
+ this._fireButtonEvent("help");
+ event.stopPropagation();
+ event.preventDefault();
+ ]]>
+ </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 = Cc["@mozilla.org/intl/stringbundle;1"]
+ .getService(Ci.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];
+
+ // show the spacer on Windows only when the extra2 button is present
+ if (/Win/.test(navigator.platform)) {
+ var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
+ spacer.removeAttribute("hidden");
+ spacer.setAttribute("flex", shown.extra2 ? "1" : "0");
+ }
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="_setDefaultButton">
+ <parameter name="aNewDefault"/>
+ <body>
+ <![CDATA[
+ // remove the default attribute from the previous default button, if any
+ var oldDefaultButton = this.getButton(this.defaultButton);
+ if (oldDefaultButton)
+ oldDefaultButton.removeAttribute("default");
+
+ var newDefaultButton = this.getButton(aNewDefault);
+ if (newDefaultButton) {
+ this.setAttribute("defaultButton", aNewDefault);
+ newDefaultButton.setAttribute("default", "true");
+ } else {
+ this.setAttribute("defaultButton", "none");
+ if (aNewDefault != "none")
+ dump("invalid new default button: " + aNewDefault + ", assuming: none\n");
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="_handleButtonCommand">
+ <parameter name="aEvent"/>
+ <body>
+ <![CDATA[
+ return document.documentElement._doButtonCommand(
+ aEvent.target.getAttribute("dlgtype"));
+ ]]>
+ </body>
+ </method>
+
+ <method name="_doButtonCommand">
+ <parameter name="aDlgType"/>
+ <body>
+ <![CDATA[
+ var button = this.getButton(aDlgType);
+ if (!button.disabled) {
+ var noCancel = this._fireButtonEvent(aDlgType);
+ if (noCancel) {
+ if (aDlgType == "accept" || aDlgType == "cancel") {
+ var closingEvent = new CustomEvent("dialogclosing", {
+ bubbles: true,
+ detail: { button: aDlgType },
+ });
+ this.dispatchEvent(closingEvent);
+ window.close();
+ }
+ }
+ return noCancel;
+ }
+ return true;
+ ]]>
+ </body>
+ </method>
+
+ <method name="_fireButtonEvent">
+ <parameter name="aDlgType"/>
+ <body>
+ <![CDATA[
+ var event = document.createEvent("Events");
+ event.initEvent("dialog" + aDlgType, true, true);
+
+ // handle dom event handlers
+ var noCancel = this.dispatchEvent(event);
+
+ // handle any xml attribute event handlers
+ var handler = this.getAttribute("ondialog" + aDlgType);
+ if (handler != "") {
+ var fn = new Function("event", handler);
+ var returned = fn(event);
+ // eslint-disable-next-line mozilla/no-compare-against-boolean-literals
+ if (returned == false)
+ noCancel = false;
+ }
+
+ return noCancel;
+ ]]>
+ </body>
+ </method>
+
+ <method name="_hitEnter">
+ <parameter name="evt"/>
+ <body>
+ <![CDATA[
+ if (evt.defaultPrevented)
+ return;
+
+ var btn = this.getButton(this.defaultButton);
+ if (btn)
+ this._doButtonCommand(this.defaultButton);
+ ]]>
+ </body>
+ </method>
+
+ </implementation>
+
+ <handlers>
+ <handler event="keypress" keycode="VK_RETURN"
+ group="system" action="this._hitEnter(event);"/>
+ <handler event="keypress" keycode="VK_ESCAPE" group="system">
+ if (!event.defaultPrevented)
+ this.cancelDialog();
+ </handler>
+#ifdef XP_MACOSX
+ <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/>
+#else
+ <handler event="focus" phase="capturing">
+ var btn = this.getButton(this.defaultButton);
+ if (btn)
+ btn.setAttribute("default", event.originalTarget == btn || !(event.originalTarget instanceof Ci.nsIDOMXULButtonElement));
+ </handler>
+#endif
+ </handlers>
+
+ </binding>
+
+</bindings>
Index: firefox-60.2.0/toolkit/mozapps/downloads/nsHelperAppDlg.js
===================================================================
--- firefox-60.2.0.orig/toolkit/mozapps/downloads/nsHelperAppDlg.js 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/toolkit/mozapps/downloads/nsHelperAppDlg.js 2018-09-05 21:49:31.498872824 +0200
@@ -632,7 +632,7 @@ nsUnknownContentTypeDialog.prototype = {
let [size, unit] = DownloadUtils.
convertByteUnits(this.mLauncher.contentLength);
type.value = this.dialogElement("strings")
- .getFormattedString("orderedFileSizeWithType",
+ .getFormattedString("orderedFileSizeWithType",
[typeString, size, unit]);
}
else {
@@ -806,7 +806,7 @@ nsUnknownContentTypeDialog.prototype = {
case 1:
// only enable the OK button if we have a default app to use or if
// the user chose an app....
- ok = this.chosenApp || /\S/.test(this.dialogElement("otherHandler").getAttribute("path"));
+ ok = this.chosenApp || /\S/.test(this.dialogElement("otherHandler").getAttribute("path"));
break;
}
}
@@ -1071,20 +1071,50 @@ nsUnknownContentTypeDialog.prototype = {
this.chosenApp = params.handlerApp;
}
} else if ("@mozilla.org/applicationchooser;1" in Cc) {
- var nsIApplicationChooser = Ci.nsIApplicationChooser;
- var appChooser = Cc["@mozilla.org/applicationchooser;1"]
- .createInstance(nsIApplicationChooser);
- appChooser.init(this.mDialog, this.dialogElement("strings").getString("chooseAppFilePickerTitle"));
- var contentTypeDialogObj = this;
- let appChooserCallback = function appChooserCallback_done(aResult) {
- if (aResult) {
- contentTypeDialogObj.chosenApp = aResult.QueryInterface(Ci.nsILocalHandlerApp);
- }
- contentTypeDialogObj.finishChooseApp();
- };
- appChooser.open(this.mLauncher.MIMEInfo.MIMEType, appChooserCallback);
- // The finishChooseApp is called from appChooserCallback
- return;
+ // handle the KDE case which is implemented in the filepicker
+ // therefore falling back to Gtk2 like behaviour if KDE is running
+ // FIXME this should be better handled in the nsIApplicationChooser
+ // interface
+ var env = Components.classes["@mozilla.org/process/environment;1"]
+ .getService(Components.interfaces.nsIEnvironment);
+ if (env.get('KDE_FULL_SESSION') == "true")
+ {
+ var nsIFilePicker = Ci.nsIFilePicker;
+ var fp = Cc["@mozilla.org/filepicker;1"]
+ .createInstance(nsIFilePicker);
+ fp.init(this.mDialog,
+ this.dialogElement("strings").getString("chooseAppFilePickerTitle"),
+ nsIFilePicker.modeOpen);
+
+ fp.appendFilters(nsIFilePicker.filterApps);
+
+ fp.open(aResult => {
+ if (aResult == nsIFilePicker.returnOK && fp.file) {
+ // Remember the file they chose to run.
+ var localHandlerApp =
+ Cc["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Ci.nsILocalHandlerApp);
+ localHandlerApp.executable = fp.file;
+ this.chosenApp = localHandlerApp;
+ }
+ this.finishChooseApp();
+ });
+ } else {
+ var nsIApplicationChooser = Ci.nsIApplicationChooser;
+ var appChooser = Cc["@mozilla.org/applicationchooser;1"]
+ .createInstance(nsIApplicationChooser);
+ appChooser.init(this.mDialog, this.dialogElement("strings").getString("chooseAppFilePickerTitle"));
+ var contentTypeDialogObj = this;
+ let appChooserCallback = function appChooserCallback_done(aResult) {
+ if (aResult) {
+ contentTypeDialogObj.chosenApp = aResult.QueryInterface(Ci.nsILocalHandlerApp);
+ }
+ contentTypeDialogObj.finishChooseApp();
+ };
+ appChooser.open(this.mLauncher.MIMEInfo.MIMEType, appChooserCallback);
+ // The finishChooseApp is called from appChooserCallback
+ return;
+ }
} else {
var nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"]
Index: firefox-60.2.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
===================================================================
--- firefox-60.2.0.orig/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2018-09-05 21:49:31.498872824 +0200
@@ -20,6 +20,7 @@
#include "nsInterfaceHashtable.h"
#include "mozilla/Attributes.h"
#include "nsIURI.h"
+#include "nsKDEUtils.h"
class nsUnixSystemProxySettings final : public nsISystemProxySettings {
public:
@@ -44,6 +45,7 @@ private:
nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult);
nsresult GetProxyFromGSettings(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult);
nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, nsACString& aResult);
+ nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
};
NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings)
@@ -510,6 +512,9 @@ nsUnixSystemProxySettings::GetProxyForUR
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))
@@ -545,3 +550,29 @@ static const mozilla::Module kUnixProxyM
};
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;
+}
+
Index: firefox-60.2.0/toolkit/xre/moz.build
===================================================================
--- firefox-60.2.0.orig/toolkit/xre/moz.build 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/toolkit/xre/moz.build 2018-09-05 21:49:31.498872824 +0200
@@ -70,7 +70,9 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'ui
'UIKitDirProvider.mm',
]
elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
+ EXPORTS += ['nsKDEUtils.h']
UNIFIED_SOURCES += [
+ 'nsKDEUtils.cpp',
'nsNativeAppSupportUnix.cpp',
]
else:
Index: firefox-60.2.0/toolkit/xre/nsKDEUtils.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/toolkit/xre/nsKDEUtils.cpp 2018-09-05 21:49:31.498872824 +0200
@@ -0,0 +1,344 @@
+/* -*- 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>
+// copied from X11/X.h as a hack since for an unknown
+// reason it's not picked up from X11/X.h
+#ifndef None
+#define None 0L /* universal null resource or null atom */
+#endif
+
+//#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 );
+ }
+
+ NS_ADDREF( *output = result);
+ return ret;
+ }
+
+
+bool nsKDEUtils::commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output )
+ {
+ return self()->internalCommand( command, parent, true, output );
+ }
+
+bool nsKDEUtils::internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool blockUi,
+ nsTArray<nsCString>* output )
+ {
+ if( !startHelper())
+ return false;
+ feedCommand( command );
+ // do not store the data in 'this' but in extra structure, just in case there
+ // is reentrancy (can there be? the event loop is re-entered)
+ nsKDECommandData data;
+ data.file = replyFile;
+ data.output = output;
+ data.success = false;
+ if( blockUi )
+ {
+ data.loop = g_main_loop_new( NULL, FALSE );
+ GtkWidget* window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ if( parent && gtk_window_get_group(parent) )
+ gtk_window_group_add_window( gtk_window_get_group(parent), GTK_WINDOW( window ));
+ gtk_widget_realize( window );
+ gtk_widget_set_sensitive( window, TRUE );
+ gtk_grab_add( window );
+ GIOChannel* channel = g_io_channel_unix_new( fileno( data.file ));
+ g_io_add_watch( channel, static_cast< GIOCondition >( G_IO_IN | G_IO_ERR | G_IO_HUP ), kdeReadFunc, &data );
+ g_io_channel_unref( channel );
+ g_main_loop_run( data.loop );
+ g_main_loop_unref( data.loop );
+ gtk_grab_remove( window );
+ gtk_widget_destroy( window );
+ }
+ else
+ {
+ data.loop = NULL;
+ while( kdeReadFunc( NULL, static_cast< GIOCondition >( 0 ), &data ))
+ ;
+ }
+ return data.success;
+ }
+
+bool nsKDEUtils::startHelper()
+ {
+ if( helperRunning )
+ return true;
+ if( helperFailed )
+ return false;
+ helperFailed = true;
+ int fdcommand[ 2 ];
+ int fdreply[ 2 ];
+ if( pipe( fdcommand ) < 0 )
+ return false;
+ if( pipe( fdreply ) < 0 )
+ {
+ close( fdcommand[ 0 ] );
+ close( fdcommand[ 1 ] );
+ return false;
+ }
+ char* args[ 2 ] = { const_cast< char* >( KMOZILLAHELPER ), NULL };
+ switch( fork())
+ {
+ case -1:
+ {
+ close( fdcommand[ 0 ] );
+ close( fdcommand[ 1 ] );
+ close( fdreply[ 0 ] );
+ close( fdreply[ 1 ] );
+ return false;
+ }
+ case 0: // child
+ {
+ if( dup2( fdcommand[ 0 ], STDIN_FILENO ) < 0 )
+ _exit( 1 );
+ if( dup2( fdreply[ 1 ], STDOUT_FILENO ) < 0 )
+ _exit( 1 );
+ int maxfd = 1024; // close all other fds
+ struct rlimit rl;
+ if( getrlimit( RLIMIT_NOFILE, &rl ) == 0 )
+ maxfd = rl.rlim_max;
+ for( int i = 3;
+ i < maxfd;
+ ++i )
+ close( i );
+#ifdef DEBUG_KDE
+ execvp( KMOZILLAHELPER, args );
+#else
+ execv( KMOZILLAHELPER, args );
+#endif
+ _exit( 1 ); // failed
+ }
+ default: // parent
+ {
+ commandFile = fdopen( fdcommand[ 1 ], "w" );
+ replyFile = fdopen( fdreply[ 0 ], "r" );
+ close( fdcommand[ 0 ] );
+ close( fdreply[ 1 ] );
+ if( commandFile == NULL || replyFile == NULL )
+ {
+ closeHelper();
+ return false;
+ }
+ // ok, helper ready, getKdeRunning() will check if it works
+ }
+ }
+ helperFailed = false;
+ helperRunning = true;
+ return true;
+ }
+
+void nsKDEUtils::closeHelper()
+ {
+ if( commandFile != NULL )
+ fclose( commandFile ); // this will also make the helper quit
+ if( replyFile != NULL )
+ fclose( replyFile );
+ helperRunning = false;
+ }
+
+void nsKDEUtils::feedCommand( const nsTArray<nsCString>& command )
+ {
+ for( int i = 0;
+ i < command.Length();
+ ++i )
+ {
+ nsCString line = command[ i ];
+ line.ReplaceSubstring( "\\", "\\" "\\" ); // \ -> \\ , i.e. escape
+ line.ReplaceSubstring( "\n", "\\n" );
+#ifdef DEBUG_KDE
+ fprintf( stderr, "COMM: %s\n", line.get());
+#endif
+ fputs( line.get(), commandFile );
+ fputs( "\n", commandFile );
+ }
+ fputs( "\\E\n", commandFile ); // done as \E, so it cannot happen in normal data
+ fflush( commandFile );
+ }
Index: firefox-60.2.0/toolkit/xre/nsKDEUtils.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/toolkit/xre/nsKDEUtils.h 2018-09-05 21:49:31.498872824 +0200
@@ -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 "nsString.h"
+#include "nsTArray.h"
+#include <stdio.h>
+
+typedef struct _GtkWindow GtkWindow;
+
+class nsIArray;
+
+class NS_EXPORT nsKDEUtils
+ {
+ public:
+ /* Returns true if running inside a KDE session (regardless of whether there is KDE
+ support available for Firefox). This should be used e.g. when determining
+ dialog button order but not for code that requires the KDE support. */
+ static bool kdeSession();
+ /* Returns true if running inside a KDE session and KDE support is available
+ for Firefox. This should be used everywhere where the external helper is needed. */
+ static bool kdeSupport();
+ /* Executes the given helper command, returns true if helper returned success. */
+ static bool command( const nsTArray<nsCString>& command, nsTArray<nsCString>* output = NULL );
+ static bool command( nsIArray* command, nsIArray** output = NULL );
+ /* Like command(), but additionally blocks the parent widget like if there was
+ a modal dialog shown and enters the event loop (i.e. there are still paint updates,
+ this is for commands that take long). */
+ static bool commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output = NULL );
+
+ private:
+ nsKDEUtils();
+ ~nsKDEUtils();
+ static nsKDEUtils* self();
+ bool startHelper();
+ void closeHelper();
+ void feedCommand( const nsTArray<nsCString>& command );
+ bool internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool isParent,
+ nsTArray<nsCString>* output );
+ FILE* commandFile;
+ FILE* replyFile;
+ };
+
+#endif // nsKDEUtils
Index: firefox-60.2.0/uriloader/exthandler/HandlerServiceParent.cpp
===================================================================
--- firefox-60.2.0.orig/uriloader/exthandler/HandlerServiceParent.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/uriloader/exthandler/HandlerServiceParent.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -5,7 +5,7 @@
#include "ContentHandlerService.h"
#include "nsStringEnumerator.h"
#ifdef MOZ_WIDGET_GTK
-#include "unix/nsGNOMERegistry.h"
+#include "unix/nsCommonRegistry.h"
#endif
using mozilla::dom::HandlerInfo;
@@ -269,7 +269,7 @@ HandlerServiceParent::RecvExistsForProto
{
#ifdef MOZ_WIDGET_GTK
// Check the GNOME registry for a protocol handler
- *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme.get());
+ *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme.get());
#else
*aHandlerExists = false;
#endif
Index: firefox-60.2.0/uriloader/exthandler/moz.build
===================================================================
--- firefox-60.2.0.orig/uriloader/exthandler/moz.build 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/uriloader/exthandler/moz.build 2018-09-05 21:49:31.502872845 +0200
@@ -82,7 +82,9 @@ else:
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
UNIFIED_SOURCES += [
+ 'unix/nsCommonRegistry.cpp',
'unix/nsGNOMERegistry.cpp',
+ 'unix/nsKDERegistry.cpp',
'unix/nsMIMEInfoUnix.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
@@ -129,6 +131,7 @@ LOCAL_INCLUDES += [
'/dom/ipc',
'/netwerk/base',
'/netwerk/protocol/http',
+ '/toolkit/xre',
]
if CONFIG['MOZ_ENABLE_DBUS']:
Index: firefox-60.2.0/uriloader/exthandler/unix/nsCommonRegistry.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/uriloader/exthandler/unix/nsCommonRegistry.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCommonRegistry.h"
+
+#include "nsGNOMERegistry.h"
+#include "nsKDERegistry.h"
+#include "nsString.h"
+#include "nsKDEUtils.h"
+
+/* static */ bool
+nsCommonRegistry::HandlerExists(const char *aProtocolScheme)
+{
+ if( nsKDEUtils::kdeSupport())
+ return nsKDERegistry::HandlerExists( aProtocolScheme );
+ return nsGNOMERegistry::HandlerExists( aProtocolScheme );
+}
+
+/* static */ nsresult
+nsCommonRegistry::LoadURL(nsIURI *aURL)
+{
+ if( nsKDEUtils::kdeSupport())
+ return nsKDERegistry::LoadURL( aURL );
+ return nsGNOMERegistry::LoadURL( aURL );
+}
+
+/* static */ void
+nsCommonRegistry::GetAppDescForScheme(const nsACString& aScheme,
+ nsAString& aDesc)
+{
+ if( nsKDEUtils::kdeSupport())
+ return nsKDERegistry::GetAppDescForScheme( aScheme, aDesc );
+ return nsGNOMERegistry::GetAppDescForScheme( aScheme, aDesc );
+}
+
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsCommonRegistry::GetFromExtension(const nsACString& aFileExt)
+{
+ if( nsKDEUtils::kdeSupport())
+ return nsKDERegistry::GetFromExtension( aFileExt );
+ return nsGNOMERegistry::GetFromExtension( aFileExt );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsCommonRegistry::GetFromType(const nsACString& aMIMEType)
+{
+ if( nsKDEUtils::kdeSupport())
+ return nsKDERegistry::GetFromType( aMIMEType );
+ return nsGNOMERegistry::GetFromType( aMIMEType );
+}
Index: firefox-60.2.0/uriloader/exthandler/unix/nsCommonRegistry.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/uriloader/exthandler/unix/nsCommonRegistry.h 2018-09-05 21:49:31.502872845 +0200
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsCommonRegistry_h__
+#define nsCommonRegistry_h__
+
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+
+class nsMIMEInfoBase;
+
+class nsCommonRegistry
+{
+ public:
+ static bool HandlerExists(const char *aProtocolScheme);
+
+ static nsresult LoadURL(nsIURI *aURL);
+
+ static void GetAppDescForScheme(const nsACString& aScheme,
+ nsAString& aDesc);
+
+ static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
+
+ static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
+};
+
+#endif
Index: firefox-60.2.0/uriloader/exthandler/unix/nsKDERegistry.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/uriloader/exthandler/unix/nsKDERegistry.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -0,0 +1,87 @@
+/* -*- 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 "nsMIMEInfoUnix.h"
+#include "nsAutoPtr.h"
+#include "nsKDEUtils.h"
+
+/* static */ bool
+nsKDERegistry::HandlerExists(const char *aProtocolScheme)
+{
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "HANDLEREXISTS" ));
+ command.AppendElement( nsAutoCString( aProtocolScheme ));
+ return nsKDEUtils::command( command );
+}
+
+/* static */ nsresult
+nsKDERegistry::LoadURL(nsIURI *aURL)
+{
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "OPEN" ));
+ nsCString url;
+ aURL->GetSpec( url );
+ command.AppendElement( url );
+ bool rv = nsKDEUtils::command( command );
+ if (!rv)
+ return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
+/* static */ void
+nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
+ nsAString& aDesc)
+{
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "GETAPPDESCFORSCHEME" ));
+ command.AppendElement( aScheme );
+ nsTArray<nsCString> output;
+ if( nsKDEUtils::command( command, &output ) && output.Length() == 1 )
+ CopyUTF8toUTF16( output[ 0 ], aDesc );
+}
+
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsKDERegistry::GetFromExtension(const nsACString& aFileExt)
+{
+ NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "GETFROMEXTENSION" ));
+ command.AppendElement( aFileExt );
+ return GetFromHelper( command );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsKDERegistry::GetFromType(const nsACString& aMIMEType)
+{
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "GETFROMTYPE" ));
+ command.AppendElement( aMIMEType );
+ return GetFromHelper( command );
+}
+
+/* static */ already_AddRefed<nsMIMEInfoBase>
+nsKDERegistry::GetFromHelper(const nsTArray<nsCString>& command)
+{
+ nsTArray<nsCString> output;
+ if( nsKDEUtils::command( command, &output ) && output.Length() == 3 )
+ {
+ nsCString mimetype = output[ 0 ];
+ RefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix( mimetype );
+ NS_ENSURE_TRUE(mimeInfo, nullptr);
+ nsCString description = output[ 1 ];
+ mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
+ nsCString handlerAppName = output[ 2 ];
+ mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
+ mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
+ return mimeInfo.forget();
+ }
+ return nullptr;
+}
Index: firefox-60.2.0/uriloader/exthandler/unix/nsKDERegistry.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ firefox-60.2.0/uriloader/exthandler/unix/nsKDERegistry.h 2018-09-05 21:49:31.502872845 +0200
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsKDERegistry_h__
+#define nsKDERegistry_h__
+
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+
+class nsMIMEInfoBase;
+//class nsAutoCString;
+//class nsCString;
+
+class nsKDERegistry
+{
+ public:
+ static bool HandlerExists(const char *aProtocolScheme);
+
+ static nsresult LoadURL(nsIURI *aURL);
+
+ static void GetAppDescForScheme(const nsACString& aScheme,
+ nsAString& aDesc);
+
+ static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
+
+ static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
+ private:
+ static already_AddRefed<nsMIMEInfoBase> GetFromHelper(const nsTArray<nsCString>& command);
+
+};
+
+#endif //nsKDERegistry_h__
Index: firefox-60.2.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
===================================================================
--- firefox-60.2.0.orig/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsMIMEInfoUnix.h"
-#include "nsGNOMERegistry.h"
+#include "nsCommonRegistry.h"
#include "nsIGIOService.h"
#include "nsNetCID.h"
#include "nsIIOService.h"
@@ -13,11 +13,14 @@
#ifdef MOZ_ENABLE_DBUS
#include "nsDBusHandlerApp.h"
#endif
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+#include "nsKDEUtils.h"
+#endif
nsresult
nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
{
- return nsGNOMERegistry::LoadURL(aURI);
+ return nsCommonRegistry::LoadURL(aURI);
}
NS_IMETHODIMP
@@ -32,14 +35,14 @@ nsMIMEInfoUnix::GetHasDefaultHandler(boo
*_retval = false;
if (mClass == eProtocolInfo) {
- *_retval = nsGNOMERegistry::HandlerExists(mSchemeOrType.get());
+ *_retval = nsCommonRegistry::HandlerExists(mSchemeOrType.get());
} else {
- RefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromType(mSchemeOrType);
+ RefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromType(mSchemeOrType);
if (!mimeInfo) {
nsAutoCString ext;
nsresult rv = GetPrimaryExtension(ext);
if (NS_SUCCEEDED(rv)) {
- mimeInfo = nsGNOMERegistry::GetFromExtension(ext);
+ mimeInfo = nsCommonRegistry::GetFromExtension(ext);
}
}
if (mimeInfo)
@@ -64,6 +67,23 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
nsAutoCString nativePath;
aFile->GetNativePath(nativePath);
+ if( nsKDEUtils::kdeSupport()) {
+ bool supports;
+ if( NS_SUCCEEDED( GetHasDefaultHandler( &supports )) && supports ) {
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING( "OPEN" ));
+ command.AppendElement( nativePath );
+ command.AppendElement( NS_LITERAL_CSTRING( "MIMETYPE" ));
+ command.AppendElement( mSchemeOrType );
+ if( nsKDEUtils::command( command ))
+ return NS_OK;
+ }
+ if (!mDefaultApplication)
+ return NS_ERROR_FILE_NOT_FOUND;
+
+ return LaunchWithIProcess(mDefaultApplication, nativePath);
+ }
+
nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
if (!giovfs) {
return NS_ERROR_FAILURE;
Index: firefox-60.2.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp
===================================================================
--- firefox-60.2.0.orig/uriloader/exthandler/unix/nsOSHelperAppService.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -10,7 +10,7 @@
#include "nsOSHelperAppService.h"
#include "nsMIMEInfoUnix.h"
#ifdef MOZ_WIDGET_GTK
-#include "nsGNOMERegistry.h"
+#include "nsCommonRegistry.h"
#endif
#include "nsISupports.h"
#include "nsString.h"
@@ -1133,7 +1133,7 @@ nsresult nsOSHelperAppService::OSProtoco
if (!XRE_IsContentProcess()) {
#ifdef MOZ_WIDGET_GTK
// Check the GNOME registry for a protocol handler
- *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme);
+ *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme);
#else
*aHandlerExists = false;
#endif
@@ -1151,7 +1151,7 @@ nsresult nsOSHelperAppService::OSProtoco
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;
@@ -1248,7 +1248,7 @@ nsOSHelperAppService::GetFromExtension(c
#ifdef MOZ_WIDGET_GTK
LOG(("Looking in GNOME registry\n"));
RefPtr<nsMIMEInfoBase> gnomeInfo =
- nsGNOMERegistry::GetFromExtension(aFileExt);
+ nsCommonRegistry::GetFromExtension(aFileExt);
if (gnomeInfo) {
LOG(("Got MIMEInfo from GNOME registry\n"));
return gnomeInfo.forget();
@@ -1369,7 +1369,7 @@ nsOSHelperAppService::GetFromType(const
#ifdef MOZ_WIDGET_GTK
if (handler.IsEmpty()) {
- RefPtr<nsMIMEInfoBase> gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType);
+ RefPtr<nsMIMEInfoBase> gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType);
if (gnomeInfo) {
LOG(("Got MIMEInfo from GNOME registry without extensions; setting them "
"to %s\n", NS_LossyConvertUTF16toASCII(extensions).get()));
Index: firefox-60.2.0/widget/gtk/moz.build
===================================================================
--- firefox-60.2.0.orig/widget/gtk/moz.build 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/widget/gtk/moz.build 2018-09-05 21:49:31.502872845 +0200
@@ -126,6 +126,7 @@ LOCAL_INCLUDES += [
'/layout/generic',
'/layout/xul',
'/other-licenses/atk-1.0',
+ '/toolkit/xre',
'/widget',
'/widget/headless',
]
Index: firefox-60.2.0/widget/gtk/nsFilePicker.cpp
===================================================================
--- firefox-60.2.0.orig/widget/gtk/nsFilePicker.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/widget/gtk/nsFilePicker.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -9,6 +9,7 @@
#include <unistd.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include "nsGtkUtils.h"
#include "nsIFileURL.h"
@@ -25,6 +26,7 @@
#include "mozcontainer.h"
#include "nsFilePicker.h"
+#include "nsKDEUtils.h"
using namespace mozilla;
@@ -251,7 +253,9 @@ nsFilePicker::AppendFilter(const nsAStri
{
if (aFilter.EqualsLiteral("..apps")) {
// No platform specific thing we can do here, really....
- return NS_OK;
+ // Unless it's KDE.
+ if( mMode != modeOpen || !nsKDEUtils::kdeSupport())
+ return NS_OK;
}
nsAutoCString filter, name;
@@ -376,6 +380,29 @@ nsFilePicker::Open(nsIFilePickerShownCal
if (mRunning)
return NS_ERROR_NOT_AVAILABLE;
+ // KDE file picker is not handled via callback
+ if( nsKDEUtils::kdeSupport()) {
+ mCallback = aCallback;
+ mRunning = true;
+ NS_ADDREF_THIS();
+ g_idle_add([](gpointer data) -> gboolean {
+ nsFilePicker* queuedPicker = (nsFilePicker*) data;
+ int16_t result;
+ queuedPicker->kdeFileDialog(&result);
+ if (queuedPicker->mCallback) {
+ queuedPicker->mCallback->Done(result);
+ queuedPicker->mCallback = nullptr;
+ } else {
+ queuedPicker->mResult = result;
+ }
+ queuedPicker->mRunning = false;
+ NS_RELEASE(queuedPicker);
+ return G_SOURCE_REMOVE;
+ }, this);
+
+ return NS_OK;
+ }
+
nsCString title;
title.Adopt(ToNewUTF8String(mTitle));
@@ -613,3 +640,228 @@ nsFilePicker::Done(GtkWidget* file_choos
}
NS_RELEASE_THIS();
}
+
+nsCString nsFilePicker::kdeMakeFilter( int index )
+ {
+ nsCString buf = mFilters[ index ];
+ for( PRUint32 i = 0;
+ i < buf.Length();
+ ++i )
+ if( buf[ i ] == ';' ) // KDE separates just using spaces
+ buf.SetCharAt( ' ', i );
+ if (!mFilterNames[index].IsEmpty())
+ {
+ buf += "|";
+ buf += mFilterNames[index].get();
+ }
+ return buf;
+ }
+
+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 );
+
+ nsCString title;
+ title.Adopt(ToNewUTF8String(mTitle));
+
+ const char* arg = NULL;
+ if( mAllowURLs )
+ {
+ switch( mMode )
+ {
+ case nsIFilePicker::modeOpen:
+ case nsIFilePicker::modeOpenMultiple:
+ arg = "GETOPENURL";
+ break;
+ case nsIFilePicker::modeSave:
+ arg = "GETSAVEURL";
+ break;
+ case nsIFilePicker::modeGetFolder:
+ arg = "GETDIRECTORYURL";
+ break;
+ }
+ }
+ else
+ {
+ switch( mMode )
+ {
+ case nsIFilePicker::modeOpen:
+ case nsIFilePicker::modeOpenMultiple:
+ arg = "GETOPENFILENAME";
+ break;
+ case nsIFilePicker::modeSave:
+ arg = "GETSAVEFILENAME";
+ break;
+ case nsIFilePicker::modeGetFolder:
+ arg = "GETDIRECTORYFILENAME";
+ break;
+ }
+ }
+
+ nsAutoCString directory;
+ if (mDisplayDirectory) {
+ 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);
+ }
+
+ 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);
+
+ nsCString 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;
+ }
+
Index: firefox-60.2.0/widget/gtk/nsFilePicker.h
===================================================================
--- firefox-60.2.0.orig/widget/gtk/nsFilePicker.h 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/widget/gtk/nsFilePicker.h 2018-09-05 21:49:31.502872845 +0200
@@ -74,6 +74,12 @@ protected:
private:
static nsIFile *mPrevDisplayDirectory;
+ bool kdeRunning();
+ bool getKdeRunning();
+ NS_IMETHODIMP kdeFileDialog(PRInt16 *aReturn);
+ NS_IMETHODIMP kdeAppsDialog(PRInt16 *aReturn);
+ nsCString kdeMakeFilter( int index );
+
#ifdef MOZ_WIDGET_GTK
GtkFileChooserWidget *mFileChooserDelegate;
#endif
Index: firefox-60.2.0/xpcom/components/ManifestParser.cpp
===================================================================
--- firefox-60.2.0.orig/xpcom/components/ManifestParser.cpp 2018-09-05 21:49:23.106829422 +0200
+++ firefox-60.2.0/xpcom/components/ManifestParser.cpp 2018-09-05 21:49:31.502872845 +0200
@@ -38,6 +38,7 @@
#include "nsIScriptError.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
+#include "nsKDEUtils.h"
using namespace mozilla;
@@ -449,6 +450,7 @@ ParseManifest(NSLocationType aType, File
NS_NAMED_LITERAL_STRING(kOs, "os");
NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
NS_NAMED_LITERAL_STRING(kABI, "abi");
+ NS_NAMED_LITERAL_STRING(kDesktop, "desktop");
NS_NAMED_LITERAL_STRING(kProcess, "process");
#if defined(MOZ_WIDGET_ANDROID)
NS_NAMED_LITERAL_STRING(kTablet, "tablet");
@@ -504,6 +506,7 @@ ParseManifest(NSLocationType aType, File
}
nsAutoString osVersion;
+ nsAutoString desktop;
#if defined(XP_WIN)
#pragma warning(push)
#pragma warning(disable:4996) // VC12+ deprecates GetVersionEx
@@ -513,6 +516,7 @@ ParseManifest(NSLocationType aType, File
info.dwMajorVersion,
info.dwMinorVersion);
}
+ desktop = NS_LITERAL_STRING("win");
#pragma warning(pop)
#elif defined(MOZ_WIDGET_COCOA)
SInt32 majorVersion = nsCocoaFeatures::OSXVersionMajor();
@@ -520,10 +524,12 @@ ParseManifest(NSLocationType aType, File
nsTextFormatter::ssprintf(osVersion, u"%ld.%ld",
majorVersion,
minorVersion);
+ desktop = NS_LITERAL_STRING("macosx");
#elif defined(MOZ_WIDGET_GTK)
nsTextFormatter::ssprintf(osVersion, u"%ld.%ld",
gtk_major_version,
gtk_minor_version);
+ desktop = nsKDEUtils::kdeSession() ? NS_LITERAL_STRING("kde") : NS_LITERAL_STRING("gnome");
#elif defined(MOZ_WIDGET_ANDROID)
bool isTablet = false;
if (mozilla::AndroidBridge::Bridge()) {
@@ -532,6 +538,7 @@ ParseManifest(NSLocationType aType, File
osVersion);
isTablet = java::GeckoAppShell::IsTablet();
}
+ desktop = NS_LITERAL_STRING("android");
#endif
if (XRE_IsContentProcess()) {
@@ -643,6 +650,7 @@ ParseManifest(NSLocationType aType, File
TriState stTablet = eUnspecified;
#endif
int flags = 0;
+ TriState stDesktop = eUnspecified;
while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
ok) {
@@ -652,6 +660,7 @@ ParseManifest(NSLocationType aType, File
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckOsFlag(kOs, wtoken, osTarget, stOs) ||
CheckStringFlag(kABI, wtoken, abi, stABI) ||
+ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
CheckStringFlag(kProcess, wtoken, process, stProcess) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
@@ -706,6 +715,7 @@ ParseManifest(NSLocationType aType, File
stGeckoVersion == eBad ||
stOs == eBad ||
stOsVersion == eBad ||
+ stDesktop == eBad ||
#ifdef MOZ_WIDGET_ANDROID
stTablet == eBad ||
#endif
Index: firefox-60.2.0/xpcom/components/moz.build
===================================================================
--- firefox-60.2.0.orig/xpcom/components/moz.build 2018-09-05 21:49:23.110829442 +0200
+++ firefox-60.2.0/xpcom/components/moz.build 2018-09-05 21:49:31.502872845 +0200
@@ -49,6 +49,7 @@ LOCAL_INCLUDES += [
'../reflect/xptinfo',
'/chrome',
'/modules/libjar',
+ '/toolkit/xre'
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
Index: firefox-60.2.0/xpcom/io/nsLocalFileUnix.cpp
===================================================================
--- firefox-60.2.0.orig/xpcom/io/nsLocalFileUnix.cpp 2018-09-05 21:49:23.110829442 +0200
+++ firefox-60.2.0/xpcom/io/nsLocalFileUnix.cpp 2018-09-05 21:56:47.649117623 +0200
@@ -52,6 +52,7 @@
#ifdef MOZ_WIDGET_GTK
#include "nsIGIOService.h"
+#include "nsKDEUtils.h"
#endif
#ifdef MOZ_WIDGET_COCOA
@@ -2010,18 +2011,16 @@ nsLocalFile::Reveal()
}
#ifdef MOZ_WIDGET_GTK
- nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
- if (!giovfs) {
- return NS_ERROR_FAILURE;
- }
+ nsAutoCString url;
bool isDirectory;
if (NS_FAILED(IsDirectory(&isDirectory))) {
return NS_ERROR_FAILURE;
}
+ nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
if (isDirectory) {
- return giovfs->ShowURIForInput(mPath);
+ url = mPath;
}
if (NS_SUCCEEDED(giovfs->OrgFreedesktopFileManager1ShowItems(mPath))) {
return NS_OK;
@@ -2035,7 +2034,7 @@ nsLocalFile::Reveal()
return NS_ERROR_FAILURE;
}
- return giovfs->ShowURIForInput(dirPath);
+ url = dirPath;
#elif defined(MOZ_WIDGET_COCOA)
CFURLRef url;
if (NS_SUCCEEDED(GetCFURL(&url))) {
@@ -2047,6 +2046,17 @@ nsLocalFile::Reveal()
#else
return NS_ERROR_FAILURE;
#endif
+ if(nsKDEUtils::kdeSupport()) {
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING("REVEAL") );
+ command.AppendElement( mPath );
+ return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
+ }
+
+ if (!giovfs)
+ return NS_ERROR_FAILURE;
+
+ return giovfs->ShowURIForInput(url);
}
NS_IMETHODIMP
@@ -2057,6 +2067,12 @@ nsLocalFile::Launch()
}
#ifdef MOZ_WIDGET_GTK
+ if( nsKDEUtils::kdeSupport()) {
+ nsTArray<nsCString> command;
+ command.AppendElement( NS_LITERAL_CSTRING("OPEN") );
+ command.AppendElement( mPath );
+ return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
+ }
nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
if (!giovfs) {
return NS_ERROR_FAILURE;