1 # HG changeset patch |
1 # HG changeset patch |
2 # User msirringhaus@suse.de |
2 # User msirringhaus@suse.de |
3 # Date 1559294891 -7200 |
3 # Date 1559294891 -7200 |
4 # Fri May 31 11:28:11 2019 +0200 |
4 # Fri May 31 11:28:11 2019 +0200 |
5 # Node ID c2aa7198fb925e7fde96abf65b6f68b9b755f112 |
5 # Node ID c2aa7198fb925e7fde96abf65b6f68b9b755f112 |
6 # Parent 4f8492f0f4bfa17f5b4523a1cdda15a45e3d74d3 |
6 # Parent 0086fcc0d5c86a31cbac0a261ed7b526dd2df2e8 |
7 Description: Add KDE integration to Firefox (toolkit parts) |
7 Description: Add KDE integration to Firefox (toolkit parts) |
8 Author: Wolfgang Rosenauer <wolfgang@rosenauer.org> |
8 Author: Wolfgang Rosenauer <wolfgang@rosenauer.org> |
9 Author: Lubos Lunak <lunak@suse.com> |
9 Author: Lubos Lunak <lunak@suse.com> |
10 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751 |
10 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751 |
11 https://bugzilla.novell.com/show_bug.cgi?id=170055 |
11 https://bugzilla.novell.com/show_bug.cgi?id=170055 |
12 |
12 |
13 diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp |
13 Index: firefox-115.0/modules/libpref/Preferences.cpp |
14 --- a/modules/libpref/Preferences.cpp |
14 =================================================================== |
15 +++ b/modules/libpref/Preferences.cpp |
15 --- firefox-115.0.orig/modules/libpref/Preferences.cpp |
16 @@ -91,16 +91,17 @@ |
16 +++ firefox-115.0/modules/libpref/Preferences.cpp |
17 #include "plstr.h" |
17 @@ -95,6 +95,7 @@ |
18 #include "prdtoa.h" |
|
19 #include "prlink.h" |
|
20 #include "xpcpublic.h" |
|
21 #include "js/RootingAPI.h" |
|
22 #ifdef MOZ_BACKGROUNDTASKS |
18 #ifdef MOZ_BACKGROUNDTASKS |
23 # include "mozilla/BackgroundTasks.h" |
19 # include "mozilla/BackgroundTasks.h" |
24 #endif |
20 #endif |
25 +#include "nsKDEUtils.h" |
21 +#include "nsKDEUtils.h" |
26 |
22 |
27 #ifdef DEBUG |
23 #ifdef DEBUG |
28 # include <map> |
24 # include <map> |
29 #endif |
25 @@ -4911,6 +4912,16 @@ nsresult Preferences::InitInitialObjects |
30 |
|
31 #ifdef MOZ_MEMORY |
|
32 # include "mozmemory.h" |
|
33 #endif |
|
34 @@ -4907,16 +4908,27 @@ nsresult Preferences::InitInitialObjects |
|
35 "unix.js" |
|
36 # if defined(_AIX) |
|
37 , |
|
38 "aix.js" |
|
39 # endif |
|
40 #endif |
26 #endif |
41 }; |
27 }; |
42 |
28 |
43 + if(nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires the helper? |
29 + if (nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires |
44 + for(int i = 0; |
30 + // the helper? |
45 + i < MOZ_ARRAY_LENGTH(specialFiles); |
31 + for (int i = 0; i < MOZ_ARRAY_LENGTH(specialFiles); ++i) { |
46 + ++i ) { |
32 + if (*specialFiles[i] == '\0') { |
47 + if( *specialFiles[ i ] == '\0' ) { |
33 + specialFiles[i] = "kde.js"; |
48 + specialFiles[ i ] = "kde.js"; |
|
49 + break; |
34 + break; |
50 + } |
35 + } |
51 + } |
36 + } |
52 + } |
37 + } |
53 + |
38 + |
54 rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, |
39 rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, |
55 ArrayLength(specialFiles)); |
40 ArrayLength(specialFiles)); |
56 if (NS_FAILED(rv)) { |
41 if (NS_FAILED(rv)) { |
57 NS_WARNING("Error parsing application default preferences."); |
42 @@ -4985,7 +4996,7 @@ nsresult Preferences::InitInitialObjects |
58 } |
|
59 |
|
60 // Load jar:$app/omni.jar!/defaults/preferences/*.js |
|
61 // or jar:$gre/omni.jar!/defaults/preferences/*.js. |
|
62 @@ -4981,17 +4993,17 @@ nsresult Preferences::InitInitialObjects |
|
63 } |
|
64 |
|
65 nsCOMPtr<nsIFile> path = do_QueryInterface(elem); |
|
66 if (!path) { |
|
67 continue; |
|
68 } |
43 } |
69 |
44 |
70 // Do we care if a file provided by this process fails to load? |
45 // Do we care if a file provided by this process fails to load? |
71 - pref_LoadPrefsInDir(path, nullptr, 0); |
46 - pref_LoadPrefsInDir(path, nullptr, 0); |
72 + pref_LoadPrefsInDir(path, specialFiles, ArrayLength(specialFiles)); |
47 + pref_LoadPrefsInDir(path, specialFiles, ArrayLength(specialFiles)); |
73 } |
48 } |
74 } |
49 } |
75 |
50 |
76 #if defined(MOZ_WIDGET_GTK) |
51 Index: firefox-115.0/modules/libpref/moz.build |
77 // To ensure the system-wide preferences are not overwritten by |
52 =================================================================== |
78 // firefox/browser/defauts/preferences/*.js we need to load |
53 --- firefox-115.0.orig/modules/libpref/moz.build |
79 // the /etc/firefox/defaults/pref/*.js settings as last. |
54 +++ firefox-115.0/modules/libpref/moz.build |
80 // Under Flatpak, the NS_OS_SYSTEM_CONFIG_DIR points to /app/etc/firefox |
55 @@ -126,6 +126,10 @@ UNIFIED_SOURCES += [ |
81 diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build |
|
82 --- a/modules/libpref/moz.build |
|
83 +++ b/modules/libpref/moz.build |
|
84 @@ -122,16 +122,20 @@ EXPORTS.mozilla += [ |
|
85 ] |
|
86 EXPORTS.mozilla += sorted(["!" + g for g in gen_h]) |
|
87 |
|
88 UNIFIED_SOURCES += [ |
|
89 "Preferences.cpp", |
|
90 "SharedPrefMap.cpp", |
56 "SharedPrefMap.cpp", |
91 ] |
57 ] |
92 |
58 |
93 +LOCAL_INCLUDES += [ |
59 +LOCAL_INCLUDES += [ |
94 + '/toolkit/xre' |
60 + '/toolkit/xre' |
95 +] |
61 +] |
96 + |
62 + |
97 gen_all_tuple = tuple(gen_h + gen_cpp + gen_rs) |
63 gen_all_tuple = tuple(gen_h + gen_cpp + gen_rs) |
98 |
64 |
99 GeneratedFile( |
65 GeneratedFile( |
100 *gen_all_tuple, |
66 Index: firefox-115.0/python/mozbuild/mozpack/chrome/flags.py |
101 script="init/generate_static_pref_list.py", |
67 =================================================================== |
102 entry_point="emit_code", |
68 --- firefox-115.0.orig/python/mozbuild/mozpack/chrome/flags.py |
103 inputs=["init/StaticPrefList.yaml"] |
69 +++ firefox-115.0/python/mozbuild/mozpack/chrome/flags.py |
104 ) |
70 @@ -234,6 +234,7 @@ class Flags(OrderedDict): |
105 diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py |
|
106 --- a/python/mozbuild/mozpack/chrome/flags.py |
|
107 +++ b/python/mozbuild/mozpack/chrome/flags.py |
|
108 @@ -229,16 +229,17 @@ class Flags(OrderedDict): |
|
109 "os": StringFlag, |
|
110 "osversion": VersionFlag, |
|
111 "abi": StringFlag, |
|
112 "platform": Flag, |
|
113 "xpcnativewrappers": Flag, |
|
114 "tablet": Flag, |
71 "tablet": Flag, |
115 "process": StringFlag, |
72 "process": StringFlag, |
116 "backgroundtask": StringFlag, |
73 "backgroundtask": StringFlag, |
117 + "desktop": StringFlag, |
74 + "desktop": StringFlag, |
118 } |
75 } |
119 RE = re.compile(r"([!<>=]+)") |
76 RE = re.compile(r"([!<>=]+)") |
120 |
77 |
121 def __init__(self, *flags): |
78 Index: firefox-115.0/python/mozbuild/mozpack/chrome/manifest.py |
122 """ |
79 =================================================================== |
123 Initialize a set of flags given in string form. |
80 --- firefox-115.0.orig/python/mozbuild/mozpack/chrome/manifest.py |
124 flags = Flags('contentaccessible=yes', 'appversion>=3.5') |
81 +++ firefox-115.0/python/mozbuild/mozpack/chrome/manifest.py |
125 """ |
82 @@ -43,6 +43,7 @@ class ManifestEntry(object): |
126 diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py |
|
127 --- a/python/mozbuild/mozpack/chrome/manifest.py |
|
128 +++ b/python/mozbuild/mozpack/chrome/manifest.py |
|
129 @@ -38,16 +38,17 @@ class ManifestEntry(object): |
|
130 "os", |
|
131 "osversion", |
|
132 "abi", |
|
133 "xpcnativewrappers", |
|
134 "tablet", |
|
135 "process", |
83 "process", |
136 "contentaccessible", |
84 "contentaccessible", |
137 "backgroundtask", |
85 "backgroundtask", |
138 + "desktop", |
86 + "desktop", |
139 ] |
87 ] |
140 |
88 |
141 def __init__(self, base, *flags): |
89 def __init__(self, base, *flags): |
142 """ |
90 Index: firefox-115.0/toolkit/components/downloads/moz.build |
143 Initialize a manifest entry with the given base path and flags. |
91 =================================================================== |
144 """ |
92 --- firefox-115.0.orig/toolkit/components/downloads/moz.build |
145 self.base = base |
93 +++ firefox-115.0/toolkit/components/downloads/moz.build |
146 self.flags = Flags(*flags) |
94 @@ -51,5 +51,9 @@ if CONFIG["MOZ_PLACES"]: |
147 diff --git a/toolkit/components/downloads/moz.build b/toolkit/components/downloads/moz.build |
|
148 --- a/toolkit/components/downloads/moz.build |
|
149 +++ b/toolkit/components/downloads/moz.build |
|
150 @@ -46,10 +46,14 @@ XPCOM_MANIFESTS += [ |
|
151 |
|
152 if CONFIG["MOZ_PLACES"]: |
|
153 EXTRA_JS_MODULES += [ |
|
154 "DownloadHistory.sys.mjs", |
|
155 ] |
|
156 |
95 |
157 FINAL_LIBRARY = "xul" |
96 FINAL_LIBRARY = "xul" |
158 |
97 |
159 +LOCAL_INCLUDES += [ |
98 +LOCAL_INCLUDES += [ |
160 + '/toolkit/xre' |
99 + '/toolkit/xre' |
161 +] |
100 +] |
162 + |
101 + |
163 with Files("**"): |
102 with Files("**"): |
164 BUG_COMPONENT = ("Toolkit", "Downloads API") |
103 BUG_COMPONENT = ("Toolkit", "Downloads API") |
165 diff --git a/toolkit/mozapps/downloads/HelperAppDlg.jsm b/toolkit/mozapps/downloads/HelperAppDlg.jsm |
104 Index: firefox-115.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs |
166 --- a/toolkit/mozapps/downloads/HelperAppDlg.jsm |
105 =================================================================== |
167 +++ b/toolkit/mozapps/downloads/HelperAppDlg.jsm |
106 --- firefox-115.0.orig/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs |
168 @@ -1250,36 +1250,66 @@ nsUnknownContentTypeDialog.prototype = { |
107 +++ firefox-115.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs |
169 params.handlerApp && |
108 @@ -1246,26 +1246,56 @@ nsUnknownContentTypeDialog.prototype = { |
170 params.handlerApp.executable && |
|
171 params.handlerApp.executable.isFile() |
|
172 ) { |
|
173 // Remember the file they chose to run. |
|
174 this.chosenApp = params.handlerApp; |
109 this.chosenApp = params.handlerApp; |
175 } |
110 } |
176 } else if ("@mozilla.org/applicationchooser;1" in Cc) { |
111 } else if ("@mozilla.org/applicationchooser;1" in Cc) { |
177 - var nsIApplicationChooser = Ci.nsIApplicationChooser; |
112 - var nsIApplicationChooser = Ci.nsIApplicationChooser; |
178 - var appChooser = Cc["@mozilla.org/applicationchooser;1"].createInstance( |
113 - var appChooser = Cc["@mozilla.org/applicationchooser;1"].createInstance( |
245 + return; |
180 + return; |
246 + } |
181 + } |
247 } else { |
182 } else { |
248 var nsIFilePicker = Ci.nsIFilePicker; |
183 var nsIFilePicker = Ci.nsIFilePicker; |
249 var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); |
184 var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); |
250 fp.init( |
185 Index: firefox-115.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
251 this.mDialog, |
186 =================================================================== |
252 this.dialogElement("strings").getString("chooseAppFilePickerTitle"), |
187 --- firefox-115.0.orig/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
253 nsIFilePicker.modeOpen |
188 +++ firefox-115.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
254 ); |
189 @@ -16,6 +16,8 @@ |
255 diff --git a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
|
256 --- a/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
|
257 +++ b/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp |
|
258 @@ -11,16 +11,18 @@ |
|
259 #include "prenv.h" |
|
260 #include "nsInterfaceHashtable.h" |
|
261 #include "nsHashtablesFwd.h" |
|
262 #include "nsHashKeys.h" |
|
263 #include "nsNetUtil.h" |
|
264 #include "nsISupportsPrimitives.h" |
190 #include "nsISupportsPrimitives.h" |
265 #include "nsIGSettingsService.h" |
191 #include "nsIGSettingsService.h" |
266 #include "nsReadableUtils.h" |
192 #include "nsReadableUtils.h" |
267 +#include "nsPrintfCString.h" |
193 +#include "nsPrintfCString.h" |
268 +#include "nsKDEUtils.h" |
194 +#include "nsKDEUtils.h" |
269 |
195 |
270 using namespace mozilla; |
196 using namespace mozilla; |
271 |
197 |
272 class nsUnixSystemProxySettings final : public nsISystemProxySettings { |
198 @@ -39,6 +41,8 @@ class nsUnixSystemProxySettings final : |
273 public: |
|
274 NS_DECL_ISUPPORTS |
|
275 NS_DECL_NSISYSTEMPROXYSETTINGS |
|
276 |
|
277 @@ -34,16 +36,18 @@ class nsUnixSystemProxySettings final : |
|
278 nsCOMPtr<nsIGSettingsCollection> mProxySettings; |
|
279 nsInterfaceHashtable<nsCStringHashKey, nsIGSettingsCollection> |
|
280 mSchemeProxySettings; |
|
281 nsresult GetProxyFromGSettings(const nsACString& aScheme, |
|
282 const nsACString& aHost, int32_t aPort, |
|
283 nsACString& aResult); |
199 nsACString& aResult); |
284 nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, |
200 nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, |
285 nsACString& aResult); |
201 nsACString& aResult); |
286 + nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, |
202 + nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, |
287 + PRInt32 aPort, nsACString& aResult); |
203 + PRInt32 aPort, nsACString& aResult); |
288 }; |
204 }; |
289 |
205 |
290 NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings) |
206 NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings) |
291 |
207 @@ -396,6 +400,9 @@ nsresult nsUnixSystemProxySettings::GetP |
292 NS_IMETHODIMP |
|
293 nsUnixSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) { |
|
294 // dbus prevents us from being threadsafe, but this routine should not block |
|
295 // anyhow |
|
296 @@ -392,21 +396,50 @@ nsresult nsUnixSystemProxySettings::GetP |
|
297 return NS_OK; |
|
298 } |
|
299 |
|
300 nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString& aSpec, |
|
301 const nsACString& aScheme, |
|
302 const nsACString& aHost, |
208 const nsACString& aHost, |
303 const int32_t aPort, |
209 const int32_t aPort, |
304 nsACString& aResult) { |
210 nsACString& aResult) { |
305 + if (nsKDEUtils::kdeSupport()) |
211 + if (nsKDEUtils::kdeSupport()) |
306 + return GetProxyFromKDE(aScheme, aHost, aPort, aResult); |
212 + return GetProxyFromKDE(aScheme, aHost, aPort, aResult); |
307 + |
213 + |
308 if (mProxySettings) { |
214 if (mProxySettings) { |
309 nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); |
215 nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); |
310 if (NS_SUCCEEDED(rv)) return rv; |
216 if (NS_SUCCEEDED(rv)) return rv; |
311 } |
217 @@ -404,6 +411,28 @@ nsresult nsUnixSystemProxySettings::GetP |
312 |
|
313 return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); |
218 return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); |
314 } |
219 } |
315 |
220 |
316 +nsresult |
221 +nsresult nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme, |
317 +nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme, |
222 + const nsACString& aHost, |
318 + const nsACString& aHost, |
223 + PRInt32 aPort, |
319 + PRInt32 aPort, |
224 + nsACString& aResult) { |
320 + nsACString& aResult) |
|
321 +{ |
|
322 + nsAutoCString url; |
225 + nsAutoCString url; |
323 + url = aScheme; |
226 + url = aScheme; |
324 + url += "://"; |
227 + url += "://"; |
325 + url += aHost; |
228 + url += aHost; |
326 + if( aPort >= 0 ) |
229 + if (aPort >= 0) { |
327 + { |
|
328 + url += ":"; |
230 + url += ":"; |
329 + url += nsPrintfCString("%d", aPort); |
231 + url += nsPrintfCString("%d", aPort); |
330 + } |
232 + } |
331 + nsTArray<nsCString> command; |
233 + nsTArray<nsCString> command; |
332 + command.AppendElement( "GETPROXY"_ns ); |
234 + command.AppendElement("GETPROXY"_ns); |
333 + command.AppendElement( url ); |
235 + command.AppendElement(url); |
334 + nsTArray<nsCString> result; |
236 + nsTArray<nsCString> result; |
335 + if( !nsKDEUtils::command( command, &result ) || result.Length() != 1 ) |
237 + if (!nsKDEUtils::command(command, &result) || result.Length() != 1) |
336 + return NS_ERROR_FAILURE; |
238 + return NS_ERROR_FAILURE; |
337 + aResult = result[0]; |
239 + aResult = result[0]; |
338 + return NS_OK; |
240 + return NS_OK; |
339 +} |
241 +} |
340 + |
242 + |
341 + |
|
342 NS_IMPL_COMPONENT_FACTORY(nsUnixSystemProxySettings) { |
243 NS_IMPL_COMPONENT_FACTORY(nsUnixSystemProxySettings) { |
343 auto result = MakeRefPtr<nsUnixSystemProxySettings>(); |
244 auto result = MakeRefPtr<nsUnixSystemProxySettings>(); |
344 result->Init(); |
245 result->Init(); |
345 return result.forget().downcast<nsISupports>(); |
246 Index: firefox-115.0/toolkit/xre/moz.build |
346 } |
247 =================================================================== |
347 diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build |
248 --- firefox-115.0.orig/toolkit/xre/moz.build |
348 --- a/toolkit/xre/moz.build |
249 +++ firefox-115.0/toolkit/xre/moz.build |
349 +++ b/toolkit/xre/moz.build |
250 @@ -96,7 +96,9 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "ui |
350 @@ -91,17 +91,19 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "co |
|
351 "../components/printingui", |
|
352 ] |
|
353 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "uikit": |
|
354 UNIFIED_SOURCES += [ |
|
355 "nsNativeAppSupportDefault.cpp", |
|
356 "UIKitDirProvider.mm", |
251 "UIKitDirProvider.mm", |
357 ] |
252 ] |
358 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
253 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
359 + EXPORTS += ['nsKDEUtils.h'] |
254 + EXPORTS += ['nsKDEUtils.h'] |
360 UNIFIED_SOURCES += [ |
255 UNIFIED_SOURCES += [ |
361 + "nsKDEUtils.cpp", |
256 + "nsKDEUtils.cpp", |
362 "nsNativeAppSupportUnix.cpp", |
257 "nsNativeAppSupportUnix.cpp", |
363 ] |
258 ] |
364 CXXFLAGS += CONFIG["MOZ_X11_SM_CFLAGS"] |
259 CXXFLAGS += CONFIG["MOZ_X11_SM_CFLAGS"] |
365 else: |
260 Index: firefox-115.0/toolkit/xre/nsKDEUtils.cpp |
366 UNIFIED_SOURCES += [ |
261 =================================================================== |
367 "nsNativeAppSupportDefault.cpp", |
|
368 ] |
|
369 |
|
370 diff --git a/toolkit/xre/nsKDEUtils.cpp b/toolkit/xre/nsKDEUtils.cpp |
|
371 new file mode 100644 |
|
372 --- /dev/null |
262 --- /dev/null |
373 +++ b/toolkit/xre/nsKDEUtils.cpp |
263 +++ firefox-115.0/toolkit/xre/nsKDEUtils.cpp |
374 @@ -0,0 +1,321 @@ |
264 @@ -0,0 +1,286 @@ |
375 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
265 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
376 +/* This Source Code Form is subject to the terms of the Mozilla Public |
266 +/* This Source Code Form is subject to the terms of the Mozilla Public |
377 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
267 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
378 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
268 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
379 + |
269 + |
393 +#include <unistd.h> |
283 +#include <unistd.h> |
394 +#include <X11/Xlib.h> |
284 +#include <X11/Xlib.h> |
395 +// copied from X11/X.h as a hack since for an unknown |
285 +// copied from X11/X.h as a hack since for an unknown |
396 +// reason it's not picked up from X11/X.h |
286 +// reason it's not picked up from X11/X.h |
397 +#ifndef None |
287 +#ifndef None |
398 +#define None 0L /* universal null resource or null atom */ |
288 +# define None 0L /* universal null resource or null atom */ |
399 +#endif |
289 +#endif |
400 + |
290 + |
401 +//#define DEBUG_KDE |
291 +// #define DEBUG_KDE |
402 +#ifdef DEBUG_KDE |
292 +#ifdef DEBUG_KDE |
403 +#define KMOZILLAHELPER "kmozillahelper" |
293 +# define KMOZILLAHELPER "kmozillahelper" |
404 +#else |
294 +#else |
405 +// not need for lib64, it's a binary |
295 +// not need for lib64, it's a binary |
406 +#define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper" |
296 +# define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper" |
407 +#endif |
297 +#endif |
408 + |
298 + |
409 +#define KMOZILLAHELPER_VERSION 6 |
299 +#define KMOZILLAHELPER_VERSION 6 |
410 +#define MAKE_STR2( n ) #n |
300 +#define MAKE_STR2(n) #n |
411 +#define MAKE_STR( n ) MAKE_STR2( n ) |
301 +#define MAKE_STR(n) MAKE_STR2(n) |
412 + |
302 + |
413 +static bool getKdeSession() |
303 +static bool getKdeSession() { |
414 +{ |
304 + if (PR_GetEnv("KDE_FULL_SESSION")) { |
415 + if (PR_GetEnv("KDE_FULL_SESSION")) |
305 + return true; |
416 + { |
306 + } |
417 + return true; |
307 + return false; |
418 + } |
308 +} |
419 + return false; |
309 + |
420 +} |
310 +static bool getKdeSupport() { |
421 + |
311 + nsTArray<nsCString> command; |
422 +static bool getKdeSupport() |
312 + command.AppendElement("CHECK"_ns); |
423 + { |
313 + command.AppendElement("KMOZILLAHELPER_VERSION"_ns); |
424 + nsTArray<nsCString> command; |
314 + bool kde = nsKDEUtils::command(command); |
425 + command.AppendElement( "CHECK"_ns ); |
|
426 + command.AppendElement( "KMOZILLAHELPER_VERSION"_ns ); |
|
427 + bool kde = nsKDEUtils::command( command ); |
|
428 +#ifdef DEBUG_KDE |
315 +#ifdef DEBUG_KDE |
429 + fprintf( stderr, "KDE RUNNING %d\n", kde ); |
316 + fprintf(stderr, "KDE RUNNING %d\n", kde); |
430 +#endif |
317 +#endif |
431 + return kde; |
318 + return kde; |
432 + } |
319 +} |
433 + |
320 + |
434 +nsKDEUtils::nsKDEUtils() |
321 +nsKDEUtils::nsKDEUtils() : commandFile(NULL), replyFile(NULL) {} |
435 + : commandFile( NULL ) |
322 + |
436 + , replyFile( NULL ) |
323 +nsKDEUtils::~nsKDEUtils() { |
437 + { |
324 + // closeHelper(); not actually useful, exiting will close the fd too |
438 + } |
325 +} |
439 + |
326 + |
440 +nsKDEUtils::~nsKDEUtils() |
327 +nsKDEUtils* nsKDEUtils::self() { |
441 + { |
328 + static nsKDEUtils s; |
442 +// closeHelper(); not actually useful, exiting will close the fd too |
329 + return &s; |
443 + } |
330 +} |
444 + |
|
445 +nsKDEUtils* nsKDEUtils::self() |
|
446 + { |
|
447 + static nsKDEUtils s; |
|
448 + return &s; |
|
449 + } |
|
450 + |
331 + |
451 +static bool helperRunning = false; |
332 +static bool helperRunning = false; |
452 +static bool helperFailed = false; |
333 +static bool helperFailed = false; |
453 + |
334 + |
454 +bool nsKDEUtils::kdeSession() |
335 +bool nsKDEUtils::kdeSession() { |
|
336 + static bool session = getKdeSession(); |
|
337 + return session; |
|
338 +} |
|
339 + |
|
340 +bool nsKDEUtils::kdeSupport() { |
|
341 + static bool support = kdeSession() && getKdeSupport(); |
|
342 + return support && helperRunning; |
|
343 +} |
|
344 + |
|
345 +struct nsKDECommandData { |
|
346 + FILE* file; |
|
347 + nsTArray<nsCString>* output; |
|
348 + GMainLoop* loop; |
|
349 + bool success; |
|
350 +}; |
|
351 + |
|
352 +static gboolean kdeReadFunc(GIOChannel*, GIOCondition, gpointer data) { |
|
353 + nsKDECommandData* p = static_cast<nsKDECommandData*>(data); |
|
354 + char buf[8192]; // TODO big enough |
|
355 + bool command_done = false; |
|
356 + bool command_failed = false; |
|
357 + while (!command_done && !command_failed && |
|
358 + fgets(buf, 8192, p->file) != |
|
359 + NULL) { // TODO what if the kernel splits a line into two chunks? |
|
360 + // #ifdef DEBUG_KDE |
|
361 + // fprintf( stderr, "READ: %s %d\n", buf, feof( p->file )); |
|
362 + // #endif |
|
363 + if (char* eol = strchr(buf, '\n')) *eol = '\0'; |
|
364 + command_done = (strcmp(buf, "\\1") == 0); |
|
365 + command_failed = (strcmp(buf, "\\0") == 0); |
|
366 + nsAutoCString line(buf); |
|
367 + line.ReplaceSubstring("\\n", "\n"); |
|
368 + line.ReplaceSubstring( |
|
369 + "\\" |
|
370 + "\\", |
|
371 + "\\"); // \\ -> \ , i.e. unescape |
|
372 + if (p->output && !(command_done || command_failed)) |
|
373 + p->output->AppendElement(nsCString(buf)); // TODO utf8? |
|
374 + } |
|
375 + bool quit = false; |
|
376 + if (feof(p->file) || command_failed) { |
|
377 + quit = true; |
|
378 + p->success = false; |
|
379 + } |
|
380 + if (command_done) { // reading one reply finished |
|
381 + quit = true; |
|
382 + p->success = true; |
|
383 + } |
|
384 + if (quit) { |
|
385 + if (p->loop) g_main_loop_quit(p->loop); |
|
386 + return FALSE; |
|
387 + } |
|
388 + return TRUE; |
|
389 +} |
|
390 + |
|
391 +bool nsKDEUtils::command(const nsTArray<nsCString>& command, |
|
392 + nsTArray<nsCString>* output) { |
|
393 + return self()->internalCommand(command, NULL, false, output); |
|
394 +} |
|
395 + |
|
396 +bool nsKDEUtils::command(nsIArray* command, nsIArray** output) { |
|
397 + nsTArray<nsCString> in; |
|
398 + PRUint32 length; |
|
399 + command->GetLength(&length); |
|
400 + for (PRUint32 i = 0; i < length; i++) { |
|
401 + nsCOMPtr<nsISupportsCString> str = do_QueryElementAt(command, i); |
|
402 + if (str) { |
|
403 + nsAutoCString s; |
|
404 + str->GetData(s); |
|
405 + in.AppendElement(s); |
|
406 + } |
|
407 + } |
|
408 + |
|
409 + nsTArray<nsCString> out; |
|
410 + bool ret = self()->internalCommand(in, NULL, false, &out); |
|
411 + |
|
412 + if (!output) return ret; |
|
413 + |
|
414 + nsCOMPtr<nsIMutableArray> result = do_CreateInstance(NS_ARRAY_CONTRACTID); |
|
415 + if (!result) return false; |
|
416 + |
|
417 + for (PRUint32 i = 0; i < out.Length(); i++) { |
|
418 + nsCOMPtr<nsISupportsCString> rstr = |
|
419 + do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID); |
|
420 + if (!rstr) return false; |
|
421 + |
|
422 + rstr->SetData(out[i]); |
|
423 + result->AppendElement(rstr); |
|
424 + } |
|
425 + |
|
426 + NS_ADDREF(*output = result); |
|
427 + return ret; |
|
428 +} |
|
429 + |
|
430 +bool nsKDEUtils::commandBlockUi(const nsTArray<nsCString>& command, |
|
431 + GtkWindow* parent, |
|
432 + nsTArray<nsCString>* output) { |
|
433 + return self()->internalCommand(command, parent, true, output); |
|
434 +} |
|
435 + |
|
436 +bool nsKDEUtils::internalCommand(const nsTArray<nsCString>& command, |
|
437 + GtkWindow* parent, bool blockUi, |
|
438 + nsTArray<nsCString>* output) { |
|
439 + if (!startHelper()) return false; |
|
440 + feedCommand(command); |
|
441 + // do not store the data in 'this' but in extra structure, just in case there |
|
442 + // is reentrancy (can there be? the event loop is re-entered) |
|
443 + nsKDECommandData data; |
|
444 + data.file = replyFile; |
|
445 + data.output = output; |
|
446 + data.success = false; |
|
447 + if (blockUi) { |
|
448 + data.loop = g_main_loop_new(NULL, FALSE); |
|
449 + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
|
450 + if (parent && gtk_window_get_group(parent)) |
|
451 + gtk_window_group_add_window(gtk_window_get_group(parent), |
|
452 + GTK_WINDOW(window)); |
|
453 + gtk_widget_realize(window); |
|
454 + gtk_widget_set_sensitive(window, TRUE); |
|
455 + gtk_grab_add(window); |
|
456 + GIOChannel* channel = g_io_channel_unix_new(fileno(data.file)); |
|
457 + g_io_add_watch(channel, |
|
458 + static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP), |
|
459 + kdeReadFunc, &data); |
|
460 + g_io_channel_unref(channel); |
|
461 + g_main_loop_run(data.loop); |
|
462 + g_main_loop_unref(data.loop); |
|
463 + gtk_grab_remove(window); |
|
464 + gtk_widget_destroy(window); |
|
465 + } else { |
|
466 + data.loop = NULL; |
|
467 + while (kdeReadFunc(NULL, static_cast<GIOCondition>(0), &data)) |
|
468 + ; |
|
469 + } |
|
470 + return data.success; |
|
471 +} |
|
472 + |
|
473 +bool nsKDEUtils::startHelper() { |
|
474 + if (helperRunning) return true; |
|
475 + if (helperFailed) return false; |
|
476 + helperFailed = true; |
|
477 + int fdcommand[2]; |
|
478 + int fdreply[2]; |
|
479 + if (pipe(fdcommand) < 0) return false; |
|
480 + if (pipe(fdreply) < 0) { |
|
481 + close(fdcommand[0]); |
|
482 + close(fdcommand[1]); |
|
483 + return false; |
|
484 + } |
|
485 + char* args[2] = {const_cast<char*>(KMOZILLAHELPER), NULL}; |
|
486 + switch (fork()) { |
|
487 + case -1: { |
|
488 + close(fdcommand[0]); |
|
489 + close(fdcommand[1]); |
|
490 + close(fdreply[0]); |
|
491 + close(fdreply[1]); |
|
492 + return false; |
|
493 + } |
|
494 + case 0: // child |
455 + { |
495 + { |
456 + static bool session = getKdeSession(); |
496 + if (dup2(fdcommand[0], STDIN_FILENO) < 0) _exit(1); |
457 + return session; |
497 + if (dup2(fdreply[1], STDOUT_FILENO) < 0) _exit(1); |
|
498 + int maxfd = 1024; // close all other fds |
|
499 + struct rlimit rl; |
|
500 + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) maxfd = rl.rlim_max; |
|
501 + for (int i = 3; i < maxfd; ++i) close(i); |
|
502 +#ifdef DEBUG_KDE |
|
503 + execvp(KMOZILLAHELPER, args); |
|
504 +#else |
|
505 + execv(KMOZILLAHELPER, args); |
|
506 +#endif |
|
507 + _exit(1); // failed |
458 + } |
508 + } |
459 + |
509 + default: // parent |
460 +bool nsKDEUtils::kdeSupport() |
|
461 + { |
510 + { |
462 + static bool support = kdeSession() && getKdeSupport(); |
511 + commandFile = fdopen(fdcommand[1], "w"); |
463 + return support && helperRunning; |
512 + replyFile = fdopen(fdreply[0], "r"); |
|
513 + close(fdcommand[0]); |
|
514 + close(fdreply[1]); |
|
515 + if (commandFile == NULL || replyFile == NULL) { |
|
516 + closeHelper(); |
|
517 + return false; |
|
518 + } |
|
519 + // ok, helper ready, getKdeRunning() will check if it works |
464 + } |
520 + } |
465 + |
521 + } |
466 +struct nsKDECommandData |
522 + helperFailed = false; |
467 + { |
523 + helperRunning = true; |
468 + FILE* file; |
524 + return true; |
469 + nsTArray<nsCString>* output; |
525 +} |
470 + GMainLoop* loop; |
526 + |
471 + bool success; |
527 +void nsKDEUtils::closeHelper() { |
472 + }; |
528 + if (commandFile != NULL) |
473 + |
529 + fclose(commandFile); // this will also make the helper quit |
474 +static gboolean kdeReadFunc( GIOChannel*, GIOCondition, gpointer data ) |
530 + if (replyFile != NULL) fclose(replyFile); |
475 + { |
531 + helperRunning = false; |
476 + nsKDECommandData* p = static_cast< nsKDECommandData* >( data ); |
532 +} |
477 + char buf[ 8192 ]; // TODO big enough |
533 + |
478 + bool command_done = false; |
534 +void nsKDEUtils::feedCommand(const nsTArray<nsCString>& command) { |
479 + bool command_failed = false; |
535 + for (int i = 0; i < command.Length(); ++i) { |
480 + while( !command_done && !command_failed && fgets( buf, 8192, p->file ) != NULL ) |
536 + nsCString line = command[i]; |
481 + { // TODO what if the kernel splits a line into two chunks? |
537 + line.ReplaceSubstring("\\", |
482 +//#ifdef DEBUG_KDE |
538 + "\\" |
483 +// fprintf( stderr, "READ: %s %d\n", buf, feof( p->file )); |
539 + "\\"); // \ -> \\ , i.e. escape |
484 +//#endif |
540 + line.ReplaceSubstring("\n", "\\n"); |
485 + if( char* eol = strchr( buf, '\n' )) |
|
486 + *eol = '\0'; |
|
487 + command_done = ( strcmp( buf, "\\1" ) == 0 ); |
|
488 + command_failed = ( strcmp( buf, "\\0" ) == 0 ); |
|
489 + nsAutoCString line( buf ); |
|
490 + line.ReplaceSubstring( "\\n", "\n" ); |
|
491 + line.ReplaceSubstring( "\\" "\\", "\\" ); // \\ -> \ , i.e. unescape |
|
492 + if( p->output && !( command_done || command_failed )) |
|
493 + p->output->AppendElement( nsCString( buf )); // TODO utf8? |
|
494 + } |
|
495 + bool quit = false; |
|
496 + if( feof( p->file ) || command_failed ) |
|
497 + { |
|
498 + quit = true; |
|
499 + p->success = false; |
|
500 + } |
|
501 + if( command_done ) |
|
502 + { // reading one reply finished |
|
503 + quit = true; |
|
504 + p->success = true; |
|
505 + } |
|
506 + if( quit ) |
|
507 + { |
|
508 + if( p->loop ) |
|
509 + g_main_loop_quit( p->loop ); |
|
510 + return FALSE; |
|
511 + } |
|
512 + return TRUE; |
|
513 + } |
|
514 + |
|
515 +bool nsKDEUtils::command( const nsTArray<nsCString>& command, nsTArray<nsCString>* output ) |
|
516 + { |
|
517 + return self()->internalCommand( command, NULL, false, output ); |
|
518 + } |
|
519 + |
|
520 +bool nsKDEUtils::command( nsIArray* command, nsIArray** output) |
|
521 + { |
|
522 + nsTArray<nsCString> in; |
|
523 + PRUint32 length; |
|
524 + command->GetLength( &length ); |
|
525 + for ( PRUint32 i = 0; i < length; i++ ) |
|
526 + { |
|
527 + nsCOMPtr<nsISupportsCString> str = do_QueryElementAt( command, i ); |
|
528 + if( str ) |
|
529 + { |
|
530 + nsAutoCString s; |
|
531 + str->GetData( s ); |
|
532 + in.AppendElement( s ); |
|
533 + } |
|
534 + } |
|
535 + |
|
536 + nsTArray<nsCString> out; |
|
537 + bool ret = self()->internalCommand( in, NULL, false, &out ); |
|
538 + |
|
539 + if ( !output ) return ret; |
|
540 + |
|
541 + nsCOMPtr<nsIMutableArray> result = do_CreateInstance( NS_ARRAY_CONTRACTID ); |
|
542 + if ( !result ) return false; |
|
543 + |
|
544 + for ( PRUint32 i = 0; i < out.Length(); i++ ) |
|
545 + { |
|
546 + nsCOMPtr<nsISupportsCString> rstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); |
|
547 + if ( !rstr ) return false; |
|
548 + |
|
549 + rstr->SetData( out[i] ); |
|
550 + result->AppendElement( rstr ); |
|
551 + } |
|
552 + |
|
553 + NS_ADDREF( *output = result); |
|
554 + return ret; |
|
555 + } |
|
556 + |
|
557 + |
|
558 +bool nsKDEUtils::commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output ) |
|
559 + { |
|
560 + return self()->internalCommand( command, parent, true, output ); |
|
561 + } |
|
562 + |
|
563 +bool nsKDEUtils::internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool blockUi, |
|
564 + nsTArray<nsCString>* output ) |
|
565 + { |
|
566 + if( !startHelper()) |
|
567 + return false; |
|
568 + feedCommand( command ); |
|
569 + // do not store the data in 'this' but in extra structure, just in case there |
|
570 + // is reentrancy (can there be? the event loop is re-entered) |
|
571 + nsKDECommandData data; |
|
572 + data.file = replyFile; |
|
573 + data.output = output; |
|
574 + data.success = false; |
|
575 + if( blockUi ) |
|
576 + { |
|
577 + data.loop = g_main_loop_new( NULL, FALSE ); |
|
578 + GtkWidget* window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); |
|
579 + if( parent && gtk_window_get_group(parent) ) |
|
580 + gtk_window_group_add_window( gtk_window_get_group(parent), GTK_WINDOW( window )); |
|
581 + gtk_widget_realize( window ); |
|
582 + gtk_widget_set_sensitive( window, TRUE ); |
|
583 + gtk_grab_add( window ); |
|
584 + GIOChannel* channel = g_io_channel_unix_new( fileno( data.file )); |
|
585 + g_io_add_watch( channel, static_cast< GIOCondition >( G_IO_IN | G_IO_ERR | G_IO_HUP ), kdeReadFunc, &data ); |
|
586 + g_io_channel_unref( channel ); |
|
587 + g_main_loop_run( data.loop ); |
|
588 + g_main_loop_unref( data.loop ); |
|
589 + gtk_grab_remove( window ); |
|
590 + gtk_widget_destroy( window ); |
|
591 + } |
|
592 + else |
|
593 + { |
|
594 + data.loop = NULL; |
|
595 + while( kdeReadFunc( NULL, static_cast< GIOCondition >( 0 ), &data )) |
|
596 + ; |
|
597 + } |
|
598 + return data.success; |
|
599 + } |
|
600 + |
|
601 +bool nsKDEUtils::startHelper() |
|
602 + { |
|
603 + if( helperRunning ) |
|
604 + return true; |
|
605 + if( helperFailed ) |
|
606 + return false; |
|
607 + helperFailed = true; |
|
608 + int fdcommand[ 2 ]; |
|
609 + int fdreply[ 2 ]; |
|
610 + if( pipe( fdcommand ) < 0 ) |
|
611 + return false; |
|
612 + if( pipe( fdreply ) < 0 ) |
|
613 + { |
|
614 + close( fdcommand[ 0 ] ); |
|
615 + close( fdcommand[ 1 ] ); |
|
616 + return false; |
|
617 + } |
|
618 + char* args[ 2 ] = { const_cast< char* >( KMOZILLAHELPER ), NULL }; |
|
619 + switch( fork()) |
|
620 + { |
|
621 + case -1: |
|
622 + { |
|
623 + close( fdcommand[ 0 ] ); |
|
624 + close( fdcommand[ 1 ] ); |
|
625 + close( fdreply[ 0 ] ); |
|
626 + close( fdreply[ 1 ] ); |
|
627 + return false; |
|
628 + } |
|
629 + case 0: // child |
|
630 + { |
|
631 + if( dup2( fdcommand[ 0 ], STDIN_FILENO ) < 0 ) |
|
632 + _exit( 1 ); |
|
633 + if( dup2( fdreply[ 1 ], STDOUT_FILENO ) < 0 ) |
|
634 + _exit( 1 ); |
|
635 + int maxfd = 1024; // close all other fds |
|
636 + struct rlimit rl; |
|
637 + if( getrlimit( RLIMIT_NOFILE, &rl ) == 0 ) |
|
638 + maxfd = rl.rlim_max; |
|
639 + for( int i = 3; |
|
640 + i < maxfd; |
|
641 + ++i ) |
|
642 + close( i ); |
|
643 +#ifdef DEBUG_KDE |
541 +#ifdef DEBUG_KDE |
644 + execvp( KMOZILLAHELPER, args ); |
542 + fprintf(stderr, "COMM: %s\n", line.get()); |
645 +#else |
|
646 + execv( KMOZILLAHELPER, args ); |
|
647 +#endif |
543 +#endif |
648 + _exit( 1 ); // failed |
544 + fputs(line.get(), commandFile); |
649 + } |
545 + fputs("\n", commandFile); |
650 + default: // parent |
546 + } |
651 + { |
547 + fputs("\\E\n", |
652 + commandFile = fdopen( fdcommand[ 1 ], "w" ); |
548 + commandFile); // done as \E, so it cannot happen in normal data |
653 + replyFile = fdopen( fdreply[ 0 ], "r" ); |
549 + fflush(commandFile); |
654 + close( fdcommand[ 0 ] ); |
550 +} |
655 + close( fdreply[ 1 ] ); |
551 Index: firefox-115.0/toolkit/xre/nsKDEUtils.h |
656 + if( commandFile == NULL || replyFile == NULL ) |
552 =================================================================== |
657 + { |
|
658 + closeHelper(); |
|
659 + return false; |
|
660 + } |
|
661 + // ok, helper ready, getKdeRunning() will check if it works |
|
662 + } |
|
663 + } |
|
664 + helperFailed = false; |
|
665 + helperRunning = true; |
|
666 + return true; |
|
667 + } |
|
668 + |
|
669 +void nsKDEUtils::closeHelper() |
|
670 + { |
|
671 + if( commandFile != NULL ) |
|
672 + fclose( commandFile ); // this will also make the helper quit |
|
673 + if( replyFile != NULL ) |
|
674 + fclose( replyFile ); |
|
675 + helperRunning = false; |
|
676 + } |
|
677 + |
|
678 +void nsKDEUtils::feedCommand( const nsTArray<nsCString>& command ) |
|
679 + { |
|
680 + for( int i = 0; |
|
681 + i < command.Length(); |
|
682 + ++i ) |
|
683 + { |
|
684 + nsCString line = command[ i ]; |
|
685 + line.ReplaceSubstring( "\\", "\\" "\\" ); // \ -> \\ , i.e. escape |
|
686 + line.ReplaceSubstring( "\n", "\\n" ); |
|
687 +#ifdef DEBUG_KDE |
|
688 + fprintf( stderr, "COMM: %s\n", line.get()); |
|
689 +#endif |
|
690 + fputs( line.get(), commandFile ); |
|
691 + fputs( "\n", commandFile ); |
|
692 + } |
|
693 + fputs( "\\E\n", commandFile ); // done as \E, so it cannot happen in normal data |
|
694 + fflush( commandFile ); |
|
695 + } |
|
696 diff --git a/toolkit/xre/nsKDEUtils.h b/toolkit/xre/nsKDEUtils.h |
|
697 new file mode 100644 |
|
698 --- /dev/null |
553 --- /dev/null |
699 +++ b/toolkit/xre/nsKDEUtils.h |
554 +++ firefox-115.0/toolkit/xre/nsKDEUtils.h |
700 @@ -0,0 +1,48 @@ |
555 @@ -0,0 +1,53 @@ |
701 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
556 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
702 +/* This Source Code Form is subject to the terms of the Mozilla Public |
557 +/* This Source Code Form is subject to the terms of the Mozilla Public |
703 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
558 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
704 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
559 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
705 + |
560 + |
712 + |
567 + |
713 +typedef struct _GtkWindow GtkWindow; |
568 +typedef struct _GtkWindow GtkWindow; |
714 + |
569 + |
715 +class nsIArray; |
570 +class nsIArray; |
716 + |
571 + |
717 +class NS_EXPORT nsKDEUtils |
572 +class NS_EXPORT nsKDEUtils { |
718 + { |
573 + public: |
719 + public: |
574 + /* Returns true if running inside a KDE session (regardless of whether there |
720 + /* Returns true if running inside a KDE session (regardless of whether there is KDE |
575 + is KDE support available for Firefox). This should be used e.g. when |
721 + support available for Firefox). This should be used e.g. when determining |
576 + determining dialog button order but not for code that requires the KDE |
722 + dialog button order but not for code that requires the KDE support. */ |
577 + support. */ |
723 + static bool kdeSession(); |
578 + static bool kdeSession(); |
724 + /* Returns true if running inside a KDE session and KDE support is available |
579 + /* Returns true if running inside a KDE session and KDE support is available |
725 + for Firefox. This should be used everywhere where the external helper is needed. */ |
580 + for Firefox. This should be used everywhere where the external helper is |
726 + static bool kdeSupport(); |
581 + needed. */ |
727 + /* Executes the given helper command, returns true if helper returned success. */ |
582 + static bool kdeSupport(); |
728 + static bool command( const nsTArray<nsCString>& command, nsTArray<nsCString>* output = NULL ); |
583 + /* Executes the given helper command, returns true if helper returned success. |
729 + static bool command( nsIArray* command, nsIArray** output = NULL ); |
584 + */ |
730 + /* Like command(), but additionally blocks the parent widget like if there was |
585 + static bool command(const nsTArray<nsCString>& command, |
731 + a modal dialog shown and enters the event loop (i.e. there are still paint updates, |
586 + nsTArray<nsCString>* output = NULL); |
732 + this is for commands that take long). */ |
587 + static bool command(nsIArray* command, nsIArray** output = NULL); |
733 + static bool commandBlockUi( const nsTArray<nsCString>& command, GtkWindow* parent, nsTArray<nsCString>* output = NULL ); |
588 + /* Like command(), but additionally blocks the parent widget like if there was |
734 + |
589 + a modal dialog shown and enters the event loop (i.e. there are still paint |
735 + private: |
590 + updates, this is for commands that take long). */ |
736 + nsKDEUtils(); |
591 + static bool commandBlockUi(const nsTArray<nsCString>& command, |
737 + ~nsKDEUtils(); |
592 + GtkWindow* parent, |
738 + static nsKDEUtils* self(); |
593 + nsTArray<nsCString>* output = NULL); |
739 + bool startHelper(); |
594 + |
740 + void closeHelper(); |
595 + private: |
741 + void feedCommand( const nsTArray<nsCString>& command ); |
596 + nsKDEUtils(); |
742 + bool internalCommand( const nsTArray<nsCString>& command, GtkWindow* parent, bool isParent, |
597 + ~nsKDEUtils(); |
743 + nsTArray<nsCString>* output ); |
598 + static nsKDEUtils* self(); |
744 + FILE* commandFile; |
599 + bool startHelper(); |
745 + FILE* replyFile; |
600 + void closeHelper(); |
746 + }; |
601 + void feedCommand(const nsTArray<nsCString>& command); |
747 + |
602 + bool internalCommand(const nsTArray<nsCString>& command, GtkWindow* parent, |
748 +#endif // nsKDEUtils |
603 + bool isParent, nsTArray<nsCString>* output); |
749 diff --git a/uriloader/exthandler/HandlerServiceParent.cpp b/uriloader/exthandler/HandlerServiceParent.cpp |
604 + FILE* commandFile; |
750 --- a/uriloader/exthandler/HandlerServiceParent.cpp |
605 + FILE* replyFile; |
751 +++ b/uriloader/exthandler/HandlerServiceParent.cpp |
606 +}; |
752 @@ -13,17 +13,17 @@ |
607 + |
753 #include "ContentHandlerService.h" |
608 +#endif // nsKDEUtils |
754 #include "nsIExternalProtocolService.h" |
609 Index: firefox-115.0/uriloader/exthandler/HandlerServiceParent.cpp |
755 #include "nsStringEnumerator.h" |
610 =================================================================== |
756 #include "nsIMutableArray.h" |
611 --- firefox-115.0.orig/uriloader/exthandler/HandlerServiceParent.cpp |
757 #include "nsCExternalHandlerService.h" |
612 +++ firefox-115.0/uriloader/exthandler/HandlerServiceParent.cpp |
|
613 @@ -18,7 +18,7 @@ |
758 #include "nsComponentManagerUtils.h" |
614 #include "nsComponentManagerUtils.h" |
759 #include "nsServiceManagerUtils.h" |
615 #include "nsServiceManagerUtils.h" |
760 #ifdef MOZ_WIDGET_GTK |
616 #ifdef MOZ_WIDGET_GTK |
761 -# include "unix/nsGNOMERegistry.h" |
617 -# include "unix/nsGNOMERegistry.h" |
762 +# include "unix/nsCommonRegistry.h" |
618 +# include "unix/nsCommonRegistry.h" |
763 #endif |
619 #endif |
764 |
620 |
765 using mozilla::dom::ContentHandlerService; |
621 using mozilla::dom::ContentHandlerService; |
766 using mozilla::dom::HandlerApp; |
622 @@ -310,8 +310,8 @@ mozilla::ipc::IPCResult HandlerServicePa |
767 using mozilla::dom::HandlerInfo; |
|
768 using mozilla::dom::RemoteHandlerApp; |
|
769 |
|
770 namespace { |
|
771 @@ -306,17 +306,17 @@ mozilla::ipc::IPCResult HandlerServicePa |
|
772 const nsACString& aProtocolScheme, bool* aHandlerExists) { |
|
773 if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) { |
|
774 *aHandlerExists = false; |
|
775 return IPC_OK(); |
|
776 } |
623 } |
777 #ifdef MOZ_WIDGET_GTK |
624 #ifdef MOZ_WIDGET_GTK |
778 // Check the GNOME registry for a protocol handler |
625 // Check the GNOME registry for a protocol handler |
779 *aHandlerExists = |
626 - *aHandlerExists = |
780 - nsGNOMERegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get()); |
627 - nsGNOMERegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get()); |
781 + nsCommonRegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get()); |
628 + *aHandlerExists = nsCommonRegistry::HandlerExists( |
|
629 + PromiseFlatCString(aProtocolScheme).get()); |
782 #else |
630 #else |
783 *aHandlerExists = false; |
631 *aHandlerExists = false; |
784 #endif |
632 #endif |
785 return IPC_OK(); |
633 Index: firefox-115.0/uriloader/exthandler/moz.build |
786 } |
634 =================================================================== |
787 |
635 --- firefox-115.0.orig/uriloader/exthandler/moz.build |
788 /* |
636 +++ firefox-115.0/uriloader/exthandler/moz.build |
789 * Check if a handler exists for the provided protocol. Check the datastore |
637 @@ -86,7 +86,9 @@ else: |
790 diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build |
|
791 --- a/uriloader/exthandler/moz.build |
|
792 +++ b/uriloader/exthandler/moz.build |
|
793 @@ -81,17 +81,19 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "ui |
|
794 else: |
|
795 # These files can't be built in unified mode because they redefine LOG. |
|
796 SOURCES += [ |
|
797 osdir + "/nsOSHelperAppService.cpp", |
|
798 ] |
|
799 |
638 |
800 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
639 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
801 UNIFIED_SOURCES += [ |
640 UNIFIED_SOURCES += [ |
802 + "unix/nsCommonRegistry.cpp", |
641 + "unix/nsCommonRegistry.cpp", |
803 "unix/nsGNOMERegistry.cpp", |
642 "unix/nsGNOMERegistry.cpp", |
804 + "unix/nsKDERegistry.cpp", |
643 + "unix/nsKDERegistry.cpp", |
805 "unix/nsMIMEInfoUnix.cpp", |
644 "unix/nsMIMEInfoUnix.cpp", |
806 ] |
645 ] |
807 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": |
646 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": |
808 UNIFIED_SOURCES += [ |
647 @@ -134,6 +136,7 @@ LOCAL_INCLUDES += [ |
809 "android/nsMIMEInfoAndroid.cpp", |
|
810 ] |
|
811 elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": |
|
812 UNIFIED_SOURCES += [ |
|
813 @@ -129,16 +131,17 @@ include("/ipc/chromium/chromium-config.m |
|
814 FINAL_LIBRARY = "xul" |
|
815 |
|
816 LOCAL_INCLUDES += [ |
|
817 "/docshell/base", |
|
818 "/dom/base", |
|
819 "/dom/ipc", |
648 "/dom/ipc", |
820 "/netwerk/base", |
649 "/netwerk/base", |
821 "/netwerk/protocol/http", |
650 "/netwerk/protocol/http", |
822 + "/toolkit/xre", |
651 + "/toolkit/xre", |
823 ] |
652 ] |
824 |
653 |
825 if CONFIG["MOZ_ENABLE_DBUS"]: |
654 if CONFIG["MOZ_ENABLE_DBUS"]: |
826 CXXFLAGS += CONFIG["MOZ_DBUS_CFLAGS"] |
655 Index: firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.cpp |
827 |
656 =================================================================== |
828 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
|
829 CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] |
|
830 CXXFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"] |
|
831 diff --git a/uriloader/exthandler/unix/nsCommonRegistry.cpp b/uriloader/exthandler/unix/nsCommonRegistry.cpp |
|
832 new file mode 100644 |
|
833 --- /dev/null |
657 --- /dev/null |
834 +++ b/uriloader/exthandler/unix/nsCommonRegistry.cpp |
658 +++ firefox-115.0/uriloader/exthandler/unix/nsCommonRegistry.cpp |
835 @@ -0,0 +1,53 @@ |
659 @@ -0,0 +1,42 @@ |
836 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
660 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
837 +/* This Source Code Form is subject to the terms of the Mozilla Public |
661 +/* This Source Code Form is subject to the terms of the Mozilla Public |
838 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
662 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
839 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
663 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
840 + |
664 + |
1105 - mimeInfo = nsGNOMERegistry::GetFromExtension(ext); |
895 - mimeInfo = nsGNOMERegistry::GetFromExtension(ext); |
1106 + mimeInfo = nsCommonRegistry::GetFromExtension(ext); |
896 + mimeInfo = nsCommonRegistry::GetFromExtension(ext); |
1107 } |
897 } |
1108 } |
898 } |
1109 if (mimeInfo) *_retval = true; |
899 if (mimeInfo) *_retval = true; |
1110 } |
900 @@ -59,6 +62,21 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi |
1111 |
|
1112 if (*_retval) return NS_OK; |
|
1113 |
|
1114 return NS_OK; |
|
1115 @@ -54,16 +57,33 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi |
|
1116 // give the GNOME answer. |
|
1117 if (GetDefaultApplication()) { |
|
1118 return nsMIMEInfoImpl::LaunchDefaultWithFile(aFile); |
|
1119 } |
|
1120 |
|
1121 nsAutoCString nativePath; |
901 nsAutoCString nativePath; |
1122 aFile->GetNativePath(nativePath); |
902 aFile->GetNativePath(nativePath); |
1123 |
903 |
1124 + if( nsKDEUtils::kdeSupport()) { |
904 + if (nsKDEUtils::kdeSupport()) { |
1125 + bool supports; |
905 + bool supports; |
1126 + if( NS_SUCCEEDED( GetHasDefaultHandler( &supports )) && supports ) { |
906 + if (NS_SUCCEEDED(GetHasDefaultHandler(&supports)) && supports) { |
1127 + nsTArray<nsCString> command; |
907 + nsTArray<nsCString> command; |
1128 + command.AppendElement( "OPEN"_ns ); |
908 + command.AppendElement("OPEN"_ns); |
1129 + command.AppendElement( nativePath ); |
909 + command.AppendElement(nativePath); |
1130 + command.AppendElement( "MIMETYPE"_ns ); |
910 + command.AppendElement("MIMETYPE"_ns); |
1131 + command.AppendElement( mSchemeOrType ); |
911 + command.AppendElement(mSchemeOrType); |
1132 + if( nsKDEUtils::command( command )) |
912 + if (nsKDEUtils::command(command)) return NS_OK; |
1133 + return NS_OK; |
|
1134 + } |
913 + } |
1135 + if (!GetDefaultApplication()) |
914 + if (!GetDefaultApplication()) return NS_ERROR_FILE_NOT_FOUND; |
1136 + return NS_ERROR_FILE_NOT_FOUND; |
|
1137 + |
915 + |
1138 + return LaunchWithIProcess(GetDefaultApplication(), nativePath); |
916 + return LaunchWithIProcess(GetDefaultApplication(), nativePath); |
1139 + } |
917 + } |
1140 + |
918 + |
1141 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
919 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
1142 if (!giovfs) { |
920 if (!giovfs) { |
1143 return NS_ERROR_FAILURE; |
921 return NS_ERROR_FAILURE; |
1144 } |
922 Index: firefox-115.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
1145 |
923 =================================================================== |
1146 // nsGIOMimeApp->Launch wants a URI string instead of local file |
924 --- firefox-115.0.orig/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
1147 nsresult rv; |
925 +++ firefox-115.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
1148 nsCOMPtr<nsIIOService> ioservice = |
926 @@ -10,7 +10,7 @@ |
1149 diff --git a/uriloader/exthandler/unix/nsOSHelperAppService.cpp b/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
|
1150 --- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
|
1151 +++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp |
|
1152 @@ -5,17 +5,17 @@ |
|
1153 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
1154 |
|
1155 #include <sys/types.h> |
|
1156 #include <sys/stat.h> |
|
1157 |
|
1158 #include "nsOSHelperAppService.h" |
927 #include "nsOSHelperAppService.h" |
1159 #include "nsMIMEInfoUnix.h" |
928 #include "nsMIMEInfoUnix.h" |
1160 #ifdef MOZ_WIDGET_GTK |
929 #ifdef MOZ_WIDGET_GTK |
1161 -# include "nsGNOMERegistry.h" |
930 -# include "nsGNOMERegistry.h" |
1162 +# include "nsCommonRegistry.h" |
931 +# include "nsCommonRegistry.h" |
1163 # ifdef MOZ_BUILD_APP_IS_BROWSER |
932 # ifdef MOZ_BUILD_APP_IS_BROWSER |
1164 # include "nsIToolkitShellService.h" |
933 # include "nsIToolkitShellService.h" |
1165 # include "nsIGNOMEShellService.h" |
934 # include "nsIGNOMEShellService.h" |
1166 # endif |
935 @@ -1106,7 +1106,7 @@ nsresult nsOSHelperAppService::OSProtoco |
1167 #endif |
|
1168 #include "nsISupports.h" |
|
1169 #include "nsString.h" |
|
1170 #include "nsReadableUtils.h" |
|
1171 @@ -1102,17 +1102,17 @@ nsresult nsOSHelperAppService::GetHandle |
|
1172 |
|
1173 nsresult nsOSHelperAppService::OSProtocolHandlerExists( |
|
1174 const char* aProtocolScheme, bool* aHandlerExists) { |
|
1175 nsresult rv = NS_OK; |
|
1176 |
|
1177 if (!XRE_IsContentProcess()) { |
936 if (!XRE_IsContentProcess()) { |
1178 #ifdef MOZ_WIDGET_GTK |
937 #ifdef MOZ_WIDGET_GTK |
1179 // Check the GNOME registry for a protocol handler |
938 // Check the GNOME registry for a protocol handler |
1180 - *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme); |
939 - *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme); |
1181 + *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme); |
940 + *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme); |
1182 #else |
941 #else |
1183 *aHandlerExists = false; |
942 *aHandlerExists = false; |
1184 #endif |
943 #endif |
1185 } else { |
944 @@ -1126,7 +1126,7 @@ nsresult nsOSHelperAppService::OSProtoco |
1186 *aHandlerExists = false; |
|
1187 nsCOMPtr<nsIHandlerService> handlerSvc = |
|
1188 do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv); |
|
1189 if (NS_SUCCEEDED(rv) && handlerSvc) { |
|
1190 @@ -1122,17 +1122,17 @@ nsresult nsOSHelperAppService::OSProtoco |
|
1191 } |
|
1192 |
|
1193 return rv; |
|
1194 } |
|
1195 |
|
1196 NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription( |
945 NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription( |
1197 const nsACString& aScheme, nsAString& _retval) { |
946 const nsACString& aScheme, nsAString& _retval) { |
1198 #ifdef MOZ_WIDGET_GTK |
947 #ifdef MOZ_WIDGET_GTK |
1199 - nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval); |
948 - nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval); |
1200 + nsCommonRegistry::GetAppDescForScheme(aScheme, _retval); |
949 + nsCommonRegistry::GetAppDescForScheme(aScheme, _retval); |
1201 return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK; |
950 return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK; |
1202 #else |
951 #else |
1203 return NS_ERROR_NOT_AVAILABLE; |
952 return NS_ERROR_NOT_AVAILABLE; |
1204 #endif |
953 @@ -1231,7 +1231,7 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel |
1205 } |
|
1206 |
|
1207 NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol( |
|
1208 const nsACString& aScheme, bool* _retval) { |
|
1209 @@ -1227,17 +1227,17 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel |
|
1210 nsresult rv = |
|
1211 LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt), majorType, |
|
1212 minorType, mime_types_description, true); |
|
1213 |
|
1214 if (NS_FAILED(rv) || majorType.IsEmpty()) { |
|
1215 #ifdef MOZ_WIDGET_GTK |
954 #ifdef MOZ_WIDGET_GTK |
1216 LOG("Looking in GNOME registry\n"); |
955 LOG("Looking in GNOME registry\n"); |
1217 RefPtr<nsMIMEInfoBase> gnomeInfo = |
956 RefPtr<nsMIMEInfoBase> gnomeInfo = |
1218 - nsGNOMERegistry::GetFromExtension(aFileExt); |
957 - nsGNOMERegistry::GetFromExtension(aFileExt); |
1219 + nsCommonRegistry::GetFromExtension(aFileExt); |
958 + nsCommonRegistry::GetFromExtension(aFileExt); |
1220 if (gnomeInfo) { |
959 if (gnomeInfo) { |
1221 LOG("Got MIMEInfo from GNOME registry\n"); |
960 LOG("Got MIMEInfo from GNOME registry\n"); |
1222 return gnomeInfo.forget(); |
961 return gnomeInfo.forget(); |
1223 } |
962 @@ -1344,7 +1344,7 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel |
1224 #endif |
|
1225 |
|
1226 rv = LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt), majorType, |
|
1227 minorType, mime_types_description, false); |
|
1228 @@ -1342,17 +1342,17 @@ already_AddRefed<nsMIMEInfoBase> nsOSHel |
|
1229 |
|
1230 // Now look up our extensions |
|
1231 nsAutoString extensions, mime_types_description; |
|
1232 LookUpExtensionsAndDescription(majorType, minorType, extensions, |
|
1233 mime_types_description); |
|
1234 |
963 |
1235 #ifdef MOZ_WIDGET_GTK |
964 #ifdef MOZ_WIDGET_GTK |
1236 if (handler.IsEmpty()) { |
965 if (handler.IsEmpty()) { |
1237 - RefPtr<nsMIMEInfoBase> gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType); |
966 - RefPtr<nsMIMEInfoBase> gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType); |
1238 + RefPtr<nsMIMEInfoBase> gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType); |
967 + RefPtr<nsMIMEInfoBase> gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType); |
1239 if (gnomeInfo) { |
968 if (gnomeInfo) { |
1240 LOG("Got MIMEInfo from GNOME registry without extensions; setting them " |
969 LOG("Got MIMEInfo from GNOME registry without extensions; setting them " |
1241 "to %s\n", |
970 "to %s\n", |
1242 NS_LossyConvertUTF16toASCII(extensions).get()); |
971 Index: firefox-115.0/widget/gtk/moz.build |
1243 |
972 =================================================================== |
1244 NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?"); |
973 --- firefox-115.0.orig/widget/gtk/moz.build |
1245 gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions)); |
974 +++ firefox-115.0/widget/gtk/moz.build |
1246 return gnomeInfo.forget(); |
975 @@ -149,6 +149,7 @@ LOCAL_INCLUDES += [ |
1247 diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build |
|
1248 --- a/widget/gtk/moz.build |
|
1249 +++ b/widget/gtk/moz.build |
|
1250 @@ -142,16 +142,17 @@ FINAL_LIBRARY = "xul" |
|
1251 |
|
1252 LOCAL_INCLUDES += [ |
|
1253 "/layout/base", |
|
1254 "/layout/forms", |
|
1255 "/layout/generic", |
|
1256 "/layout/xul", |
976 "/layout/xul", |
1257 "/other-licenses/atk-1.0", |
977 "/other-licenses/atk-1.0", |
1258 "/third_party/cups/include", |
978 "/third_party/cups/include", |
1259 + "/toolkit/xre", |
979 + "/toolkit/xre", |
1260 "/widget", |
980 "/widget", |
1261 "/widget/headless", |
981 "/widget/headless", |
1262 ] |
982 ] |
1263 |
983 Index: firefox-115.0/widget/gtk/nsFilePicker.cpp |
1264 if CONFIG["MOZ_X11"] or CONFIG["MOZ_WAYLAND"]: |
984 =================================================================== |
1265 LOCAL_INCLUDES += [ |
985 --- firefox-115.0.orig/widget/gtk/nsFilePicker.cpp |
1266 "/widget/x11", |
986 +++ firefox-115.0/widget/gtk/nsFilePicker.cpp |
1267 ] |
987 @@ -5,6 +5,7 @@ |
1268 diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp |
|
1269 --- a/widget/gtk/nsFilePicker.cpp |
|
1270 +++ b/widget/gtk/nsFilePicker.cpp |
|
1271 @@ -1,15 +1,16 @@ |
|
1272 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
1273 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
1274 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
1275 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
1276 |
988 |
1277 #include <dlfcn.h> |
989 #include <dlfcn.h> |
1278 #include <gtk/gtk.h> |
990 #include <gtk/gtk.h> |
1279 +#include <gdk/gdkx.h> |
991 +#include <gdk/gdkx.h> |
1280 #include <sys/types.h> |
992 #include <sys/types.h> |
1281 #include <sys/stat.h> |
993 #include <sys/stat.h> |
1282 #include <unistd.h> |
994 #include <unistd.h> |
1283 |
995 @@ -28,6 +29,8 @@ |
1284 #include "mozilla/Types.h" |
|
1285 #include "nsGtkUtils.h" |
|
1286 #include "nsIFileURL.h" |
|
1287 #include "nsIGIOService.h" |
|
1288 @@ -23,16 +24,18 @@ |
|
1289 #include "nsArrayEnumerator.h" |
|
1290 #include "nsEnumeratorUtils.h" |
|
1291 #include "nsNetUtil.h" |
|
1292 #include "nsReadableUtils.h" |
|
1293 #include "MozContainer.h" |
|
1294 #include "WidgetUtilsGtk.h" |
996 #include "WidgetUtilsGtk.h" |
1295 |
997 |
1296 #include "nsFilePicker.h" |
998 #include "nsFilePicker.h" |
1297 +#include "nsKDEUtils.h" |
999 +#include "nsKDEUtils.h" |
1298 +#include "nsURLHelper.h" |
1000 +#include "nsURLHelper.h" |
1299 |
1001 |
1300 #undef LOG |
1002 #undef LOG |
1301 #ifdef MOZ_LOGGING |
1003 #ifdef MOZ_LOGGING |
1302 # include "mozilla/Logging.h" |
1004 @@ -242,7 +245,8 @@ NS_IMETHODIMP |
1303 # include "nsTArray.h" |
|
1304 # include "Units.h" |
|
1305 extern mozilla::LazyLogModule gWidgetLog; |
|
1306 # define LOG(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args) |
|
1307 @@ -237,17 +240,19 @@ nsFilePicker::AppendFilters(int32_t aFil |
|
1308 mAllowURLs = !!(aFilterMask & filterAllowURLs); |
|
1309 return nsBaseFilePicker::AppendFilters(aFilterMask); |
|
1310 } |
|
1311 |
|
1312 NS_IMETHODIMP |
|
1313 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) { |
1005 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) { |
1314 if (aFilter.EqualsLiteral("..apps")) { |
1006 if (aFilter.EqualsLiteral("..apps")) { |
1315 // No platform specific thing we can do here, really.... |
1007 // No platform specific thing we can do here, really.... |
1316 - return NS_OK; |
1008 - return NS_OK; |
1317 + // Unless it's KDE. |
1009 + // Unless it's KDE. |
1318 + if( mMode != modeOpen || !nsKDEUtils::kdeSupport()) |
1010 + if (mMode != modeOpen || !nsKDEUtils::kdeSupport()) return NS_OK; |
1319 + return NS_OK; |
|
1320 } |
1011 } |
1321 |
1012 |
1322 nsAutoCString filter, name; |
1013 nsAutoCString filter, name; |
1323 CopyUTF16toUTF8(aFilter, filter); |
1014 @@ -352,6 +356,31 @@ nsFilePicker::Open(nsIFilePickerShownCal |
1324 CopyUTF16toUTF8(aTitle, name); |
|
1325 |
|
1326 mFilters.AppendElement(filter); |
|
1327 mFilterNames.AppendElement(name); |
|
1328 @@ -347,16 +352,39 @@ nsresult nsFilePicker::Show(nsIFilePicke |
|
1329 return NS_OK; |
|
1330 } |
|
1331 |
|
1332 NS_IMETHODIMP |
|
1333 nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) { |
|
1334 // Can't show two dialogs concurrently with the same filepicker |
1015 // Can't show two dialogs concurrently with the same filepicker |
1335 if (mRunning) return NS_ERROR_NOT_AVAILABLE; |
1016 if (mRunning) return NS_ERROR_NOT_AVAILABLE; |
1336 |
1017 |
1337 + // KDE file picker is not handled via callback |
1018 + // KDE file picker is not handled via callback |
1338 + if( nsKDEUtils::kdeSupport()) { |
1019 + if (nsKDEUtils::kdeSupport()) { |
1339 + mCallback = aCallback; |
1020 + mCallback = aCallback; |
1340 + mRunning = true; |
1021 + mRunning = true; |
1341 + NS_ADDREF_THIS(); |
1022 + NS_ADDREF_THIS(); |
1342 + g_idle_add([](gpointer data) -> gboolean { |
1023 + g_idle_add( |
1343 + nsFilePicker* queuedPicker = (nsFilePicker*) data; |
1024 + [](gpointer data) -> gboolean { |
1344 + nsIFilePicker::ResultCode result; |
1025 + nsFilePicker* queuedPicker = (nsFilePicker*)data; |
1345 + queuedPicker->kdeFileDialog(&result); |
1026 + nsIFilePicker::ResultCode result; |
1346 + if (queuedPicker->mCallback) { |
1027 + queuedPicker->kdeFileDialog(&result); |
1347 + queuedPicker->mCallback->Done(result); |
1028 + if (queuedPicker->mCallback) { |
1348 + queuedPicker->mCallback = nullptr; |
1029 + queuedPicker->mCallback->Done(result); |
1349 + } else { |
1030 + queuedPicker->mCallback = nullptr; |
1350 + queuedPicker->mResult = result; |
1031 + } else { |
1351 + } |
1032 + queuedPicker->mResult = result; |
1352 + queuedPicker->mRunning = false; |
1033 + } |
1353 + NS_RELEASE(queuedPicker); |
1034 + queuedPicker->mRunning = false; |
1354 + return G_SOURCE_REMOVE; |
1035 + NS_RELEASE(queuedPicker); |
1355 + }, this); |
1036 + return G_SOURCE_REMOVE; |
|
1037 + }, |
|
1038 + this); |
1356 + |
1039 + |
1357 + return NS_OK; |
1040 + return NS_OK; |
1358 + } |
1041 + } |
1359 + |
1042 + |
1360 NS_ConvertUTF16toUTF8 title(mTitle); |
1043 NS_ConvertUTF16toUTF8 title(mTitle); |
1361 |
1044 |
1362 GtkWindow* parent_widget = |
1045 GtkWindow* parent_widget = |
1363 GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)); |
1046 @@ -633,6 +662,205 @@ void nsFilePicker::Done(void* file_choos |
1364 |
|
1365 GtkFileChooserAction action = GetGtkFileChooserAction(mMode); |
|
1366 |
|
1367 const gchar* accept_button; |
|
1368 @@ -628,16 +656,244 @@ void nsFilePicker::Done(void* file_choos |
|
1369 mCallback->Done(result); |
|
1370 mCallback = nullptr; |
|
1371 } else { |
|
1372 mResult = result; |
|
1373 } |
|
1374 NS_RELEASE_THIS(); |
1047 NS_RELEASE_THIS(); |
1375 } |
1048 } |
1376 |
1049 |
1377 +nsCString nsFilePicker::kdeMakeFilter( int index ) |
1050 +nsCString nsFilePicker::kdeMakeFilter(int index) { |
1378 + { |
1051 + nsCString buf = mFilters[index]; |
1379 + nsCString buf = mFilters[ index ]; |
1052 + for (PRUint32 i = 0; i < buf.Length(); ++i) |
1380 + for( PRUint32 i = 0; |
1053 + if (buf[i] == ';') // KDE separates just using spaces |
1381 + i < buf.Length(); |
1054 + buf.SetCharAt(' ', i); |
1382 + ++i ) |
1055 + if (!mFilterNames[index].IsEmpty()) { |
1383 + if( buf[ i ] == ';' ) // KDE separates just using spaces |
1056 + buf += "|"; |
1384 + buf.SetCharAt( ' ', i ); |
1057 + buf += mFilterNames[index].get(); |
1385 + if (!mFilterNames[index].IsEmpty()) |
1058 + } |
1386 + { |
1059 + return buf; |
1387 + buf += "|"; |
1060 +} |
1388 + buf += mFilterNames[index].get(); |
1061 + |
1389 + } |
1062 +static PRInt32 windowToXid(nsIWidget* widget) { |
1390 + return buf; |
1063 + GtkWindow* parent_widget = |
|
1064 + GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET)); |
|
1065 + GdkWindow* gdk_window = |
|
1066 + gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(parent_widget))); |
|
1067 + return GDK_WINDOW_XID(gdk_window); |
|
1068 +} |
|
1069 + |
|
1070 +NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode* aReturn) { |
|
1071 + NS_ENSURE_ARG_POINTER(aReturn); |
|
1072 + |
|
1073 + if (mMode == modeOpen && mFilters.Length() == 1 && |
|
1074 + mFilters[0].EqualsLiteral("..apps")) |
|
1075 + return kdeAppsDialog(aReturn); |
|
1076 + |
|
1077 + nsCString title; |
|
1078 + title.Adopt(ToNewUTF8String(mTitle)); |
|
1079 + |
|
1080 + const char* arg = NULL; |
|
1081 + if (mAllowURLs) { |
|
1082 + switch (mMode) { |
|
1083 + case nsIFilePicker::modeOpen: |
|
1084 + case nsIFilePicker::modeOpenMultiple: |
|
1085 + arg = "GETOPENURL"; |
|
1086 + break; |
|
1087 + case nsIFilePicker::modeSave: |
|
1088 + arg = "GETSAVEURL"; |
|
1089 + break; |
|
1090 + case nsIFilePicker::modeGetFolder: |
|
1091 + arg = "GETDIRECTORYURL"; |
|
1092 + break; |
1391 + } |
1093 + } |
1392 + |
1094 + } else { |
1393 +static PRInt32 windowToXid( nsIWidget* widget ) |
1095 + switch (mMode) { |
1394 + { |
1096 + case nsIFilePicker::modeOpen: |
1395 + GtkWindow *parent_widget = GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET)); |
1097 + case nsIFilePicker::modeOpenMultiple: |
1396 + GdkWindow* gdk_window = gtk_widget_get_window( gtk_widget_get_toplevel( GTK_WIDGET( parent_widget ))); |
1098 + arg = "GETOPENFILENAME"; |
1397 + return GDK_WINDOW_XID( gdk_window ); |
1099 + break; |
|
1100 + case nsIFilePicker::modeSave: |
|
1101 + arg = "GETSAVEFILENAME"; |
|
1102 + break; |
|
1103 + case nsIFilePicker::modeGetFolder: |
|
1104 + arg = "GETDIRECTORYFILENAME"; |
|
1105 + break; |
1398 + } |
1106 + } |
1399 + |
1107 + } |
1400 +NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode *aReturn) |
|
1401 + { |
|
1402 + NS_ENSURE_ARG_POINTER(aReturn); |
|
1403 + |
|
1404 + if( mMode == modeOpen && mFilters.Length() == 1 && mFilters[ 0 ].EqualsLiteral( "..apps" )) |
|
1405 + return kdeAppsDialog( aReturn ); |
|
1406 + |
|
1407 + nsCString title; |
|
1408 + title.Adopt(ToNewUTF8String(mTitle)); |
|
1409 + |
|
1410 + const char* arg = NULL; |
|
1411 + if( mAllowURLs ) |
|
1412 + { |
|
1413 + switch( mMode ) |
|
1414 + { |
|
1415 + case nsIFilePicker::modeOpen: |
|
1416 + case nsIFilePicker::modeOpenMultiple: |
|
1417 + arg = "GETOPENURL"; |
|
1418 + break; |
|
1419 + case nsIFilePicker::modeSave: |
|
1420 + arg = "GETSAVEURL"; |
|
1421 + break; |
|
1422 + case nsIFilePicker::modeGetFolder: |
|
1423 + arg = "GETDIRECTORYURL"; |
|
1424 + break; |
|
1425 + } |
|
1426 + } |
|
1427 + else |
|
1428 + { |
|
1429 + switch( mMode ) |
|
1430 + { |
|
1431 + case nsIFilePicker::modeOpen: |
|
1432 + case nsIFilePicker::modeOpenMultiple: |
|
1433 + arg = "GETOPENFILENAME"; |
|
1434 + break; |
|
1435 + case nsIFilePicker::modeSave: |
|
1436 + arg = "GETSAVEFILENAME"; |
|
1437 + break; |
|
1438 + case nsIFilePicker::modeGetFolder: |
|
1439 + arg = "GETDIRECTORYFILENAME"; |
|
1440 + break; |
|
1441 + } |
|
1442 + } |
|
1443 + |
1108 + |
1444 + nsAutoCString directory; |
1109 + nsAutoCString directory; |
1445 + if (mDisplayDirectory) { |
1110 + if (mDisplayDirectory) { |
1446 + mDisplayDirectory->GetNativePath(directory); |
1111 + mDisplayDirectory->GetNativePath(directory); |
1447 + } else if (mPrevDisplayDirectory) { |
1112 + } else if (mPrevDisplayDirectory) { |
1448 + mPrevDisplayDirectory->GetNativePath(directory); |
1113 + mPrevDisplayDirectory->GetNativePath(directory); |
1449 + } |
1114 + } |
1450 + |
1115 + |
1451 + nsAutoCString startdir; |
1116 + nsAutoCString startdir; |
1452 + if (!directory.IsEmpty()) { |
1117 + if (!directory.IsEmpty()) { |
1453 + startdir = directory; |
1118 + startdir = directory; |
1454 + } |
1119 + } |
1455 + if (mMode == nsIFilePicker::modeSave) { |
1120 + if (mMode == nsIFilePicker::modeSave) { |
1456 + if( !startdir.IsEmpty()) |
1121 + if (!startdir.IsEmpty()) { |
1457 + { |
|
1458 + startdir += "/"; |
1122 + startdir += "/"; |
1459 + startdir += ToNewUTF8String(mDefault); |
1123 + startdir += ToNewUTF8String(mDefault); |
|
1124 + } else |
|
1125 + startdir = ToNewUTF8String(mDefault); |
|
1126 + } |
|
1127 + |
|
1128 + nsAutoCString filters; |
|
1129 + PRInt32 count = mFilters.Length(); |
|
1130 + if (count == 0) // just in case |
|
1131 + filters = "*"; |
|
1132 + else { |
|
1133 + filters = kdeMakeFilter(0); |
|
1134 + for (PRInt32 i = 1; i < count; ++i) { |
|
1135 + filters += "\n"; |
|
1136 + filters += kdeMakeFilter(i); |
|
1137 + } |
|
1138 + } |
|
1139 + |
|
1140 + nsTArray<nsCString> command; |
|
1141 + command.AppendElement(nsAutoCString(arg)); |
|
1142 + command.AppendElement(startdir); |
|
1143 + if (mMode != nsIFilePicker::modeGetFolder) { |
|
1144 + command.AppendElement(filters); |
|
1145 + nsAutoCString selected; |
|
1146 + selected.AppendInt(mSelectedType); |
|
1147 + command.AppendElement(selected); |
|
1148 + } |
|
1149 + command.AppendElement(title); |
|
1150 + if (mMode == nsIFilePicker::modeOpenMultiple) |
|
1151 + command.AppendElement("MULTIPLE"_ns); |
|
1152 + if (PRInt32 xid = windowToXid(mParentWidget)) { |
|
1153 + command.AppendElement("PARENT"_ns); |
|
1154 + nsAutoCString parent; |
|
1155 + parent.AppendInt(xid); |
|
1156 + command.AppendElement(parent); |
|
1157 + } |
|
1158 + |
|
1159 + nsTArray<nsCString> output; |
|
1160 + if (nsKDEUtils::commandBlockUi( |
|
1161 + command, |
|
1162 + GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), |
|
1163 + &output)) { |
|
1164 + *aReturn = nsIFilePicker::returnOK; |
|
1165 + mFiles.Clear(); |
|
1166 + if (mMode != nsIFilePicker::modeGetFolder) { |
|
1167 + mSelectedType = atoi(output[0].get()); |
|
1168 + output.RemoveElementAt(0); |
|
1169 + } |
|
1170 + if (mMode == nsIFilePicker::modeOpenMultiple) { |
|
1171 + mFileURL.Truncate(); |
|
1172 + PRUint32 count = output.Length(); |
|
1173 + for (PRUint32 i = 0; i < count; ++i) { |
|
1174 + nsCOMPtr<nsIFile> localfile; |
|
1175 + nsresult rv = NS_NewNativeLocalFile(output[i], PR_FALSE, |
|
1176 + getter_AddRefs(localfile)); |
|
1177 + if (NS_SUCCEEDED(rv)) mFiles.AppendObject(localfile); |
1460 + } |
1178 + } |
1461 + else |
1179 + } else { |
1462 + startdir = ToNewUTF8String(mDefault); |
1180 + if (output.Length() == 0) |
1463 + } |
1181 + mFileURL = nsCString(); |
1464 + |
1182 + else if (mAllowURLs) |
1465 + nsAutoCString filters; |
1183 + mFileURL = output[0]; |
1466 + PRInt32 count = mFilters.Length(); |
1184 + else // GetFile() actually requires it to be url even for local files :-/ |
1467 + if( count == 0 ) //just in case |
1185 + { |
1468 + filters = "*"; |
1186 + nsCOMPtr<nsIFile> localfile; |
1469 + else |
1187 + nsresult rv = NS_NewNativeLocalFile(output[0], PR_FALSE, |
1470 + { |
1188 + getter_AddRefs(localfile)); |
1471 + filters = kdeMakeFilter( 0 ); |
1189 + if (NS_SUCCEEDED(rv)) |
1472 + for (PRInt32 i = 1; i < count; ++i) |
1190 + rv = net_GetURLSpecFromActualFile(localfile, mFileURL); |
1473 + { |
1191 + } |
1474 + filters += "\n"; |
|
1475 + filters += kdeMakeFilter( i ); |
|
1476 + } |
|
1477 + } |
|
1478 + |
|
1479 + nsTArray<nsCString> command; |
|
1480 + command.AppendElement( nsAutoCString( arg )); |
|
1481 + command.AppendElement( startdir ); |
|
1482 + if( mMode != nsIFilePicker::modeGetFolder ) |
|
1483 + { |
|
1484 + command.AppendElement( filters ); |
|
1485 + nsAutoCString selected; |
|
1486 + selected.AppendInt( mSelectedType ); |
|
1487 + command.AppendElement( selected ); |
|
1488 + } |
|
1489 + command.AppendElement( title ); |
|
1490 + if( mMode == nsIFilePicker::modeOpenMultiple ) |
|
1491 + command.AppendElement( "MULTIPLE"_ns ); |
|
1492 + if( PRInt32 xid = windowToXid( mParentWidget )) |
|
1493 + { |
|
1494 + command.AppendElement( "PARENT"_ns ); |
|
1495 + nsAutoCString parent; |
|
1496 + parent.AppendInt( xid ); |
|
1497 + command.AppendElement( parent ); |
|
1498 + } |
|
1499 + |
|
1500 + nsTArray<nsCString> output; |
|
1501 + if( nsKDEUtils::commandBlockUi( command, GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), &output )) |
|
1502 + { |
|
1503 + *aReturn = nsIFilePicker::returnOK; |
|
1504 + mFiles.Clear(); |
|
1505 + if( mMode != nsIFilePicker::modeGetFolder ) |
|
1506 + { |
|
1507 + mSelectedType = atoi( output[ 0 ].get()); |
|
1508 + output.RemoveElementAt( 0 ); |
|
1509 + } |
|
1510 + if (mMode == nsIFilePicker::modeOpenMultiple) |
|
1511 + { |
|
1512 + mFileURL.Truncate(); |
|
1513 + PRUint32 count = output.Length(); |
|
1514 + for( PRUint32 i = 0; |
|
1515 + i < count; |
|
1516 + ++i ) |
|
1517 + { |
|
1518 + nsCOMPtr<nsIFile> localfile; |
|
1519 + nsresult rv = NS_NewNativeLocalFile( output[ i ], |
|
1520 + PR_FALSE, |
|
1521 + getter_AddRefs(localfile)); |
|
1522 + if (NS_SUCCEEDED(rv)) |
|
1523 + mFiles.AppendObject(localfile); |
|
1524 + } |
|
1525 + } |
|
1526 + else |
|
1527 + { |
|
1528 + if( output.Length() == 0 ) |
|
1529 + mFileURL = nsCString(); |
|
1530 + else if( mAllowURLs ) |
|
1531 + mFileURL = output[ 0 ]; |
|
1532 + else // GetFile() actually requires it to be url even for local files :-/ |
|
1533 + { |
|
1534 + nsCOMPtr<nsIFile> localfile; |
|
1535 + nsresult rv = NS_NewNativeLocalFile( output[ 0 ], |
|
1536 + PR_FALSE, |
|
1537 + getter_AddRefs(localfile)); |
|
1538 + if (NS_SUCCEEDED(rv)) |
|
1539 + rv = net_GetURLSpecFromActualFile(localfile, mFileURL); |
|
1540 + } |
|
1541 + } |
|
1542 + // Remember last used directory. |
|
1543 + nsCOMPtr<nsIFile> file; |
|
1544 + GetFile(getter_AddRefs(file)); |
|
1545 + if (file) { |
|
1546 + nsCOMPtr<nsIFile> dir; |
|
1547 + file->GetParent(getter_AddRefs(dir)); |
|
1548 + nsCOMPtr<nsIFile> localDir(do_QueryInterface(dir)); |
|
1549 + if (localDir) { |
|
1550 + localDir.swap(mPrevDisplayDirectory); |
|
1551 + } |
1192 + } |
1552 + } |
1193 + // Remember last used directory. |
1553 + if (mMode == nsIFilePicker::modeSave) |
1194 + nsCOMPtr<nsIFile> file; |
1554 + { |
1195 + GetFile(getter_AddRefs(file)); |
1555 + nsCOMPtr<nsIFile> file; |
1196 + if (file) { |
1556 + GetFile(getter_AddRefs(file)); |
1197 + nsCOMPtr<nsIFile> dir; |
1557 + if (file) |
1198 + file->GetParent(getter_AddRefs(dir)); |
1558 + { |
1199 + nsCOMPtr<nsIFile> localDir(dir); |
1559 + bool exists = false; |
1200 + if (localDir) { |
1560 + file->Exists(&exists); |
1201 + localDir.swap(mPrevDisplayDirectory); |
1561 + if (exists) // TODO do overwrite check in the helper app |
1202 + } |
1562 + *aReturn = nsIFilePicker::returnReplace; |
|
1563 + } |
|
1564 + } |
|
1565 + } |
|
1566 + else |
|
1567 + { |
|
1568 + *aReturn = nsIFilePicker::returnCancel; |
|
1569 + } |
|
1570 + return NS_OK; |
|
1571 + } |
1203 + } |
1572 + |
1204 + if (mMode == nsIFilePicker::modeSave) { |
1573 + |
1205 + nsCOMPtr<nsIFile> file; |
1574 +NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode *aReturn) |
1206 + GetFile(getter_AddRefs(file)); |
1575 + { |
1207 + if (file) { |
1576 + NS_ENSURE_ARG_POINTER(aReturn); |
1208 + bool exists = false; |
1577 + |
1209 + file->Exists(&exists); |
1578 + nsCString title; |
1210 + if (exists) // TODO do overwrite check in the helper app |
1579 + title.Adopt(ToNewUTF8String(mTitle)); |
1211 + *aReturn = nsIFilePicker::returnReplace; |
1580 + |
1212 + } |
1581 + nsTArray<nsCString> command; |
|
1582 + command.AppendElement( "APPSDIALOG"_ns ); |
|
1583 + command.AppendElement( title ); |
|
1584 + if( PRInt32 xid = windowToXid( mParentWidget )) |
|
1585 + { |
|
1586 + command.AppendElement( "PARENT"_ns ); |
|
1587 + nsAutoCString parent; |
|
1588 + parent.AppendInt( xid ); |
|
1589 + command.AppendElement( parent ); |
|
1590 + } |
|
1591 + |
|
1592 + nsTArray<nsCString> output; |
|
1593 + if( nsKDEUtils::commandBlockUi( command, GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), &output )) |
|
1594 + { |
|
1595 + *aReturn = nsIFilePicker::returnOK; |
|
1596 + mFileURL = output.Length() > 0 ? output[ 0 ] : nsCString(); |
|
1597 + } |
|
1598 + else |
|
1599 + { |
|
1600 + *aReturn = nsIFilePicker::returnCancel; |
|
1601 + } |
|
1602 + return NS_OK; |
|
1603 + } |
1213 + } |
|
1214 + } else { |
|
1215 + *aReturn = nsIFilePicker::returnCancel; |
|
1216 + } |
|
1217 + return NS_OK; |
|
1218 +} |
|
1219 + |
|
1220 +NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode* aReturn) { |
|
1221 + NS_ENSURE_ARG_POINTER(aReturn); |
|
1222 + |
|
1223 + nsCString title; |
|
1224 + title.Adopt(ToNewUTF8String(mTitle)); |
|
1225 + |
|
1226 + nsTArray<nsCString> command; |
|
1227 + command.AppendElement("APPSDIALOG"_ns); |
|
1228 + command.AppendElement(title); |
|
1229 + if (PRInt32 xid = windowToXid(mParentWidget)) { |
|
1230 + command.AppendElement("PARENT"_ns); |
|
1231 + nsAutoCString parent; |
|
1232 + parent.AppendInt(xid); |
|
1233 + command.AppendElement(parent); |
|
1234 + } |
|
1235 + |
|
1236 + nsTArray<nsCString> output; |
|
1237 + if (nsKDEUtils::commandBlockUi( |
|
1238 + command, |
|
1239 + GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), |
|
1240 + &output)) { |
|
1241 + *aReturn = nsIFilePicker::returnOK; |
|
1242 + mFileURL = output.Length() > 0 ? output[0] : nsCString(); |
|
1243 + } else { |
|
1244 + *aReturn = nsIFilePicker::returnCancel; |
|
1245 + } |
|
1246 + return NS_OK; |
|
1247 +} |
1604 + |
1248 + |
1605 // All below functions available as of GTK 3.20+ |
1249 // All below functions available as of GTK 3.20+ |
1606 void* nsFilePicker::GtkFileChooserNew(const gchar* title, GtkWindow* parent, |
1250 void* nsFilePicker::GtkFileChooserNew(const gchar* title, GtkWindow* parent, |
1607 GtkFileChooserAction action, |
1251 GtkFileChooserAction action, |
1608 const gchar* accept_label) { |
1252 Index: firefox-115.0/widget/gtk/nsFilePicker.h |
1609 static auto sGtkFileChooserNativeNewPtr = |
1253 =================================================================== |
1610 (void* (*)(const gchar*, GtkWindow*, GtkFileChooserAction, const gchar*, |
1254 --- firefox-115.0.orig/widget/gtk/nsFilePicker.h |
1611 const gchar*))dlsym(RTLD_DEFAULT, |
1255 +++ firefox-115.0/widget/gtk/nsFilePicker.h |
1612 "gtk_file_chooser_native_new"); |
1256 @@ -74,6 +74,12 @@ class nsFilePicker : public nsBaseFilePi |
1613 diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h |
|
1614 --- a/widget/gtk/nsFilePicker.h |
|
1615 +++ b/widget/gtk/nsFilePicker.h |
|
1616 @@ -69,16 +69,22 @@ class nsFilePicker : public nsBaseFilePi |
|
1617 nsString mDefaultExtension; |
|
1618 |
|
1619 nsTArray<nsCString> mFilters; |
|
1620 nsTArray<nsCString> mFilterNames; |
|
1621 |
|
1622 private: |
1257 private: |
1623 static nsIFile* mPrevDisplayDirectory; |
1258 static nsIFile* mPrevDisplayDirectory; |
1624 |
1259 |
1625 + bool kdeRunning(); |
1260 + bool kdeRunning(); |
1626 + bool getKdeRunning(); |
1261 + bool getKdeRunning(); |
1627 + NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode *aReturn); |
1262 + NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode* aReturn); |
1628 + NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode *aReturn); |
1263 + NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode* aReturn); |
1629 + nsCString kdeMakeFilter( int index ); |
1264 + nsCString kdeMakeFilter(int index); |
1630 + |
1265 + |
1631 void* GtkFileChooserNew(const gchar* title, GtkWindow* parent, |
1266 void* GtkFileChooserNew(const gchar* title, GtkWindow* parent, |
1632 GtkFileChooserAction action, |
1267 GtkFileChooserAction action, |
1633 const gchar* accept_label); |
1268 const gchar* accept_label); |
1634 void GtkFileChooserShow(void* file_chooser); |
1269 Index: firefox-115.0/xpcom/components/ManifestParser.cpp |
1635 void GtkFileChooserDestroy(void* file_chooser); |
1270 =================================================================== |
1636 void GtkFileChooserSetModal(void* file_chooser, GtkWindow* parent_widget, |
1271 --- firefox-115.0.orig/xpcom/components/ManifestParser.cpp |
1637 gboolean modal); |
1272 +++ firefox-115.0/xpcom/components/ManifestParser.cpp |
1638 |
1273 @@ -43,6 +43,7 @@ |
1639 diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp |
|
1640 --- a/xpcom/components/ManifestParser.cpp |
|
1641 +++ b/xpcom/components/ManifestParser.cpp |
|
1642 @@ -38,16 +38,17 @@ |
|
1643 #include "nsTextFormatter.h" |
|
1644 #include "nsVersionComparator.h" |
|
1645 #include "nsXPCOMCIDInternal.h" |
|
1646 |
|
1647 #include "nsIConsoleService.h" |
|
1648 #include "nsIScriptError.h" |
1274 #include "nsIScriptError.h" |
1649 #include "nsIXULAppInfo.h" |
1275 #include "nsIXULAppInfo.h" |
1650 #include "nsIXULRuntime.h" |
1276 #include "nsIXULRuntime.h" |
1651 +#include "nsKDEUtils.h" |
1277 +#include "nsKDEUtils.h" |
1652 |
1278 |
1653 using namespace mozilla; |
1279 using namespace mozilla; |
1654 |
1280 |
1655 struct ManifestDirective { |
1281 @@ -394,6 +395,7 @@ void ParseManifest(NSLocationType aType, |
1656 const char* directive; |
|
1657 int argc; |
|
1658 |
|
1659 bool ischrome; |
|
1660 @@ -389,16 +390,17 @@ void ParseManifest(NSLocationType aType, |
|
1661 constexpr auto kRemoteEnabled = u"remoteenabled"_ns; |
|
1662 constexpr auto kRemoteRequired = u"remoterequired"_ns; |
|
1663 constexpr auto kApplication = u"application"_ns; |
|
1664 constexpr auto kAppVersion = u"appversion"_ns; |
|
1665 constexpr auto kGeckoVersion = u"platformversion"_ns; |
|
1666 constexpr auto kOs = u"os"_ns; |
1282 constexpr auto kOs = u"os"_ns; |
1667 constexpr auto kOsVersion = u"osversion"_ns; |
1283 constexpr auto kOsVersion = u"osversion"_ns; |
1668 constexpr auto kABI = u"abi"_ns; |
1284 constexpr auto kABI = u"abi"_ns; |
1669 + constexpr auto kDesktop = u"desktop"_ns; |
1285 + constexpr auto kDesktop = u"desktop"_ns; |
1670 constexpr auto kProcess = u"process"_ns; |
1286 constexpr auto kProcess = u"process"_ns; |
1671 #if defined(MOZ_WIDGET_ANDROID) |
1287 #if defined(MOZ_WIDGET_ANDROID) |
1672 constexpr auto kTablet = u"tablet"_ns; |
1288 constexpr auto kTablet = u"tablet"_ns; |
1673 #endif |
1289 @@ -453,6 +455,7 @@ void ParseManifest(NSLocationType aType, |
1674 // You might expect this to be guarded by MOZ_BACKGROUNDTASKS, but it's not |
|
1675 // possible to have conditional manifest contents, so we need to recognize and |
|
1676 // discard these tokens even when MOZ_BACKGROUNDTASKS is not set. |
|
1677 constexpr auto kBackgroundTask = u"backgroundtask"_ns; |
|
1678 @@ -448,39 +450,44 @@ void ParseManifest(NSLocationType aType, |
|
1679 CopyUTF8toUTF16(s, abi); |
|
1680 abi.Insert(char16_t('_'), 0); |
|
1681 abi.Insert(osTarget, 0); |
|
1682 } |
|
1683 } |
|
1684 } |
1290 } |
1685 |
1291 |
1686 nsAutoString osVersion; |
1292 nsAutoString osVersion; |
1687 + nsAutoString desktop; |
1293 + nsAutoString desktop; |
1688 #if defined(XP_WIN) |
1294 #if defined(XP_WIN) |
1689 # pragma warning(push) |
1295 # pragma warning(push) |
1690 # pragma warning(disable : 4996) // VC12+ deprecates GetVersionEx |
1296 # pragma warning(disable : 4996) // VC12+ deprecates GetVersionEx |
1691 OSVERSIONINFO info = {sizeof(OSVERSIONINFO)}; |
1297 @@ -461,14 +464,17 @@ void ParseManifest(NSLocationType aType, |
1692 if (GetVersionEx(&info)) { |
|
1693 nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", info.dwMajorVersion, |
1298 nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", info.dwMajorVersion, |
1694 info.dwMinorVersion); |
1299 info.dwMinorVersion); |
1695 } |
1300 } |
1696 + desktop = u"win"_ns; |
1301 + desktop = u"win"_ns; |
1697 # pragma warning(pop) |
1302 # pragma warning(pop) |
1705 gtk_minor_version); |
1310 gtk_minor_version); |
1706 + desktop = nsKDEUtils::kdeSession() ? u"kde"_ns : u"gnome"_ns; |
1311 + desktop = nsKDEUtils::kdeSession() ? u"kde"_ns : u"gnome"_ns; |
1707 #elif defined(MOZ_WIDGET_ANDROID) |
1312 #elif defined(MOZ_WIDGET_ANDROID) |
1708 bool isTablet = false; |
1313 bool isTablet = false; |
1709 if (jni::IsAvailable()) { |
1314 if (jni::IsAvailable()) { |
1710 jni::String::LocalRef release = java::sdk::Build::VERSION::RELEASE(); |
1315 @@ -476,6 +482,7 @@ void ParseManifest(NSLocationType aType, |
1711 osVersion.Assign(release->ToString()); |
1316 osVersion.Assign(release->ToString()); |
1712 isTablet = java::GeckoAppShell::IsTablet(); |
1317 isTablet = java::GeckoAppShell::IsTablet(); |
1713 } |
1318 } |
1714 + desktop = u"android"_ns; |
1319 + desktop = u"android"_ns; |
1715 #endif |
1320 #endif |
1716 |
1321 |
1717 if (XRE_IsContentProcess()) { |
1322 if (XRE_IsContentProcess()) { |
1718 process = kContent; |
1323 @@ -576,6 +583,7 @@ void ParseManifest(NSLocationType aType, |
1719 } else { |
|
1720 process = kMain; |
|
1721 } |
|
1722 |
|
1723 @@ -571,25 +578,27 @@ void ParseManifest(NSLocationType aType, |
|
1724 // When in background task mode, default to not registering |
|
1725 // category directivies unless backgroundtask=1 is specified. |
|
1726 TriState stBackgroundTask = (BackgroundTasks::IsBackgroundTaskMode() && |
|
1727 strcmp("category", directive->directive) == 0) |
|
1728 ? eBad |
|
1729 : eUnspecified; |
1324 : eUnspecified; |
1730 #endif |
1325 #endif |
1731 int flags = 0; |
1326 int flags = 0; |
1732 + TriState stDesktop = eUnspecified; |
1327 + TriState stDesktop = eUnspecified; |
1733 |
1328 |
1734 while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && |
1329 while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && |
1735 ok) { |
1330 ok) { |
1736 ToLowerCase(token); |
1331 @@ -585,6 +593,7 @@ void ParseManifest(NSLocationType aType, |
1737 NS_ConvertASCIItoUTF16 wtoken(token); |
|
1738 |
|
1739 if (CheckStringFlag(kApplication, wtoken, appID, stApp) || |
1332 if (CheckStringFlag(kApplication, wtoken, appID, stApp) || |
1740 CheckOsFlag(kOs, wtoken, osTarget, stOs) || |
1333 CheckOsFlag(kOs, wtoken, osTarget, stOs) || |
1741 CheckStringFlag(kABI, wtoken, abi, stABI) || |
1334 CheckStringFlag(kABI, wtoken, abi, stABI) || |
1742 + CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) || |
1335 + CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) || |
1743 CheckStringFlag(kProcess, wtoken, process, stProcess) || |
1336 CheckStringFlag(kProcess, wtoken, process, stProcess) || |
1744 CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || |
1337 CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || |
1745 CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || |
1338 CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || |
1746 CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, |
1339 @@ -644,6 +653,7 @@ void ParseManifest(NSLocationType aType, |
1747 stGeckoVersion)) { |
|
1748 continue; |
|
1749 } |
|
1750 |
|
1751 @@ -638,17 +647,17 @@ void ParseManifest(NSLocationType aType, |
|
1752 } |
|
1753 |
|
1754 LogMessageWithContext( |
|
1755 aFile, line, "Unrecognized chrome manifest modifier '%s'.", token); |
|
1756 ok = false; |
|
1757 } |
|
1758 |
1340 |
1759 if (!ok || stApp == eBad || stAppVersion == eBad || |
1341 if (!ok || stApp == eBad || stAppVersion == eBad || |
1760 - stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad || |
1342 stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad || |
1761 + stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad || stDesktop == eBad || |
1343 + stDesktop == eBad || |
1762 #ifdef MOZ_WIDGET_ANDROID |
1344 #ifdef MOZ_WIDGET_ANDROID |
1763 stTablet == eBad || |
1345 stTablet == eBad || |
1764 #endif |
1346 #endif |
1765 #ifdef MOZ_BACKGROUNDTASKS |
1347 Index: firefox-115.0/xpcom/components/moz.build |
1766 stBackgroundTask == eBad || |
1348 =================================================================== |
1767 #endif |
1349 --- firefox-115.0.orig/xpcom/components/moz.build |
1768 stABI == eBad || stProcess == eBad) { |
1350 +++ firefox-115.0/xpcom/components/moz.build |
1769 continue; |
1351 @@ -71,6 +71,7 @@ LOCAL_INCLUDES += [ |
1770 diff --git a/xpcom/components/moz.build b/xpcom/components/moz.build |
|
1771 --- a/xpcom/components/moz.build |
|
1772 +++ b/xpcom/components/moz.build |
|
1773 @@ -66,16 +66,17 @@ LOCAL_INCLUDES += [ |
|
1774 "!..", |
|
1775 "../base", |
|
1776 "../build", |
|
1777 "../ds", |
|
1778 "/chrome", |
|
1779 "/js/xpconnect/loader", |
1352 "/js/xpconnect/loader", |
1780 "/layout/build", |
1353 "/layout/build", |
1781 "/modules/libjar", |
1354 "/modules/libjar", |
1782 + "/toolkit/xre", |
1355 + "/toolkit/xre", |
1783 ] |
1356 ] |
1784 |
1357 |
1785 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
1358 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": |
1786 CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] |
1359 Index: firefox-115.0/xpcom/io/nsLocalFileUnix.cpp |
1787 if CONFIG["MOZ_ENABLE_DBUS"]: |
1360 =================================================================== |
1788 CXXFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"] |
1361 --- firefox-115.0.orig/xpcom/io/nsLocalFileUnix.cpp |
1789 |
1362 +++ firefox-115.0/xpcom/io/nsLocalFileUnix.cpp |
1790 include("/ipc/chromium/chromium-config.mozbuild") |
1363 @@ -51,6 +51,7 @@ |
1791 diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp |
|
1792 --- a/xpcom/io/nsLocalFileUnix.cpp |
|
1793 +++ b/xpcom/io/nsLocalFileUnix.cpp |
|
1794 @@ -46,16 +46,17 @@ |
|
1795 #include "nsString.h" |
|
1796 #include "nsIDirectoryEnumerator.h" |
|
1797 #include "nsSimpleEnumerator.h" |
|
1798 #include "private/pprio.h" |
|
1799 #include "prlink.h" |
|
1800 |
1364 |
1801 #ifdef MOZ_WIDGET_GTK |
1365 #ifdef MOZ_WIDGET_GTK |
1802 # include "nsIGIOService.h" |
1366 # include "nsIGIOService.h" |
1803 +# include "nsKDEUtils.h" |
1367 +# include "nsKDEUtils.h" |
1804 #endif |
1368 #endif |
1805 |
1369 |
1806 #ifdef MOZ_WIDGET_COCOA |
1370 #ifdef MOZ_WIDGET_COCOA |
1807 # include <Carbon/Carbon.h> |
1371 @@ -2172,10 +2173,18 @@ nsLocalFile::Reveal() { |
1808 # include "CocoaFileUtils.h" |
|
1809 # include "prmem.h" |
|
1810 # include "plbase64.h" |
|
1811 |
|
1812 @@ -2167,20 +2168,29 @@ nsLocalFile::SetPersistentDescriptor(con |
|
1813 |
|
1814 NS_IMETHODIMP |
|
1815 nsLocalFile::Reveal() { |
|
1816 if (!FilePreferences::IsAllowedPath(mPath)) { |
|
1817 return NS_ERROR_FILE_ACCESS_DENIED; |
|
1818 } |
1372 } |
1819 |
1373 |
1820 #ifdef MOZ_WIDGET_GTK |
1374 #ifdef MOZ_WIDGET_GTK |
1821 + nsAutoCString url; |
1375 + nsAutoCString url; |
1822 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
1376 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
1823 - if (!giovfs) { |
1377 - if (!giovfs) { |
|
1378 - return NS_ERROR_FAILURE; |
1824 + url = mPath; |
1379 + url = mPath; |
1825 + if(nsKDEUtils::kdeSupport()) { |
1380 + if (nsKDEUtils::kdeSupport()) { |
1826 + nsTArray<nsCString> command; |
1381 + nsTArray<nsCString> command; |
1827 + command.AppendElement( "REVEAL"_ns ); |
1382 + command.AppendElement("REVEAL"_ns); |
1828 + command.AppendElement( mPath ); |
1383 + command.AppendElement(mPath); |
1829 + return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE; |
1384 + return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE; |
1830 + } |
1385 } |
1831 + |
1386 + |
1832 + if (!giovfs) |
1387 + if (!giovfs) return NS_ERROR_FAILURE; |
1833 return NS_ERROR_FAILURE; |
|
1834 - } |
|
1835 + |
1388 + |
1836 return giovfs->RevealFile(this); |
1389 return giovfs->RevealFile(this); |
1837 #elif defined(MOZ_WIDGET_COCOA) |
1390 #elif defined(MOZ_WIDGET_COCOA) |
1838 CFURLRef url; |
1391 CFURLRef url; |
1839 if (NS_SUCCEEDED(GetCFURL(&url))) { |
1392 @@ -2197,6 +2206,13 @@ nsLocalFile::Launch() { |
1840 nsresult rv = CocoaFileUtils::RevealFileInFinder(url); |
|
1841 ::CFRelease(url); |
|
1842 return rv; |
|
1843 } |
1393 } |
1844 @@ -2192,16 +2202,23 @@ nsLocalFile::Reveal() { |
|
1845 |
|
1846 NS_IMETHODIMP |
|
1847 nsLocalFile::Launch() { |
|
1848 if (!FilePreferences::IsAllowedPath(mPath)) { |
|
1849 return NS_ERROR_FILE_ACCESS_DENIED; |
|
1850 } |
|
1851 |
1394 |
1852 #ifdef MOZ_WIDGET_GTK |
1395 #ifdef MOZ_WIDGET_GTK |
1853 + if( nsKDEUtils::kdeSupport()) { |
1396 + if (nsKDEUtils::kdeSupport()) { |
1854 + nsTArray<nsCString> command; |
1397 + nsTArray<nsCString> command; |
1855 + command.AppendElement( "OPEN"_ns ); |
1398 + command.AppendElement("OPEN"_ns); |
1856 + command.AppendElement( mPath ); |
1399 + command.AppendElement(mPath); |
1857 + return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE; |
1400 + return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE; |
1858 + } |
1401 + } |
1859 + |
1402 + |
1860 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
1403 nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
1861 if (!giovfs) { |
1404 if (!giovfs) { |
1862 return NS_ERROR_FAILURE; |
1405 return NS_ERROR_FAILURE; |
1863 } |
|
1864 |
|
1865 return giovfs->LaunchFile(mPath); |
|
1866 #elif defined(MOZ_WIDGET_ANDROID) |
|
1867 // Not supported on GeckoView |
|