diff --git a/firefox-4.0-gnome3.patch b/firefox-4.0-gnome3.patch new file mode 100644 index 0000000..c1f229a --- /dev/null +++ b/firefox-4.0-gnome3.patch @@ -0,0 +1,1299 @@ +diff --git a/toolkit/system/gnome/nsGIOService.cpp b/toolkit/system/gnome/nsGIOService.cpp +--- a/toolkit/system/gnome/nsGIOService.cpp ++++ b/toolkit/system/gnome/nsGIOService.cpp +@@ -101,25 +101,25 @@ nsGIOMimeApp::GetName(nsACString& aName) + return NS_OK; + } + + NS_IMETHODIMP + nsGIOMimeApp::GetCommand(nsACString& aCommand) + { + get_commandline_t g_app_info_get_commandline_ptr; + +- void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY); ++ void *libHandle = dlopen("libgio-2.0.so.0", RTLD_LAZY); + if (!libHandle) { + return NS_ERROR_FAILURE; + } + dlerror(); /* clear any existing error */ + g_app_info_get_commandline_ptr = + (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline"); +- if (dlerror() != NULL) { +- const char cmd = *g_app_info_get_commandline_ptr(mApp); ++ if (dlerror() == NULL) { ++ const char *cmd = g_app_info_get_commandline_ptr(mApp); + if (!cmd) { + dlclose(libHandle); + return NS_ERROR_FAILURE; + } + aCommand.Assign(cmd); + } + dlclose(libHandle); + return NS_OK; +@@ -414,75 +414,46 @@ nsGIOService::CreateAppFromCommand(nsACS + nsIGIOMimeApp** appInfo) + { + GError *error = NULL; + *appInfo = nsnull; + + GAppInfo *app_info = NULL, *app_info_from_list = NULL; + GList *apps = g_app_info_get_all(); + GList *apps_p = apps; +- get_commandline_t g_app_info_get_commandline_ptr; +- +- void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY); +- if (!libHandle) { +- return NS_ERROR_FAILURE; +- } +- dlerror(); /* clear any existing error */ +- g_app_info_get_commandline_ptr = +- (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline"); +- if (dlerror() != NULL) { +- g_app_info_get_commandline_ptr = NULL; +- } + + // Try to find relevant and existing GAppInfo in all installed application ++ // We do this by comparing each GAppInfo's executable with out own + while (apps_p) { + app_info_from_list = (GAppInfo*) apps_p->data; +- /* This is a silly test. It just compares app names but not +- * commands. This is due to old version of Glib/Gio. The required +- * function which allows to do a regular check of existence of desktop file +- * is possible by using function g_app_info_get_commandline. This function +- * has been introduced in Glib 2.20. */ +- if (app_info_from_list && strcmp(g_app_info_get_name(app_info_from_list), +- PromiseFlatCString(appName).get()) == 0 ) +- { +- if (g_app_info_get_commandline_ptr) +- { +- /* Following test is only possible with Glib >= 2.20. +- * Compare path only by using strncmp */ +- if (strncmp(g_app_info_get_commandline_ptr(app_info_from_list), +- PromiseFlatCString(cmd).get(), +- strlen(PromiseFlatCString(cmd).get())) == 0) +- { +- app_info = app_info_from_list; +- break; +- } else { +- g_object_unref(app_info_from_list); +- } +- } else { ++ if (!app_info) { ++ // If the executable is not absolute, get it's full path ++ char *executable = g_find_program_in_path(g_app_info_get_executable(app_info_from_list)); ++ ++ if (executable && strcmp(executable, PromiseFlatCString(cmd).get()) == 0) { ++ g_object_ref (app_info_from_list); + app_info = app_info_from_list; +- break; + } +- } else { +- g_object_unref(app_info_from_list); ++ g_free(executable); + } ++ ++ g_object_unref(app_info_from_list); + apps_p = apps_p->next; + } + g_list_free(apps); + + if (!app_info) { + app_info = g_app_info_create_from_commandline(PromiseFlatCString(cmd).get(), + PromiseFlatCString(appName).get(), + G_APP_INFO_CREATE_SUPPORTS_URIS, + &error); + } + + if (!app_info) { + g_warning("Cannot create application info from command: %s", error->message); + g_error_free(error); +- dlclose(libHandle); + return NS_ERROR_FAILURE; + } + nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info); + NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY); + NS_ADDREF(*appInfo = mozApp); +- dlclose(libHandle); + return NS_OK; + } + +diff --git a/browser/components/shell/src/nsGNOMEShellService.cpp b/browser/components/shell/src/nsGNOMEShellService.cpp +--- a/browser/components/shell/src/nsGNOMEShellService.cpp ++++ b/browser/components/shell/src/nsGNOMEShellService.cpp +@@ -101,24 +101,24 @@ static const char kDesktopOptionsKey[] = + static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background"; + static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color"; + + nsresult + nsGNOMEShellService::Init() + { + nsresult rv; + +- // GConf _must_ be available, or we do not allow ++ // GConf or GIO _must_ be available, or we do not allow + // CreateInstance to succeed. + + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + nsCOMPtr giovfs = + do_GetService(NS_GIOSERVICE_CONTRACTID); + +- if (!gconf) ++ if (!gconf && !giovfs) + return NS_ERROR_NOT_AVAILABLE; + + // Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use + // the locale encoding. If it's not set, they use UTF-8. + mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull; + + if (GetAppPathFromLauncher()) + return NS_OK; +@@ -189,50 +189,77 @@ nsGNOMEShellService::KeyMatchesAppName(c + if (!commandPath) + return PR_FALSE; + + PRBool matches = mAppPath.Equals(commandPath); + g_free(commandPath); + return matches; + } + ++PRBool ++nsGNOMEShellService::CheckHandlerMatchesAppName(const nsACString &handler) const ++{ ++ gint argc; ++ gchar **argv; ++ nsCAutoString command(handler); ++ ++ // The string will be something of the form: [/path/to/]browser "%s" ++ // We want to remove all of the parameters and get just the binary name. ++ ++ if (g_shell_parse_argv(command.get(), &argc, &argv, NULL) && argc > 0) { ++ command.Assign(argv[0]); ++ g_strfreev(argv); ++ } ++ ++ if (!KeyMatchesAppName(command.get())) ++ return PR_FALSE; // the handler is set to another app ++ ++ return PR_TRUE; ++} ++ + NS_IMETHODIMP + nsGNOMEShellService::IsDefaultBrowser(PRBool aStartupCheck, + PRBool* aIsDefaultBrowser) + { + *aIsDefaultBrowser = PR_FALSE; + if (aStartupCheck) + mCheckedThisSession = PR_TRUE; + + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); ++ nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); + + PRBool enabled; + nsCAutoString handler; ++ nsCOMPtr gioApp; + + for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { + if (!appProtocols[i].essential) + continue; + +- handler.Truncate(); +- gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), +- &enabled, handler); ++ if (gconf) { ++ handler.Truncate(); ++ gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), ++ &enabled, handler); + +- // The string will be something of the form: [/path/to/]browser "%s" +- // We want to remove all of the parameters and get just the binary name. +- +- gint argc; +- gchar **argv; +- +- if (g_shell_parse_argv(handler.get(), &argc, &argv, NULL) && argc > 0) { +- handler.Assign(argv[0]); +- g_strfreev(argv); ++ if (!CheckHandlerMatchesAppName(handler) || !enabled) ++ return NS_OK; // the handler is disabled or set to another app + } + +- if (!KeyMatchesAppName(handler.get()) || !enabled) +- return NS_OK; // the handler is disabled or set to another app ++ if (giovfs) { ++ handler.Truncate(); ++ giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name), ++ getter_AddRefs(gioApp)); ++ if (!gioApp) ++ return NS_OK; ++ ++ gioApp->GetCommand(handler); ++ ++ if (!CheckHandlerMatchesAppName(handler)) ++ return NS_OK; // the handler is set to another app ++ } + } + + *aIsDefaultBrowser = PR_TRUE; + + return NS_OK; + } + + NS_IMETHODIMP +@@ -240,19 +267,20 @@ nsGNOMEShellService::SetDefaultBrowser(P + PRBool aForAllUsers) + { + #ifdef DEBUG + if (aForAllUsers) + NS_WARNING("Setting the default browser for all users is not yet supported"); + #endif + + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); ++ nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); + if (gconf) { + nsCAutoString appKeyValue; +- if(mAppIsInPath) { ++ if (mAppIsInPath) { + // mAppPath is in the users path, so use only the basename as the launcher + gchar *tmp = g_path_get_basename(mAppPath.get()); + appKeyValue = tmp; + g_free(tmp); + } else { + appKeyValue = mAppPath; + } + +@@ -261,23 +289,18 @@ nsGNOMEShellService::SetDefaultBrowser(P + for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { + if (appProtocols[i].essential || aClaimAllTypes) { + gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name), + appKeyValue); + } + } + } + +- // set handler for .html and xhtml files and MIME types: +- if (aClaimAllTypes) { ++ if (giovfs) { + nsresult rv; +- nsCOMPtr giovfs = +- do_GetService(NS_GIOSERVICE_CONTRACTID, &rv); +- NS_ENSURE_SUCCESS(rv, NS_OK); +- + nsCOMPtr bundleService = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr brandBundle; + rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle)); + NS_ENSURE_SUCCESS(rv, rv); + +@@ -290,20 +313,30 @@ nsGNOMEShellService::SetDefaultBrowser(P + // use brandShortName as the application id. + NS_ConvertUTF16toUTF8 id(brandShortName); + nsCOMPtr appInfo; + rv = giovfs->CreateAppFromCommand(mAppPath, + id, + getter_AddRefs(appInfo)); + NS_ENSURE_SUCCESS(rv, rv); + +- // Add mime types for html, xhtml extension and set app to just created appinfo. +- for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) { +- appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType)); +- appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions)); ++ // set handler for the protocols ++ for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { ++ if (appProtocols[i].essential || aClaimAllTypes) { ++ appInfo->SetAsDefaultForURIScheme(nsDependentCString(appProtocols[i].name)); ++ } ++ } ++ ++ // set handler for .html and xhtml files and MIME types: ++ if (aClaimAllTypes) { ++ // Add mime types for html, xhtml extension and set app to just created appinfo. ++ for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) { ++ appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType)); ++ appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions)); ++ } + } + } + + return NS_OK; + } + + NS_IMETHODIMP + nsGNOMEShellService::GetShouldCheckDefaultBrowser(PRBool* aResult) +@@ -403,48 +436,52 @@ nsGNOMEShellService::SetDesktopBackgroun + filePath.Append("_wallpaper.png"); + + // write the image to a file in the home dir + rv = WriteImage(filePath, container); + + // if the file was written successfully, set it as the system wallpaper + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + +- nsCAutoString options; +- if (aPosition == BACKGROUND_TILE) +- options.Assign("wallpaper"); +- else if (aPosition == BACKGROUND_STRETCH) +- options.Assign("stretched"); +- else +- options.Assign("centered"); ++ if (gconf) { ++ nsCAutoString options; ++ if (aPosition == BACKGROUND_TILE) ++ options.Assign("wallpaper"); ++ else if (aPosition == BACKGROUND_STRETCH) ++ options.Assign("stretched"); ++ else ++ options.Assign("centered"); + +- gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); ++ gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); + +- // Set the image to an empty string first to force a refresh +- // (since we could be writing a new image on top of an existing +- // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) +- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), +- EmptyCString()); ++ // Set the image to an empty string first to force a refresh ++ // (since we could be writing a new image on top of an existing ++ // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) ++ gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), ++ EmptyCString()); + +- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); +- gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), PR_TRUE); ++ gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); ++ gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), PR_TRUE); ++ } + + return rv; + } + + #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8) + #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c)) + + NS_IMETHODIMP + nsGNOMEShellService::GetDesktopBackgroundColor(PRUint32 *aColor) + { + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + + nsCAutoString background; +- gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); ++ if (gconf) { ++ gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); ++ } + + if (background.IsEmpty()) { + *aColor = 0; + return NS_OK; + } + + GdkColor color; + gboolean success = gdk_color_parse(background.get(), &color); +@@ -473,36 +510,48 @@ ColorToCString(PRUint32 aColor, nsCStrin + } + + NS_IMETHODIMP + nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor) + { + NS_ASSERTION(aColor <= 0xffffff, "aColor has extra bits"); + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + +- nsCAutoString colorString; +- ColorToCString(aColor, colorString); ++ if (gconf) { ++ nsCAutoString colorString; ++ ColorToCString(aColor, colorString); + +- gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); ++ gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); ++ } + + return NS_OK; + } + + NS_IMETHODIMP + nsGNOMEShellService::OpenApplication(PRInt32 aApplication) + { + nsCAutoString scheme; + if (aApplication == APPLICATION_MAIL) + scheme.Assign("mailto"); + else if (aApplication == APPLICATION_NEWS) + scheme.Assign("news"); + else + return NS_ERROR_NOT_AVAILABLE; + ++ nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); ++ if (giovfs) { ++ nsCOMPtr gioApp; ++ giovfs->GetAppForURIScheme(scheme, getter_AddRefs(gioApp)); ++ if (gioApp) ++ return gioApp->Launch(EmptyCString()); ++ } ++ + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); ++ if (!gconf) ++ return NS_ERROR_FAILURE; + + PRBool enabled; + nsCAutoString appCommand; + gconf->GetAppForProtocol(scheme, &enabled, appCommand); + + if (!enabled) + return NS_ERROR_FAILURE; + +diff --git a/browser/components/shell/src/nsGNOMEShellService.h b/browser/components/shell/src/nsGNOMEShellService.h +--- a/browser/components/shell/src/nsGNOMEShellService.h ++++ b/browser/components/shell/src/nsGNOMEShellService.h +@@ -49,16 +49,17 @@ public: + NS_DECL_NSISHELLSERVICE + + nsresult Init() NS_HIDDEN; + + private: + ~nsGNOMEShellService() {} + + NS_HIDDEN_(PRBool) KeyMatchesAppName(const char *aKeyValue) const; ++ NS_HIDDEN_(PRBool) CheckHandlerMatchesAppName(const nsACString& handler) const; + + NS_HIDDEN_(PRBool) GetAppPathFromLauncher(); + PRPackedBool mCheckedThisSession; + PRPackedBool mUseLocaleFilenames; + nsCString mAppPath; + PRPackedBool mAppIsInPath; + }; + +diff --git a/toolkit/system/gnome/nsGIOService.cpp b/toolkit/system/gnome/nsGIOService.cpp +--- a/toolkit/system/gnome/nsGIOService.cpp ++++ b/toolkit/system/gnome/nsGIOService.cpp +@@ -277,16 +277,43 @@ nsGIOMimeApp::SetAsDefaultForFileExtensi + } else { + *ext_pos = '\0'; + } + } + g_free(extensions); + return NS_OK; + } + ++/** ++ * Set default application for URI's of a particular scheme ++ * @param aURIScheme string containing the URI scheme ++ * @return NS_OK when application was set as default for URI scheme, ++ * NS_ERROR_FAILURE otherwise ++ */ ++NS_IMETHODIMP ++nsGIOMimeApp::SetAsDefaultForURIScheme(nsACString const& aURIScheme) ++{ ++ GError *error = NULL; ++ nsCAutoString contentType("x-scheme-handler/"); ++ contentType.Append(aURIScheme); ++ ++ g_app_info_set_as_default_for_type(mApp, ++ contentType.get(), ++ &error); ++ if (error) { ++ g_warning("Cannot set application as default for URI scheme (%s): %s", ++ PromiseFlatCString(aURIScheme).get(), ++ error->message); ++ g_error_free(error); ++ return NS_ERROR_FAILURE; ++ } ++ ++ return NS_OK; ++} ++ + nsresult + nsGIOService::Init() + { + // do nothing, gvfs/gio does not init. + return NS_OK; + } + + NS_IMPL_ISUPPORTS1(nsGIOService, nsIGIOService) +@@ -317,16 +344,33 @@ nsGIOService::GetMimeTypeFromExtension(c + g_free(mime_type); + g_free(content_type); + + return NS_OK; + } + // used in nsGNOMERegistry + // ----------------------------------------------------------------------------- + NS_IMETHODIMP ++nsGIOService::GetAppForURIScheme(const nsACString& aURIScheme, ++ nsIGIOMimeApp** aApp) ++{ ++ *aApp = nsnull; ++ ++ GAppInfo *app_info = g_app_info_get_default_for_uri_scheme( ++ PromiseFlatCString(aURIScheme).get()); ++ if (app_info) { ++ nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info); ++ NS_ADDREF(*aApp = mozApp); ++ } else { ++ return NS_ERROR_FAILURE; ++ } ++ return NS_OK; ++} ++ ++NS_IMETHODIMP + nsGIOService::GetAppForMimeType(const nsACString& aMimeType, + nsIGIOMimeApp** aApp) + { + *aApp = nsnull; + char *content_type = + get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get()); + if (!content_type) + return NS_ERROR_FAILURE; +diff --git a/xpcom/system/nsIGIOService.idl b/xpcom/system/nsIGIOService.idl +--- a/xpcom/system/nsIGIOService.idl ++++ b/xpcom/system/nsIGIOService.idl +@@ -41,57 +41,61 @@ + + interface nsIUTF8StringEnumerator; + interface nsIURI; + + /* nsIGIOMimeApp holds information about an application that is looked up + with nsIGIOService::GetAppForMimeType. */ + // 66009894-9877-405b-9321-bf30420e34e6 prev uuid + +-[scriptable, uuid(e77021b4-4012-407d-b686-7a1f18050109)] ++[scriptable, uuid(ca6bad0c-8a48-48ac-82c7-27bb8f510fbe)] + interface nsIGIOMimeApp : nsISupports + { + const long EXPECTS_URIS = 0; + const long EXPECTS_PATHS = 1; + const long EXPECTS_URIS_FOR_NON_FILES = 2; + + readonly attribute AUTF8String id; + readonly attribute AUTF8String name; + readonly attribute AUTF8String command; + readonly attribute long expectsURIs; // see constants above + readonly attribute nsIUTF8StringEnumerator supportedURISchemes; + + void launch(in AUTF8String uri); + void setAsDefaultForMimeType(in AUTF8String mimeType); + void setAsDefaultForFileExtensions(in AUTF8String extensions); ++ void setAsDefaultForURIScheme(in AUTF8String uriScheme); + }; + + /* + * The VFS service makes use of two distinct registries. + * + * The application registry holds information about applications (uniquely + * identified by id), such as which MIME types and URI schemes they are + * capable of handling, whether they run in a terminal, etc. + * + * The MIME registry holds information about MIME types, such as which + * extensions map to a given MIME type. The MIME registry also stores the + * id of the application selected to handle each MIME type. + */ + + // prev id dea20bf0-4e4d-48c5-b932-dc3e116dc64b +-[scriptable, uuid(47e372c2-78bb-4899-8114-56aa7d9cdac5)] ++[scriptable, uuid(eda22a30-84e1-4e16-9ca0-cd1553c2b34a)] + interface nsIGIOService : nsISupports + { + + /*** MIME registry methods ***/ + + /* Obtain the MIME type registered for an extension. The extension + should not include a leading dot. */ + AUTF8String getMimeTypeFromExtension(in AUTF8String extension); + ++ /* Obtain the preferred application for opening a given URI scheme */ ++ nsIGIOMimeApp getAppForURIScheme(in AUTF8String aURIScheme); ++ + /* Obtain the preferred application for opening a given MIME type */ + nsIGIOMimeApp getAppForMimeType(in AUTF8String mimeType); + + /* Obtain the preferred application for opening a given MIME type */ + nsIGIOMimeApp createAppFromCommand(in AUTF8String cmd, + in AUTF8String appName); + + /* Obtain a description for the given MIME type */ + +diff --git a/toolkit/system/gnome/Makefile.in b/toolkit/system/gnome/Makefile.in +--- a/toolkit/system/gnome/Makefile.in ++++ b/toolkit/system/gnome/Makefile.in +@@ -60,16 +60,17 @@ ifdef MOZ_ENABLE_GNOMEVFS + CPPSRCS += \ + nsGnomeVFSService.cpp \ + $(NULL) + endif + + ifdef MOZ_ENABLE_GIO + CPPSRCS += \ + nsGIOService.cpp \ ++ nsGSettingsService.cpp \ + $(NULL) + endif + + ifdef MOZ_ENABLE_LIBNOTIFY + CPPSRCS += \ + nsAlertsService.cpp \ + nsAlertsIconListener.cpp \ + $(NULL) +diff --git a/toolkit/system/gnome/nsGSettingsService.cpp b/toolkit/system/gnome/nsGSettingsService.cpp +new file mode 100644 +--- /dev/null ++++ b/toolkit/system/gnome/nsGSettingsService.cpp +@@ -0,0 +1,238 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is the Mozilla GNOME integration code. ++ * ++ * The Initial Developer of the Original Code is ++ * Canonical Ltd. ++ * Portions created by the Initial Developer are Copyright (C) 2010 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Chris Coulson ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#include "nsGSettingsService.h" ++#include "nsStringAPI.h" ++#include "nsCOMPtr.h" ++#include "prlink.h" ++#include "nsComponentManagerUtils.h" ++ ++#include ++#include ++ ++typedef struct _GSettings GSettings; ++ ++typedef GSettings * (*_g_settings_new_fn) (const char* schema); ++typedef const char * const* (*_g_settings_list_schemas_fn) (void); ++typedef gboolean (*_g_settings_set_string_fn) (GSettings* settings, ++ const char* key, ++ const char* value); ++typedef gboolean (*_g_settings_set_boolean_fn) (GSettings* settings, ++ const char* key, ++ gboolean value); ++typedef gboolean (*_g_settings_set_int_fn) (GSettings* settings, ++ const char* key, ++ int value); ++typedef char * (*_g_settings_get_string_fn) (GSettings* settings, ++ const char* key); ++typedef gboolean (*_g_settings_get_boolean_fn) (GSettings* settings, ++ const char* key); ++typedef int (*_g_settings_get_int_fn) (GSettings* settings, ++ const char* key); ++ ++static _g_settings_new_fn _g_settings_new; ++static _g_settings_list_schemas_fn _g_settings_list_schemas; ++static PRLibrary *gioLib = nsnull; ++ ++class nsGSettingsCollection : public nsIGSettingsCollection ++{ ++public: ++ NS_DECL_ISUPPORTS ++ NS_DECL_NSIGSETTINGSCOLLECTION ++ ++ nsGSettingsCollection(GSettings* aSettings) : mSettings(aSettings) {} ++ ~nsGSettingsCollection() { g_object_unref(mSettings); } ++ ++private: ++ GSettings *mSettings; ++}; ++ ++NS_IMPL_ISUPPORTS1(nsGSettingsCollection, nsIGSettingsCollection) ++ ++NS_IMETHODIMP ++nsGSettingsCollection::SetString(const nsACString& aKey, ++ const nsACString& aValue) ++{ ++ _g_settings_set_string_fn _g_settings_set_string = ++ (_g_settings_set_string_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_set_string"); ++ if (!_g_settings_set_string) ++ return NS_ERROR_FAILURE; ++ ++ gboolean res = _g_settings_set_string(mSettings, ++ PromiseFlatCString(aKey).get(), ++ PromiseFlatCString(aValue).get()); ++ ++ return res ? NS_OK : NS_ERROR_FAILURE; ++} ++ ++NS_IMETHODIMP ++nsGSettingsCollection::SetBoolean(const nsACString& aKey, ++ PRBool aValue) ++{ ++ _g_settings_set_boolean_fn _g_settings_set_boolean = ++ (_g_settings_set_boolean_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_set_boolean"); ++ if (!_g_settings_set_boolean) ++ return NS_ERROR_FAILURE; ++ ++ gboolean res = _g_settings_set_boolean(mSettings, ++ PromiseFlatCString(aKey).get(), ++ aValue); ++ ++ return res ? NS_OK : NS_ERROR_FAILURE; ++} ++ ++NS_IMETHODIMP ++nsGSettingsCollection::SetInt(const nsACString& aKey, ++ PRInt32 aValue) ++{ ++ _g_settings_set_int_fn _g_settings_set_int = ++ (_g_settings_set_int_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_set_int"); ++ if (!_g_settings_set_int) ++ return NS_ERROR_FAILURE; ++ ++ gboolean res = _g_settings_set_int(mSettings, ++ PromiseFlatCString(aKey).get(), ++ aValue); ++ ++ return res ? NS_OK : NS_ERROR_FAILURE; ++} ++ ++NS_IMETHODIMP ++nsGSettingsCollection::GetString(const nsACString& aKey, ++ nsACString& aResult) ++{ ++ _g_settings_get_string_fn _g_settings_get_string = ++ (_g_settings_get_string_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_get_string"); ++ if (!_g_settings_get_string) ++ return NS_ERROR_FAILURE; ++ ++ char *result = _g_settings_get_string(mSettings, ++ PromiseFlatCString(aKey).get()); ++ if (!result) ++ return NS_ERROR_FAILURE; ++ ++ aResult.Assign(result); ++ g_free(result); ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsGSettingsCollection::GetBoolean(const nsACString& aKey, ++ PRBool* aResult) ++{ ++ _g_settings_get_boolean_fn _g_settings_get_boolean = ++ (_g_settings_get_boolean_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_get_boolean"); ++ if (!_g_settings_get_boolean) ++ return NS_ERROR_FAILURE; ++ ++ gboolean res = _g_settings_get_boolean(mSettings, ++ PromiseFlatCString(aKey).get()); ++ *aResult = res ? PR_TRUE : PR_FALSE; ++ ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsGSettingsCollection::GetInt(const nsACString& aKey, ++ PRInt32* aResult) ++{ ++ _g_settings_get_int_fn _g_settings_get_int = ++ (_g_settings_get_int_fn) PR_FindFunctionSymbol(gioLib, ++ "g_settings_get_int"); ++ if (!_g_settings_get_int) ++ return NS_ERROR_FAILURE; ++ ++ *aResult = _g_settings_get_int(mSettings, ++ PromiseFlatCString(aKey).get()); ++ ++ return NS_OK; ++} ++ ++nsresult ++nsGSettingsService::Init() ++{ ++ if (!gioLib) { ++ gioLib = PR_LoadLibrary("libgio-2.0.so.0"); ++ } ++ ++ _g_settings_new = (_g_settings_new_fn) ++ PR_FindFunctionSymbol(gioLib, "g_settings_new"); ++ _g_settings_list_schemas = (_g_settings_list_schemas_fn) ++ PR_FindFunctionSymbol(gioLib, "g_settings_list_schemas"); ++ ++ if (!_g_settings_new || !_g_settings_list_schemas) { ++ PR_UnloadLibrary(gioLib); ++ return NS_ERROR_FAILURE; ++ } ++ ++ return NS_OK; ++} ++ ++NS_IMPL_ISUPPORTS1(nsGSettingsService, nsIGSettingsService) ++ ++nsGSettingsService::~nsGSettingsService() ++{ ++ if (gioLib) { ++ PR_UnloadLibrary(gioLib); ++ gioLib = nsnull; ++ } ++} ++ ++NS_IMETHODIMP ++nsGSettingsService::GetCollectionForSchema(const nsACString& schema, ++ nsIGSettingsCollection** collection) ++{ ++ const char * const *schemas = _g_settings_list_schemas(); ++ unsigned int i = 0; ++ ++ for (i = 0; schemas[i] != NULL; i++) { ++ if (strcmp(schemas[i], PromiseFlatCString(schema).get()) == 0) { ++ GSettings *settings = _g_settings_new(PromiseFlatCString(schema).get()); ++ nsGSettingsCollection *mozGSettings = new nsGSettingsCollection(settings); ++ NS_ADDREF(*collection = mozGSettings); ++ return NS_OK; ++ } ++ } ++ ++ return NS_ERROR_FAILURE; ++} +diff --git a/toolkit/system/gnome/nsGSettingsService.h b/toolkit/system/gnome/nsGSettingsService.h +new file mode 100644 +--- /dev/null ++++ b/toolkit/system/gnome/nsGSettingsService.h +@@ -0,0 +1,60 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is the Mozilla GNOME integration code. ++ * ++ * The Initial Developer of the Original Code is ++ * Canonical Ltd. ++ * Portions created by the Initial Developer are Copyright (C) 2010 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Chris Coulson ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#ifndef nsGSettingsService_h_ ++#define nsGSettingsService_h_ ++ ++#include "nsIGSettingsService.h" ++ ++#define NS_GSETTINGSSERVICE_CID \ ++{0xbfd4a9d8, 0xd886, 0x4161, {0x81, 0xef, 0x88, 0x68, 0xda, 0x11, 0x41, 0x70}} ++ ++class nsGSettingsService : public nsIGSettingsService ++{ ++public: ++ NS_DECL_ISUPPORTS ++ NS_DECL_NSIGSETTINGSSERVICE ++ ++ NS_HIDDEN_(nsresult) Init(); ++ ++private: ++ ~nsGSettingsService(); ++}; ++ ++#endif ++ +diff --git a/toolkit/system/gnome/nsGnomeModule.cpp b/toolkit/system/gnome/nsGnomeModule.cpp +--- a/toolkit/system/gnome/nsGnomeModule.cpp ++++ b/toolkit/system/gnome/nsGnomeModule.cpp +@@ -44,62 +44,67 @@ + NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGConfService, Init) + #endif + #ifdef MOZ_ENABLE_GNOMEVFS + #include "nsGnomeVFSService.h" + NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGnomeVFSService, Init) + #endif + #ifdef MOZ_ENABLE_GIO + #include "nsGIOService.h" ++#include "nsGSettingsService.h" + NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGIOService, Init) ++NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGSettingsService, Init) + #endif + #ifdef MOZ_ENABLE_LIBNOTIFY + #include "nsAlertsService.h" + NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAlertsService, Init) + #endif + + #ifdef MOZ_ENABLE_GCONF + NS_DEFINE_NAMED_CID(NS_GCONFSERVICE_CID); + #endif + #ifdef MOZ_ENABLE_GNOMEVFS + NS_DEFINE_NAMED_CID(NS_GNOMEVFSSERVICE_CID); + #endif + #ifdef MOZ_ENABLE_GIO + NS_DEFINE_NAMED_CID(NS_GIOSERVICE_CID); ++NS_DEFINE_NAMED_CID(NS_GSETTINGSSERVICE_CID); + #endif + #ifdef MOZ_ENABLE_LIBNOTIFY + NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID); + #endif + + + static const mozilla::Module::CIDEntry kGnomeCIDs[] = { + #ifdef MOZ_ENABLE_GCONF + { &kNS_GCONFSERVICE_CID, false, NULL, nsGConfServiceConstructor }, + #endif + #ifdef MOZ_ENABLE_GNOMEVFS + { &kNS_GNOMEVFSSERVICE_CID, false, NULL, nsGnomeVFSServiceConstructor }, + #endif + #ifdef MOZ_ENABLE_GIO + { &kNS_GIOSERVICE_CID, false, NULL, nsGIOServiceConstructor }, ++ { &kNS_GSETTINGSSERVICE_CID, false, NULL, nsGSettingsServiceConstructor }, + #endif + #ifdef MOZ_ENABLE_LIBNOTIFY + { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, nsAlertsServiceConstructor }, + #endif + { NULL } + }; + + static const mozilla::Module::ContractIDEntry kGnomeContracts[] = { + #ifdef MOZ_ENABLE_GCONF + { NS_GCONFSERVICE_CONTRACTID, &kNS_GCONFSERVICE_CID }, + #endif + #ifdef MOZ_ENABLE_GNOMEVFS + { NS_GNOMEVFSSERVICE_CONTRACTID, &kNS_GNOMEVFSSERVICE_CID }, + #endif + #ifdef MOZ_ENABLE_GIO + { NS_GIOSERVICE_CONTRACTID, &kNS_GIOSERVICE_CID }, ++ { NS_GSETTINGSSERVICE_CONTRACTID, &kNS_GSETTINGSSERVICE_CID }, + #endif + #ifdef MOZ_ENABLE_LIBNOTIFY + { NS_SYSTEMALERTSERVICE_CONTRACTID, &kNS_SYSTEMALERTSSERVICE_CID }, + #endif + { NULL } + }; + + static const mozilla::Module kGnomeModule = { +diff --git a/xpcom/system/Makefile.in b/xpcom/system/Makefile.in +--- a/xpcom/system/Makefile.in ++++ b/xpcom/system/Makefile.in +@@ -47,16 +47,17 @@ XPIDL_MODULE = xpcom_system + + XPIDLSRCS = \ + nsIXULAppInfo.idl \ + nsIXULRuntime.idl \ + nsIGConfService.idl \ + nsIGnomeVFSService.idl \ + nsIBlocklistService.idl \ + nsIGIOService.idl \ ++ nsIGSettingsService.idl \ + nsIAccelerometer.idl \ + nsIGeolocationProvider.idl \ + nsIHapticFeedback.idl \ + $(NULL) + + ifdef MOZ_CRASHREPORTER + XPIDLSRCS += nsICrashReporter.idl + endif +diff --git a/xpcom/system/nsIGSettingsService.idl b/xpcom/system/nsIGSettingsService.idl +new file mode 100644 +--- /dev/null ++++ b/xpcom/system/nsIGSettingsService.idl +@@ -0,0 +1,61 @@ ++/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is the Mozilla GNOME integration code. ++ * ++ * The Initial Developer of the Original Code is ++ * Canonical Ltd. ++ * Portions created by the Initial Developer are Copyright (C) 2010 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Chris Coulson ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#include "nsISupports.idl" ++#include "nsIArray.idl" ++ ++[scriptable, uuid(09637d3c-3c07-40b4-aff9-1d2a0f046f3c)] ++interface nsIGSettingsCollection : nsISupports ++{ ++ void setString(in AUTF8String key, in AUTF8String value); ++ void setBoolean(in AUTF8String key, in boolean value); ++ void setInt(in AUTF8String key, in long value); ++ AUTF8String getString(in AUTF8String key); ++ boolean getBoolean(in AUTF8String key); ++ long getInt(in AUTF8String key); ++}; ++ ++[scriptable, uuid(849c088b-57d1-4f24-b7b2-3dc4acb04c0a)] ++interface nsIGSettingsService : nsISupports ++{ ++ nsIGSettingsCollection getCollectionForSchema(in AUTF8String schema); ++}; ++ ++%{C++ ++#define NS_GSETTINGSSERVICE_CONTRACTID "@mozilla.org/gsettings-service;1" ++%} + +diff --git a/browser/components/shell/src/nsGNOMEShellService.cpp b/browser/components/shell/src/nsGNOMEShellService.cpp +--- a/browser/components/shell/src/nsGNOMEShellService.cpp ++++ b/browser/components/shell/src/nsGNOMEShellService.cpp +@@ -41,16 +41,17 @@ + #include "nsILocalFile.h" + #include "nsIProperties.h" + #include "nsDirectoryServiceDefs.h" + #include "nsIPrefService.h" + #include "prenv.h" + #include "nsStringAPI.h" + #include "nsIGConfService.h" + #include "nsIGIOService.h" ++#include "nsIGSettingsService.h" + #include "nsIStringBundle.h" + #include "nsIOutputStream.h" + #include "nsIProcess.h" + #include "nsNetUtil.h" + #include "nsIDOMHTMLImageElement.h" + #include "nsIImageLoadingContent.h" + #include "imgIRequest.h" + #include "imgIContainer.h" +@@ -96,29 +97,37 @@ static const char kDocumentIconPath[] = + // GConf registry key constants + #define DG_BACKGROUND "/desktop/gnome/background" + + static const char kDesktopImageKey[] = DG_BACKGROUND "/picture_filename"; + static const char kDesktopOptionsKey[] = DG_BACKGROUND "/picture_options"; + static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background"; + static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color"; + ++static const char kDesktopBGSchema[] = "org.gnome.desktop.background"; ++static const char kDesktopImageGSKey[] = "picture-uri"; ++static const char kDesktopOptionGSKey[] = "picture-options"; ++static const char kDesktopDrawBGGSKey[] = "draw-background"; ++static const char kDesktopColorGSKey[] = "primary-color"; ++ + nsresult + nsGNOMEShellService::Init() + { + nsresult rv; + +- // GConf or GIO _must_ be available, or we do not allow ++ // GConf, GSettings or GIO _must_ be available, or we do not allow + // CreateInstance to succeed. + + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + nsCOMPtr giovfs = + do_GetService(NS_GIOSERVICE_CONTRACTID); ++ nsCOMPtr gsettings = ++ do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); + +- if (!gconf && !giovfs) ++ if (!gconf && !giovfs && !gsettings) + return NS_ERROR_NOT_AVAILABLE; + + // Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use + // the locale encoding. If it's not set, they use UTF-8. + mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull; + + if (GetAppPathFromLauncher()) + return NS_OK; +@@ -434,27 +443,47 @@ nsGNOMEShellService::SetDesktopBackgroun + filePath.Append('/'); + filePath.Append(NS_ConvertUTF16toUTF8(brandName)); + filePath.Append("_wallpaper.png"); + + // write the image to a file in the home dir + rv = WriteImage(filePath, container); + + // if the file was written successfully, set it as the system wallpaper ++ nsCAutoString options; ++ if (aPosition == BACKGROUND_TILE) ++ options.Assign("wallpaper"); ++ else if (aPosition == BACKGROUND_STRETCH) ++ options.Assign("stretched"); ++ else ++ options.Assign("centered"); ++ ++ // Try GSettings first. If we don't have GSettings or the right schema, fall back ++ // to using GConf instead. Note that if GSettings works ok, the changes get ++ // mirrored to GConf by the gsettings->gconf bridge in gnome-settings-daemon ++ nsCOMPtr gsettings = ++ do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); ++ if (gsettings) { ++ nsCOMPtr background_settings; ++ gsettings->GetCollectionForSchema( ++ NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings)); ++ if (background_settings) { ++ filePath.Insert("file://", 0); ++ background_settings->SetString(NS_LITERAL_CSTRING(kDesktopOptionGSKey), ++ options); ++ background_settings->SetString(NS_LITERAL_CSTRING(kDesktopImageGSKey), ++ filePath); ++ background_settings->SetBoolean(NS_LITERAL_CSTRING(kDesktopDrawBGGSKey), ++ PR_TRUE); ++ return rv; ++ } ++ } ++ + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); +- + if (gconf) { +- nsCAutoString options; +- if (aPosition == BACKGROUND_TILE) +- options.Assign("wallpaper"); +- else if (aPosition == BACKGROUND_STRETCH) +- options.Assign("stretched"); +- else +- options.Assign("centered"); +- + gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); + + // Set the image to an empty string first to force a refresh + // (since we could be writing a new image on top of an existing + // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) + gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), + EmptyCString()); + +@@ -466,21 +495,33 @@ nsGNOMEShellService::SetDesktopBackgroun + } + + #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8) + #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c)) + + NS_IMETHODIMP + nsGNOMEShellService::GetDesktopBackgroundColor(PRUint32 *aColor) + { +- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); ++ nsCOMPtr gsettings = ++ do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); ++ nsCOMPtr background_settings; ++ nsCAutoString background; ++ if (gsettings) { ++ gsettings->GetCollectionForSchema( ++ NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings)); ++ if (background_settings) { ++ background_settings->GetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), ++ background); ++ } ++ } + +- nsCAutoString background; +- if (gconf) { +- gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); ++ if (!background_settings) { ++ nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); ++ if (gconf) ++ gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); + } + + if (background.IsEmpty()) { + *aColor = 0; + return NS_OK; + } + + GdkColor color; +@@ -508,22 +548,35 @@ ColorToCString(PRUint32 aColor, nsCStrin + + PR_snprintf(buf, 14, "#%04x%04x%04x", red, green, blue); + } + + NS_IMETHODIMP + nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor) + { + NS_ASSERTION(aColor <= 0xffffff, "aColor has extra bits"); ++ ++ nsCAutoString colorString; ++ ColorToCString(aColor, colorString); ++ ++ nsCOMPtr gsettings = ++ do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); ++ if (gsettings) { ++ nsCOMPtr background_settings; ++ gsettings->GetCollectionForSchema( ++ NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings)); ++ if (background_settings) { ++ background_settings->SetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), ++ colorString); ++ return NS_OK; ++ } ++ } ++ + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); +- + if (gconf) { +- nsCAutoString colorString; +- ColorToCString(aColor, colorString); +- + gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); + } + + return NS_OK; + } + + NS_IMETHODIMP + nsGNOMEShellService::OpenApplication(PRInt32 aApplication) + diff --git a/firefox.spec b/firefox.spec index b1919e2..fe2ffc6 100644 --- a/firefox.spec +++ b/firefox.spec @@ -68,6 +68,7 @@ Patch0: firefox-version.patch # Upstream patches Patch30: firefox-4.0-moz-app-launcher.patch +Patch31: firefox-4.0-gnome3.patch %if %{official_branding} # Required by Mozilla Corporation @@ -114,6 +115,7 @@ sed -e 's/__RPM_VERSION_INTERNAL__/%{firefox_dir_ver}/' %{P:%%PATCH0} \ # Upstream patches %patch30 -p1 -b .moz-app-launcher +%patch31 -p1 -b .gnome3 %if %{official_branding} # Required by Mozilla Corporation