forked from mirrors/gecko-dev
		
	 3f6c1dab90
			
		
	
	
		3f6c1dab90
		
	
	
	
	
		
			
			Keeps a function for opening the Mac desktop preferences. Differential Revision: https://phabricator.services.mozilla.com/D43269 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			502 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			502 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "mozilla/ArrayUtils.h"
 | |
| 
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsGNOMEShellService.h"
 | |
| #include "nsShellService.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsIFile.h"
 | |
| #include "nsIProperties.h"
 | |
| #include "nsDirectoryServiceDefs.h"
 | |
| #include "nsIPrefService.h"
 | |
| #include "prenv.h"
 | |
| #include "nsString.h"
 | |
| #include "nsIGIOService.h"
 | |
| #include "nsIGSettingsService.h"
 | |
| #include "nsIStringBundle.h"
 | |
| #include "nsIOutputStream.h"
 | |
| #include "nsServiceManagerUtils.h"
 | |
| #include "nsComponentManagerUtils.h"
 | |
| #include "nsIImageLoadingContent.h"
 | |
| #include "imgIRequest.h"
 | |
| #include "imgIContainer.h"
 | |
| #include "mozilla/Sprintf.h"
 | |
| #include "mozilla/dom/Element.h"
 | |
| #if defined(MOZ_WIDGET_GTK)
 | |
| #  include "nsIImageToPixbuf.h"
 | |
| #endif
 | |
| #include "nsXULAppAPI.h"
 | |
| #include "gfxPlatform.h"
 | |
| 
 | |
| #include <glib.h>
 | |
| #include <glib-object.h>
 | |
| #include <gtk/gtk.h>
 | |
| #include <gdk/gdk.h>
 | |
| #include <gdk-pixbuf/gdk-pixbuf.h>
 | |
| #include <limits.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| struct ProtocolAssociation {
 | |
|   const char* name;
 | |
|   bool essential;
 | |
| };
 | |
| 
 | |
| struct MimeTypeAssociation {
 | |
|   const char* mimeType;
 | |
|   const char* extensions;
 | |
| };
 | |
| 
 | |
| static const ProtocolAssociation appProtocols[] = {
 | |
|     // clang-format off
 | |
|   { "http",   true     },
 | |
|   { "https",  true     },
 | |
|   { "ftp",    false },
 | |
|   { "chrome", false }
 | |
|     // clang-format on
 | |
| };
 | |
| 
 | |
| static const MimeTypeAssociation appTypes[] = {
 | |
|     // clang-format off
 | |
|   { "text/html",             "htm html shtml" },
 | |
|   { "application/xhtml+xml", "xhtml xht"      }
 | |
|     // clang-format on
 | |
| };
 | |
| 
 | |
| #define kDesktopBGSchema "org.gnome.desktop.background"
 | |
| #define kDesktopImageGSKey "picture-uri"
 | |
| #define kDesktopOptionGSKey "picture-options"
 | |
| #define kDesktopDrawBGGSKey "draw-background"
 | |
| #define kDesktopColorGSKey "primary-color"
 | |
| 
 | |
| static bool IsRunningAsASnap() { return (PR_GetEnv("SNAP") != nullptr); }
 | |
| 
 | |
| nsresult nsGNOMEShellService::Init() {
 | |
|   nsresult rv;
 | |
| 
 | |
|   if (gfxPlatform::IsHeadless()) {
 | |
|     return NS_ERROR_NOT_AVAILABLE;
 | |
|   }
 | |
| 
 | |
|   // GSettings or GIO _must_ be available, or we do not allow
 | |
|   // CreateInstance to succeed.
 | |
| 
 | |
|   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 | |
|   nsCOMPtr<nsIGSettingsService> gsettings =
 | |
|       do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
 | |
| 
 | |
|   if (!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") != nullptr;
 | |
| 
 | |
|   if (GetAppPathFromLauncher()) return NS_OK;
 | |
| 
 | |
|   nsCOMPtr<nsIProperties> dirSvc(
 | |
|       do_GetService("@mozilla.org/file/directory_service;1"));
 | |
|   NS_ENSURE_TRUE(dirSvc, NS_ERROR_NOT_AVAILABLE);
 | |
| 
 | |
|   nsCOMPtr<nsIFile> appPath;
 | |
|   rv = dirSvc->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
 | |
|                    getter_AddRefs(appPath));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return appPath->GetNativePath(mAppPath);
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIGNOMEShellService, nsIShellService,
 | |
|                   nsIToolkitShellService)
 | |
| 
 | |
| bool nsGNOMEShellService::GetAppPathFromLauncher() {
 | |
|   gchar* tmp;
 | |
| 
 | |
|   const char* launcher = PR_GetEnv("MOZ_APP_LAUNCHER");
 | |
|   if (!launcher) return false;
 | |
| 
 | |
|   if (g_path_is_absolute(launcher)) {
 | |
|     mAppPath = launcher;
 | |
|     tmp = g_path_get_basename(launcher);
 | |
|     gchar* fullpath = g_find_program_in_path(tmp);
 | |
|     if (fullpath && mAppPath.Equals(fullpath)) mAppIsInPath = true;
 | |
|     g_free(fullpath);
 | |
|   } else {
 | |
|     tmp = g_find_program_in_path(launcher);
 | |
|     if (!tmp) return false;
 | |
|     mAppPath = tmp;
 | |
|     mAppIsInPath = true;
 | |
|   }
 | |
| 
 | |
|   g_free(tmp);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool nsGNOMEShellService::KeyMatchesAppName(const char* aKeyValue) const {
 | |
|   gchar* commandPath;
 | |
|   if (mUseLocaleFilenames) {
 | |
|     gchar* nativePath =
 | |
|         g_filename_from_utf8(aKeyValue, -1, nullptr, nullptr, nullptr);
 | |
|     if (!nativePath) {
 | |
|       NS_ERROR("Error converting path to filesystem encoding");
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     commandPath = g_find_program_in_path(nativePath);
 | |
|     g_free(nativePath);
 | |
|   } else {
 | |
|     commandPath = g_find_program_in_path(aKeyValue);
 | |
|   }
 | |
| 
 | |
|   if (!commandPath) return false;
 | |
| 
 | |
|   bool matches = mAppPath.Equals(commandPath);
 | |
|   g_free(commandPath);
 | |
|   return matches;
 | |
| }
 | |
| 
 | |
| bool nsGNOMEShellService::CheckHandlerMatchesAppName(
 | |
|     const nsACString& handler) const {
 | |
|   gint argc;
 | |
|   gchar** argv;
 | |
|   nsAutoCString 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, nullptr) && argc > 0) {
 | |
|     command.Assign(argv[0]);
 | |
|     g_strfreev(argv);
 | |
|   }
 | |
| 
 | |
|   if (!KeyMatchesAppName(command.get()))
 | |
|     return false;  // the handler is set to another app
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::IsDefaultBrowser(bool aForAllTypes,
 | |
|                                       bool* aIsDefaultBrowser) {
 | |
|   *aIsDefaultBrowser = false;
 | |
| 
 | |
|   if (IsRunningAsASnap()) {
 | |
|     const gchar* argv[] = {"xdg-settings", "check", "default-web-browser",
 | |
|                            "firefox.desktop", nullptr};
 | |
|     GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
 | |
|                                                  G_SPAWN_STDERR_TO_DEV_NULL);
 | |
|     gchar* output = nullptr;
 | |
|     gint exit_status = 0;
 | |
|     if (!g_spawn_sync(nullptr, (gchar**)argv, nullptr, flags, nullptr, nullptr,
 | |
|                       &output, nullptr, &exit_status, nullptr)) {
 | |
|       return NS_OK;
 | |
|     }
 | |
|     if (exit_status != 0) {
 | |
|       g_free(output);
 | |
|       return NS_OK;
 | |
|     }
 | |
|     if (strcmp(output, "yes\n") == 0) {
 | |
|       *aIsDefaultBrowser = true;
 | |
|     }
 | |
|     g_free(output);
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 | |
|   nsAutoCString handler;
 | |
|   nsCOMPtr<nsIGIOMimeApp> gioApp;
 | |
| 
 | |
|   for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) {
 | |
|     if (!appProtocols[i].essential) continue;
 | |
| 
 | |
|     if (giovfs) {
 | |
|       handler.Truncate();
 | |
|       nsCOMPtr<nsIHandlerApp> handlerApp;
 | |
|       giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name),
 | |
|                                  getter_AddRefs(handlerApp));
 | |
|       gioApp = do_QueryInterface(handlerApp);
 | |
|       if (!gioApp) return NS_OK;
 | |
| 
 | |
|       gioApp->GetCommand(handler);
 | |
| 
 | |
|       if (!CheckHandlerMatchesAppName(handler))
 | |
|         return NS_OK;  // the handler is set to another app
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   *aIsDefaultBrowser = true;
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) {
 | |
| #ifdef DEBUG
 | |
|   if (aForAllUsers)
 | |
|     NS_WARNING(
 | |
|         "Setting the default browser for all users is not yet supported");
 | |
| #endif
 | |
| 
 | |
|   if (IsRunningAsASnap()) {
 | |
|     const gchar* argv[] = {"xdg-settings", "set", "default-web-browser",
 | |
|                            "firefox.desktop", nullptr};
 | |
|     GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
 | |
|                                                  G_SPAWN_STDOUT_TO_DEV_NULL |
 | |
|                                                  G_SPAWN_STDERR_TO_DEV_NULL);
 | |
|     g_spawn_sync(nullptr, (gchar**)argv, nullptr, flags, nullptr, nullptr,
 | |
|                  nullptr, nullptr, nullptr, nullptr);
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 | |
|   if (giovfs) {
 | |
|     nsresult rv;
 | |
|     nsCOMPtr<nsIStringBundleService> bundleService =
 | |
|         do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     nsCOMPtr<nsIStringBundle> brandBundle;
 | |
|     rv = bundleService->CreateBundle(BRAND_PROPERTIES,
 | |
|                                      getter_AddRefs(brandBundle));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     nsAutoString brandShortName;
 | |
|     brandBundle->GetStringFromName("brandShortName", brandShortName);
 | |
| 
 | |
|     // use brandShortName as the application id.
 | |
|     NS_ConvertUTF16toUTF8 id(brandShortName);
 | |
|     nsCOMPtr<nsIGIOMimeApp> appInfo;
 | |
|     rv = giovfs->FindAppFromCommand(mAppPath, getter_AddRefs(appInfo));
 | |
|     if (NS_FAILED(rv)) {
 | |
|       // Application was not found in the list of installed applications
 | |
|       // provided by OS. Fallback to create appInfo from command and name.
 | |
|       rv = giovfs->CreateAppFromCommand(mAppPath, id, getter_AddRefs(appInfo));
 | |
|       NS_ENSURE_SUCCESS(rv, rv);
 | |
|     }
 | |
| 
 | |
|     // set handler for the protocols
 | |
|     for (unsigned int i = 0; i < ArrayLength(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 < ArrayLength(appTypes); ++i) {
 | |
|         appInfo->SetAsDefaultForMimeType(
 | |
|             nsDependentCString(appTypes[i].mimeType));
 | |
|         appInfo->SetAsDefaultForFileExtensions(
 | |
|             nsDependentCString(appTypes[i].extensions));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
 | |
|   if (prefs) {
 | |
|     (void)prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true);
 | |
|     // Reset the number of times the dialog should be shown
 | |
|     // before it is silenced.
 | |
|     (void)prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::GetCanSetDesktopBackground(bool* aResult) {
 | |
|   // setting desktop background is currently only supported
 | |
|   // for Gnome or desktops using the same GSettings keys
 | |
|   const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
 | |
|   if (currentDesktop && strstr(currentDesktop, "GNOME") != nullptr) {
 | |
|     *aResult = true;
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   const char* gnomeSession = getenv("GNOME_DESKTOP_SESSION_ID");
 | |
|   if (gnomeSession) {
 | |
|     *aResult = true;
 | |
|   } else {
 | |
|     *aResult = false;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| static nsresult WriteImage(const nsCString& aPath, imgIContainer* aImage) {
 | |
| #if !defined(MOZ_WIDGET_GTK)
 | |
|   return NS_ERROR_NOT_AVAILABLE;
 | |
| #else
 | |
|   nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
 | |
|       do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
 | |
|   if (!imgToPixbuf) return NS_ERROR_NOT_AVAILABLE;
 | |
| 
 | |
|   GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage);
 | |
|   if (!pixbuf) return NS_ERROR_NOT_AVAILABLE;
 | |
| 
 | |
|   gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", nullptr, nullptr);
 | |
| 
 | |
|   g_object_unref(pixbuf);
 | |
|   return res ? NS_OK : NS_ERROR_FAILURE;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::SetDesktopBackground(dom::Element* aElement,
 | |
|                                           int32_t aPosition,
 | |
|                                           const nsACString& aImageName) {
 | |
|   nsresult rv;
 | |
|   nsCOMPtr<nsIImageLoadingContent> imageContent =
 | |
|       do_QueryInterface(aElement, &rv);
 | |
|   if (!imageContent) return rv;
 | |
| 
 | |
|   // get the image container
 | |
|   nsCOMPtr<imgIRequest> request;
 | |
|   rv = imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
 | |
|                                 getter_AddRefs(request));
 | |
|   if (!request) return rv;
 | |
|   nsCOMPtr<imgIContainer> container;
 | |
|   rv = request->GetImage(getter_AddRefs(container));
 | |
|   if (!container) return rv;
 | |
| 
 | |
|   // Set desktop wallpaper filling style
 | |
|   nsAutoCString options;
 | |
|   if (aPosition == BACKGROUND_TILE)
 | |
|     options.AssignLiteral("wallpaper");
 | |
|   else if (aPosition == BACKGROUND_STRETCH)
 | |
|     options.AssignLiteral("stretched");
 | |
|   else if (aPosition == BACKGROUND_FILL)
 | |
|     options.AssignLiteral("zoom");
 | |
|   else if (aPosition == BACKGROUND_FIT)
 | |
|     options.AssignLiteral("scaled");
 | |
|   else if (aPosition == BACKGROUND_SPAN)
 | |
|     options.AssignLiteral("spanned");
 | |
|   else
 | |
|     options.AssignLiteral("centered");
 | |
| 
 | |
|   // Write the background file to the home directory.
 | |
|   nsAutoCString filePath(PR_GetEnv("HOME"));
 | |
| 
 | |
|   // get the product brand name from localized strings
 | |
|   nsAutoString brandName;
 | |
|   nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID;
 | |
|   nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(bundleCID));
 | |
|   if (bundleService) {
 | |
|     nsCOMPtr<nsIStringBundle> brandBundle;
 | |
|     rv = bundleService->CreateBundle(BRAND_PROPERTIES,
 | |
|                                      getter_AddRefs(brandBundle));
 | |
|     if (NS_SUCCEEDED(rv) && brandBundle) {
 | |
|       rv = brandBundle->GetStringFromName("brandShortName", brandName);
 | |
|       NS_ENSURE_SUCCESS(rv, rv);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // build the file name
 | |
|   filePath.Append('/');
 | |
|   filePath.Append(NS_ConvertUTF16toUTF8(brandName));
 | |
|   filePath.AppendLiteral("_wallpaper.png");
 | |
| 
 | |
|   // write the image to a file in the home dir
 | |
|   rv = WriteImage(filePath, container);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsCOMPtr<nsIGSettingsService> gsettings =
 | |
|       do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
 | |
|   if (gsettings) {
 | |
|     nsCOMPtr<nsIGSettingsCollection> background_settings;
 | |
|     gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema),
 | |
|                                       getter_AddRefs(background_settings));
 | |
|     if (background_settings) {
 | |
|       gchar* file_uri = g_filename_to_uri(filePath.get(), nullptr, nullptr);
 | |
|       if (!file_uri) return NS_ERROR_FAILURE;
 | |
| 
 | |
|       background_settings->SetString(NS_LITERAL_CSTRING(kDesktopOptionGSKey),
 | |
|                                      options);
 | |
| 
 | |
|       background_settings->SetString(NS_LITERAL_CSTRING(kDesktopImageGSKey),
 | |
|                                      nsDependentCString(file_uri));
 | |
|       g_free(file_uri);
 | |
|       background_settings->SetBoolean(NS_LITERAL_CSTRING(kDesktopDrawBGGSKey),
 | |
|                                       true);
 | |
|       return rv;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NS_ERROR_FAILURE;
 | |
| }
 | |
| 
 | |
| #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8)
 | |
| #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c))
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::GetDesktopBackgroundColor(uint32_t* aColor) {
 | |
|   nsCOMPtr<nsIGSettingsService> gsettings =
 | |
|       do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
 | |
|   nsCOMPtr<nsIGSettingsCollection> background_settings;
 | |
|   nsAutoCString background;
 | |
| 
 | |
|   if (gsettings) {
 | |
|     gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema),
 | |
|                                       getter_AddRefs(background_settings));
 | |
|     if (background_settings) {
 | |
|       background_settings->GetString(NS_LITERAL_CSTRING(kDesktopColorGSKey),
 | |
|                                      background);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (background.IsEmpty()) {
 | |
|     *aColor = 0;
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   GdkColor color;
 | |
|   gboolean success = gdk_color_parse(background.get(), &color);
 | |
| 
 | |
|   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
 | |
| 
 | |
|   *aColor = COLOR_16_TO_8_BIT(color.red) << 16 |
 | |
|             COLOR_16_TO_8_BIT(color.green) << 8 | COLOR_16_TO_8_BIT(color.blue);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| static void ColorToCString(uint32_t aColor, nsCString& aResult) {
 | |
|   // The #rrrrggggbbbb format is used to match gdk_color_to_string()
 | |
|   aResult.SetLength(13);
 | |
|   char* buf = aResult.BeginWriting();
 | |
|   if (!buf) return;
 | |
| 
 | |
|   uint16_t red = COLOR_8_TO_16_BIT((aColor >> 16) & 0xff);
 | |
|   uint16_t green = COLOR_8_TO_16_BIT((aColor >> 8) & 0xff);
 | |
|   uint16_t blue = COLOR_8_TO_16_BIT(aColor & 0xff);
 | |
| 
 | |
|   snprintf(buf, 14, "#%04x%04x%04x", red, green, blue);
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsGNOMEShellService::SetDesktopBackgroundColor(uint32_t aColor) {
 | |
|   NS_ASSERTION(aColor <= 0xffffff, "aColor has extra bits");
 | |
|   nsAutoCString colorString;
 | |
|   ColorToCString(aColor, colorString);
 | |
| 
 | |
|   nsCOMPtr<nsIGSettingsService> gsettings =
 | |
|       do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
 | |
|   if (gsettings) {
 | |
|     nsCOMPtr<nsIGSettingsCollection> 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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NS_ERROR_FAILURE;
 | |
| }
 |