diff --git a/browser/components/shell/nsGNOMEShellService.cpp b/browser/components/shell/nsGNOMEShellService.cpp index 4db6a3a601c8..f9849833b15d 100644 --- a/browser/components/shell/nsGNOMEShellService.cpp +++ b/browser/components/shell/nsGNOMEShellService.cpp @@ -22,6 +22,7 @@ #include "nsIImageLoadingContent.h" #include "imgIRequest.h" #include "imgIContainer.h" +#include "mozilla/GRefPtr.h" #include "mozilla/Sprintf.h" #include "mozilla/WidgetUtils.h" #include "mozilla/WidgetUtilsGtk.h" @@ -357,14 +358,12 @@ nsGNOMEShellService::GetCanSetDesktopBackground(bool* aResult) { } static nsresult WriteImage(const nsCString& aPath, imgIContainer* aImage) { - GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(aImage); + RefPtr pixbuf = nsImageToPixbuf::ImageToPixbuf(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; } diff --git a/hal/linux/UPowerClient.cpp b/hal/linux/UPowerClient.cpp index 8bf732e233f9..1de38ad201ea 100644 --- a/hal/linux/UPowerClient.cpp +++ b/hal/linux/UPowerClient.cpp @@ -9,26 +9,13 @@ #include #include #include -#include "nsAutoRef.h" +#include "mozilla/GRefPtr.h" +#include "mozilla/GUniquePtr.h" #include -/* - * Helper that manages the destruction of glib objects as soon as they leave - * the current scope. - * - * We are specializing nsAutoRef class. - */ - -template <> -class nsAutoRefTraits : public nsPointerRefTraits { - public: - static void Release(GHashTable* ptr) { g_hash_table_unref(ptr); } -}; - using namespace mozilla::dom::battery; -namespace mozilla { -namespace hal_impl { +namespace mozilla::hal_impl { /** * This is the declaration of UPowerClient class. This class is listening and @@ -69,9 +56,8 @@ class UPowerClient { /** * Returns a hash table with the properties of aDevice. - * Note: the caller has to unref the hash table. */ - GHashTable* GetDevicePropertiesSync(DBusGProxy* aProxy); + already_AddRefed GetDevicePropertiesSync(DBusGProxy* aProxy); void GetDevicePropertiesAsync(DBusGProxy* aProxy); static void GetDevicePropertiesCallback(DBusGProxy* aProxy, DBusGProxyCall* aCall, void* aData); @@ -104,16 +90,16 @@ class UPowerClient { void* aData); // The DBus connection object. - DBusGConnection* mDBusConnection; + RefPtr mDBusConnection; // The DBus proxy object to upower. - DBusGProxy* mUPowerProxy; + RefPtr mUPowerProxy; // The path of the tracked device. - gchar* mTrackedDevice; + GUniquePtr mTrackedDevice; // The DBusGProxy for the tracked device. - DBusGProxy* mTrackedDeviceProxy; + RefPtr mTrackedDeviceProxy; double mLevel; bool mCharging; @@ -163,11 +149,7 @@ UPowerClient* UPowerClient::GetInstance() { } UPowerClient::UPowerClient() - : mDBusConnection(nullptr), - mUPowerProxy(nullptr), - mTrackedDevice(nullptr), - mTrackedDeviceProxy(nullptr), - mLevel(kDefaultLevel), + : mLevel(kDefaultLevel), mCharging(kDefaultCharging), mRemainingTime(kDefaultRemainingTime) {} @@ -179,12 +161,12 @@ UPowerClient::~UPowerClient() { } void UPowerClient::BeginListening() { - GError* error = nullptr; - mDBusConnection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + GUniquePtr error; + mDBusConnection = + dont_AddRef(dbus_g_bus_get(DBUS_BUS_SYSTEM, getter_Transfers(error))); if (!mDBusConnection) { HAL_LOG("Failed to open connection to bus: %s\n", error->message); - g_error_free(error); return; } @@ -199,9 +181,9 @@ void UPowerClient::BeginListening() { dbus_connection_add_filter(dbusConnection, ConnectionSignalFilter, this, nullptr); - mUPowerProxy = dbus_g_proxy_new_for_name( + mUPowerProxy = dont_AddRef(dbus_g_proxy_new_for_name( mDBusConnection, "org.freedesktop.UPower", "/org/freedesktop/UPower", - "org.freedesktop.UPower"); + "org.freedesktop.UPower")); UpdateTrackedDeviceSync(); @@ -231,21 +213,15 @@ void UPowerClient::StopListening() { dbus_g_proxy_disconnect_signal(mUPowerProxy, "DeviceChanged", G_CALLBACK(DeviceChanged), this); - g_free(mTrackedDevice); mTrackedDevice = nullptr; if (mTrackedDeviceProxy) { dbus_g_proxy_disconnect_signal(mTrackedDeviceProxy, "PropertiesChanged", G_CALLBACK(PropertiesChanged), this); - - g_object_unref(mTrackedDeviceProxy); mTrackedDeviceProxy = nullptr; } - g_object_unref(mUPowerProxy); mUPowerProxy = nullptr; - - dbus_g_connection_unref(mDBusConnection); mDBusConnection = nullptr; // We should now show the default values, not the latest we got. @@ -258,27 +234,23 @@ void UPowerClient::UpdateTrackedDeviceSync() { GType typeGPtrArray = dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); GPtrArray* devices = nullptr; - GError* error = nullptr; // Reset the current tracked device: - g_free(mTrackedDevice); mTrackedDevice = nullptr; // Reset the current tracked device proxy: if (mTrackedDeviceProxy) { dbus_g_proxy_disconnect_signal(mTrackedDeviceProxy, "PropertiesChanged", G_CALLBACK(PropertiesChanged), this); - - g_object_unref(mTrackedDeviceProxy); mTrackedDeviceProxy = nullptr; } + GUniquePtr error; // If that fails, that likely means upower isn't installed. - if (!dbus_g_proxy_call(mUPowerProxy, "EnumerateDevices", &error, - G_TYPE_INVALID, typeGPtrArray, &devices, - G_TYPE_INVALID)) { + if (!dbus_g_proxy_call(mUPowerProxy, "EnumerateDevices", + getter_Transfers(error), G_TYPE_INVALID, typeGPtrArray, + &devices, G_TYPE_INVALID)) { HAL_LOG("Error: %s\n", error->message); - g_error_free(error); return; } @@ -287,23 +259,25 @@ void UPowerClient::UpdateTrackedDeviceSync() { * TODO: we could try to combine more than one battery. */ for (guint i = 0; i < devices->len; ++i) { - gchar* devicePath = static_cast(g_ptr_array_index(devices, i)); + GUniquePtr devicePath( + static_cast(g_ptr_array_index(devices, i))); + if (mTrackedDevice) { + continue; + } - DBusGProxy* proxy = dbus_g_proxy_new_from_proxy( - mUPowerProxy, "org.freedesktop.DBus.Properties", devicePath); + RefPtr proxy = dont_AddRef(dbus_g_proxy_new_from_proxy( + mUPowerProxy, "org.freedesktop.DBus.Properties", devicePath.get())); - nsAutoRef hashTable(GetDevicePropertiesSync(proxy)); + RefPtr hashTable(GetDevicePropertiesSync(proxy)); if (g_value_get_uint(static_cast( g_hash_table_lookup(hashTable, "Type"))) == sDeviceTypeBattery) { UpdateSavedInfo(hashTable); - mTrackedDevice = devicePath; - mTrackedDeviceProxy = proxy; - break; + mTrackedDevice = std::move(devicePath); + mTrackedDeviceProxy = std::move(proxy); + // Can't break here because we still need to iterate over all other + // devices to free them. } - - g_object_unref(proxy); - g_free(devicePath); } if (mTrackedDeviceProxy) { @@ -326,9 +300,9 @@ void UPowerClient::DeviceChanged(DBusGProxy* aProxy, const gchar* aObjectPath, } #if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 16 - if (g_strcmp0(aObjectPath, aListener->mTrackedDevice)) { + if (g_strcmp0(aObjectPath, aListener->mTrackedDevice.get())) { #else - if (g_ascii_strcasecmp(aObjectPath, aListener->mTrackedDevice)) { + if (g_ascii_strcasecmp(aObjectPath, aListener->mTrackedDevice.get())) { #endif return; } @@ -355,34 +329,35 @@ DBusHandlerResult UPowerClient::ConnectionSignalFilter( return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -GHashTable* UPowerClient::GetDevicePropertiesSync(DBusGProxy* aProxy) { - GError* error = nullptr; - GHashTable* hashTable = nullptr; +already_AddRefed UPowerClient::GetDevicePropertiesSync( + DBusGProxy* aProxy) { + GUniquePtr error; + RefPtr hashTable; GType typeGHashTable = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE); - if (!dbus_g_proxy_call(aProxy, "GetAll", &error, G_TYPE_STRING, - "org.freedesktop.UPower.Device", G_TYPE_INVALID, - typeGHashTable, &hashTable, G_TYPE_INVALID)) { + if (!dbus_g_proxy_call(aProxy, "GetAll", getter_Transfers(error), + G_TYPE_STRING, "org.freedesktop.UPower.Device", + G_TYPE_INVALID, typeGHashTable, + hashTable.StartAssignment(), G_TYPE_INVALID)) { HAL_LOG("Error: %s\n", error->message); - g_error_free(error); return nullptr; } - return hashTable; + return hashTable.forget(); } /* static */ void UPowerClient::GetDevicePropertiesCallback(DBusGProxy* aProxy, DBusGProxyCall* aCall, void* aData) { - GError* error = nullptr; - GHashTable* hashTable = nullptr; + GUniquePtr error; + RefPtr hashTable; GType typeGHashTable = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE); - if (!dbus_g_proxy_end_call(aProxy, aCall, &error, typeGHashTable, &hashTable, + if (!dbus_g_proxy_end_call(aProxy, aCall, getter_Transfers(error), + typeGHashTable, hashTable.StartAssignment(), G_TYPE_INVALID)) { HAL_LOG("Error: %s\n", error->message); - g_error_free(error); } else { sInstance->UpdateSavedInfo(hashTable); hal::NotifyBatteryChange(hal::BatteryInformation( @@ -470,5 +445,4 @@ bool UPowerClient::IsCharging() { return mCharging; } double UPowerClient::GetRemainingTime() { return mRemainingTime; } -} // namespace hal_impl -} // namespace mozilla +} // namespace mozilla::hal_impl diff --git a/hal/moz.build b/hal/moz.build index eb6935eea7cd..71501fddac16 100644 --- a/hal/moz.build +++ b/hal/moz.build @@ -45,6 +45,7 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": "android/AndroidHal.cpp", ] elif CONFIG["OS_TARGET"] == "Linux": + UNIFIED_SOURCES += [ "fallback/FallbackProcessPriority.cpp", "fallback/FallbackScreenConfiguration.cpp", @@ -127,6 +128,8 @@ LOCAL_INCLUDES += [ ] CFLAGS += CONFIG["GLIB_CFLAGS"] +CFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] CFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"] CXXFLAGS += CONFIG["GLIB_CFLAGS"] +CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] CXXFLAGS += CONFIG["MOZ_DBUS_GLIB_CFLAGS"] diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp index c64f2eb067b2..e4b859438786 100644 --- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -16,11 +16,15 @@ #include "nsIObserverService.h" #include "nsCRT.h" #include "mozilla/XREAppData.h" +#include "mozilla/GRefPtr.h" +#include "mozilla/GUniquePtr.h" +#include "mozilla/UniquePtrExtensions.h" #include #include -extern const mozilla::StaticXREAppData* gAppData; +using namespace mozilla; +extern const StaticXREAppData* gAppData; static bool gHasActions = false; static bool gHasCaps = false; @@ -64,7 +68,8 @@ static void notify_closed_marshal(GClosure* closure, GValue* return_value, NS_RELEASE(alert); } -static GdkPixbuf* GetPixbufFromImgRequest(imgIRequest* aRequest) { +static already_AddRefed GetPixbufFromImgRequest( + imgIRequest* aRequest) { nsCOMPtr image; nsresult rv = aRequest->GetImage(getter_AddRefs(image)); if (NS_FAILED(rv)) { @@ -145,14 +150,8 @@ nsAlertsIconListener::OnImageMissing(nsISupports*) { NS_IMETHODIMP nsAlertsIconListener::OnImageReady(nsISupports*, imgIRequest* aRequest) { - GdkPixbuf* imagePixbuf = GetPixbufFromImgRequest(aRequest); - if (!imagePixbuf) { - ShowAlert(nullptr); - } else { - ShowAlert(imagePixbuf); - g_object_unref(imagePixbuf); - } - + RefPtr imagePixbuf = GetPixbufFromImgRequest(aRequest); + ShowAlert(imagePixbuf); return NS_OK; } @@ -202,10 +201,9 @@ nsresult nsAlertsIconListener::ShowAlert(GdkPixbuf* aPixbuf) { g_closure_set_marshal(closure, notify_closed_marshal); mClosureHandler = g_signal_connect_closure(mNotification, "closed", closure, FALSE); - GError* error = nullptr; - if (!notify_notification_show(mNotification, &error)) { + GUniquePtr error; + if (!notify_notification_show(mNotification, getter_Transfers(error))) { NS_WARNING(error->message); - g_error_free(error); return NS_ERROR_FAILURE; } @@ -253,10 +251,9 @@ nsresult nsAlertsIconListener::Close() { return NS_OK; } - GError* error = nullptr; - if (!notify_notification_close(mNotification, &error)) { + GUniquePtr error; + if (!notify_notification_close(mNotification, getter_Transfers(error))) { NS_WARNING(error->message); - g_error_free(error); return NS_ERROR_FAILURE; } diff --git a/toolkit/system/gnome/nsGIOService.cpp b/toolkit/system/gnome/nsGIOService.cpp index 447884c0fef3..1358ea163310 100644 --- a/toolkit/system/gnome/nsGIOService.cpp +++ b/toolkit/system/gnome/nsGIOService.cpp @@ -73,7 +73,7 @@ nsFlatpakHandlerApp::LaunchWithURI( nsIURI* aUri, mozilla::dom::BrowsingContext* aBrowsingContext) { nsCString spec; aUri->GetSpec(spec); - GError* error = nullptr; + GUniquePtr error; // The TMPDIR where files are downloaded when user choose to open them // needs to be accessible from sandbox and host. The default settings @@ -81,12 +81,11 @@ nsFlatpakHandlerApp::LaunchWithURI( // why the gtk_show_uri fails there. // The workaround is to set TMPDIR environment variable in sandbox to // $XDG_CACHE_HOME/tmp before executing Firefox. - gtk_show_uri(nullptr, spec.get(), GDK_CURRENT_TIME, &error); + gtk_show_uri(nullptr, spec.get(), GDK_CURRENT_TIME, getter_Transfers(error)); if (error) { NS_WARNING( nsPrintfCString("Cannot launch flatpak handler: %s", error->message) .get()); - g_error_free(error); return NS_ERROR_FAILURE; } return NS_OK; @@ -100,13 +99,12 @@ nsFlatpakHandlerApp::LaunchWithURI( */ static nsresult GetCommandFromCommandline( nsACString const& aCommandWithArguments, nsACString& aCommand) { - GError* error = nullptr; + GUniquePtr error; gchar** argv = nullptr; if (!g_shell_parse_argv(aCommandWithArguments.BeginReading(), nullptr, &argv, - &error) || + getter_Transfers(error)) || !argv[0]) { g_warning("Cannot parse command with arguments: %s", error->message); - g_error_free(error); g_strfreev(argv); return NS_ERROR_FAILURE; } @@ -121,12 +119,12 @@ class nsGIOMimeApp final : public nsIGIOMimeApp { NS_DECL_NSIHANDLERAPP NS_DECL_NSIGIOMIMEAPP - explicit nsGIOMimeApp(GAppInfo* aApp) : mApp(aApp) {} + explicit nsGIOMimeApp(already_AddRefed aApp) : mApp(aApp) {} private: - ~nsGIOMimeApp() { g_object_unref(mApp); } + ~nsGIOMimeApp() = default; - GAppInfo* mApp; + RefPtr mApp; }; NS_IMPL_ISUPPORTS(nsGIOMimeApp, nsIGIOMimeApp, nsIHandlerApp) @@ -224,12 +222,12 @@ nsGIOMimeApp::LaunchWithURI(nsIURI* aUri, // nsPromiseFlatCString flatUri(aUri); uris.data = const_cast(spec.get()); - GError* error = nullptr; - gboolean result = g_app_info_launch_uris(mApp, &uris, nullptr, &error); + GUniquePtr error; + gboolean result = + g_app_info_launch_uris(mApp, &uris, nullptr, getter_Transfers(error)); if (!result) { g_warning("Cannot launch application: %s", error->message); - g_error_free(error); return NS_ERROR_FAILURE; } @@ -297,20 +295,17 @@ nsGIOMimeApp::GetSupportedURISchemes(nsIUTF8StringEnumerator** aSchemes) { NS_IMETHODIMP nsGIOMimeApp::SetAsDefaultForMimeType(nsACString const& aMimeType) { - char* content_type = - g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get()); + GUniquePtr content_type( + g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get())); if (!content_type) return NS_ERROR_FAILURE; - GError* error = nullptr; - g_app_info_set_as_default_for_type(mApp, content_type, &error); + GUniquePtr error; + g_app_info_set_as_default_for_type(mApp, content_type.get(), + getter_Transfers(error)); if (error) { g_warning("Cannot set application as default for MIME type (%s): %s", PromiseFlatCString(aMimeType).get(), error->message); - g_error_free(error); - g_free(content_type); return NS_ERROR_FAILURE; } - - g_free(content_type); return NS_OK; } /** @@ -321,21 +316,20 @@ nsGIOMimeApp::SetAsDefaultForMimeType(nsACString const& aMimeType) { */ NS_IMETHODIMP nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts) { - GError* error = nullptr; - char* extensions = g_strdup(PromiseFlatCString(fileExts).get()); - char* ext_pos = extensions; + GUniquePtr error; + GUniquePtr extensions(g_strdup(PromiseFlatCString(fileExts).get())); + char* ext_pos = extensions.get(); char* space_pos; while ((space_pos = strchr(ext_pos, ' ')) || (*ext_pos != '\0')) { if (space_pos) { *space_pos = '\0'; } - g_app_info_set_as_default_for_extension(mApp, ext_pos, &error); + g_app_info_set_as_default_for_extension(mApp, ext_pos, + getter_Transfers(error)); if (error) { g_warning("Cannot set application as default for extension (%s): %s", ext_pos, error->message); - g_error_free(error); - g_free(extensions); return NS_ERROR_FAILURE; } if (space_pos) { @@ -344,7 +338,6 @@ nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts) { *ext_pos = '\0'; } } - g_free(extensions); return NS_OK; } @@ -356,15 +349,15 @@ nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts) { */ NS_IMETHODIMP nsGIOMimeApp::SetAsDefaultForURIScheme(nsACString const& aURIScheme) { - GError* error = nullptr; + GUniquePtr error; nsAutoCString contentType("x-scheme-handler/"); contentType.Append(aURIScheme); - g_app_info_set_as_default_for_type(mApp, contentType.get(), &error); + g_app_info_set_as_default_for_type(mApp, contentType.get(), + getter_Transfers(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; } @@ -380,21 +373,18 @@ nsGIOService::GetMimeTypeFromExtension(const nsACString& aExtension, fileExtToUse.Append(aExtension); gboolean result_uncertain; - char* content_type = - g_content_type_guess(fileExtToUse.get(), nullptr, 0, &result_uncertain); - if (!content_type) return NS_ERROR_FAILURE; - - char* mime_type = g_content_type_get_mime_type(content_type); - if (!mime_type) { - g_free(content_type); + GUniquePtr content_type( + g_content_type_guess(fileExtToUse.get(), nullptr, 0, &result_uncertain)); + if (!content_type) { return NS_ERROR_FAILURE; } - aMimeType.Assign(mime_type); - - g_free(mime_type); - g_free(content_type); + GUniquePtr mime_type(g_content_type_get_mime_type(content_type.get())); + if (!mime_type) { + return NS_ERROR_FAILURE; + } + aMimeType.Assign(mime_type.get()); return NS_OK; } // used in nsGNOMERegistry @@ -416,19 +406,18 @@ nsGIOService::GetAppForURIScheme(const nsACString& aURIScheme, // apps, and we're much better off returning an error here instead. return NS_ERROR_FAILURE; } - nsFlatpakHandlerApp* mozApp = new nsFlatpakHandlerApp(); - NS_ADDREF(*aApp = mozApp); + RefPtr mozApp = new nsFlatpakHandlerApp(); + mozApp.forget(aApp); return NS_OK; } - 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 { + RefPtr app_info = dont_AddRef(g_app_info_get_default_for_uri_scheme( + PromiseFlatCString(aURIScheme).get())); + if (!app_info) { return NS_ERROR_FAILURE; } + RefPtr mozApp = new nsGIOMimeApp(app_info.forget()); + mozApp.forget(aApp); return NS_OK; } @@ -456,13 +445,13 @@ nsGIOService::GetAppsForURIScheme(const nsACString& aURIScheme, GList* appInfo = appInfoList; while (appInfo) { nsCOMPtr mimeApp = - new nsGIOMimeApp(G_APP_INFO(appInfo->data)); + new nsGIOMimeApp(dont_AddRef(G_APP_INFO(appInfo->data))); handlersArray->AppendElement(mimeApp); appInfo = appInfo->next; } g_list_free(appInfoList); } - NS_ADDREF(*aResult = handlersArray); + handlersArray.forget(aResult); return NS_OK; } @@ -474,19 +463,21 @@ nsGIOService::GetAppForMimeType(const nsACString& aMimeType, // Flatpak does not reveal installed application to the sandbox, // we need to create generic system handler. if (widget::ShouldUsePortal(widget::PortalKind::MimeHandler)) { - nsFlatpakHandlerApp* mozApp = new nsFlatpakHandlerApp(); - NS_ADDREF(*aApp = mozApp); + RefPtr mozApp = new nsFlatpakHandlerApp(); + mozApp.forget(aApp); return NS_OK; } - char* content_type = - g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get()); - if (!content_type) return NS_ERROR_FAILURE; + GUniquePtr content_type( + g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get())); + if (!content_type) { + return NS_ERROR_FAILURE; + } // GIO returns "unknown" appinfo for the application/octet-stream, which is // useless. It's better to fallback to create appinfo from file extension // later. - if (g_content_type_is_unknown(content_type)) { + if (g_content_type_is_unknown(content_type.get())) { return NS_ERROR_NOT_AVAILABLE; } @@ -496,40 +487,37 @@ nsGIOService::GetAppForMimeType(const nsACString& aMimeType, // registered as defaults for this type. Fake it up by just executing // xdg-open via gio-launch-desktop (which we do have access to) and letting // it figure out which program to execute for this MIME type - GAppInfo* app_info = g_app_info_create_from_commandline( + RefPtr app_info = dont_AddRef(g_app_info_create_from_commandline( "/usr/local/bin/xdg-open", - nsPrintfCString("System default for %s", content_type).get(), - G_APP_INFO_CREATE_NONE, NULL); + nsPrintfCString("System default for %s", content_type.get()).get(), + G_APP_INFO_CREATE_NONE, NULL)); #else - GAppInfo* app_info = g_app_info_get_default_for_type(content_type, false); + RefPtr app_info = + dont_AddRef(g_app_info_get_default_for_type(content_type.get(), false)); #endif - if (app_info) { - nsGIOMimeApp* mozApp = new nsGIOMimeApp(app_info); - NS_ADDREF(*aApp = mozApp); - } else { - g_free(content_type); + if (!app_info) { return NS_ERROR_FAILURE; } - g_free(content_type); + RefPtr mozApp = new nsGIOMimeApp(app_info.forget()); + mozApp.forget(aApp); return NS_OK; } NS_IMETHODIMP nsGIOService::GetDescriptionForMimeType(const nsACString& aMimeType, nsACString& aDescription) { - char* content_type = - g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get()); - if (!content_type) return NS_ERROR_FAILURE; - - char* desc = g_content_type_get_description(content_type); - if (!desc) { - g_free(content_type); + GUniquePtr content_type( + g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get())); + if (!content_type) { return NS_ERROR_FAILURE; } - aDescription.Assign(desc); - g_free(content_type); - g_free(desc); + GUniquePtr desc(g_content_type_get_description(content_type.get())); + if (!desc) { + return NS_ERROR_FAILURE; + } + + aDescription.Assign(desc.get()); return NS_OK; } @@ -538,11 +526,11 @@ nsGIOService::ShowURI(nsIURI* aURI) { nsAutoCString spec; nsresult rv = aURI->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); - GError* error = nullptr; - if (!g_app_info_launch_default_for_uri(spec.get(), nullptr, &error)) { + GUniquePtr error; + if (!g_app_info_launch_default_for_uri(spec.get(), nullptr, + getter_Transfers(error))) { g_warning("Could not launch default application for URI: %s", error->message); - g_error_free(error); return NS_ERROR_FAILURE; } return NS_OK; @@ -550,22 +538,17 @@ nsGIOService::ShowURI(nsIURI* aURI) { NS_IMETHODIMP nsGIOService::ShowURIForInput(const nsACString& aUri) { - GFile* file = g_file_new_for_commandline_arg(PromiseFlatCString(aUri).get()); - char* spec = g_file_get_uri(file); - nsresult rv = NS_ERROR_FAILURE; - GError* error = nullptr; - - g_app_info_launch_default_for_uri(spec, nullptr, &error); + RefPtr file = dont_AddRef( + g_file_new_for_commandline_arg(PromiseFlatCString(aUri).get())); + GUniquePtr spec(g_file_get_uri(file)); + GUniquePtr error; + g_app_info_launch_default_for_uri(spec.get(), nullptr, + getter_Transfers(error)); if (error) { g_warning("Cannot launch default application: %s", error->message); - g_error_free(error); - } else { - rv = NS_OK; + return NS_ERROR_FAILURE; } - g_object_unref(file); - g_free(spec); - - return rv; + return NS_OK; } NS_IMETHODIMP @@ -625,39 +608,37 @@ nsGIOService::OrgFreedesktopFileManager1ShowItems(const nsACString& aPath) { NS_IMETHODIMP nsGIOService::FindAppFromCommand(nsACString const& aCmd, nsIGIOMimeApp** aAppInfo) { - GAppInfo *app_info = nullptr, *app_info_from_list = nullptr; + RefPtr app_info; + GList* apps = g_app_info_get_all(); - GList* apps_p = apps; // 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; + for (GList* node = apps; node; node = node->next) { + RefPtr app_info_from_list = dont_AddRef((GAppInfo*)node->data); + node->data = nullptr; 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)); + GUniquePtr executable(g_find_program_in_path( + g_app_info_get_executable(app_info_from_list))); if (executable && - strcmp(executable, PromiseFlatCString(aCmd).get()) == 0) { - g_object_ref(app_info_from_list); - app_info = app_info_from_list; + strcmp(executable.get(), PromiseFlatCString(aCmd).get()) == 0) { + app_info = std::move(app_info_from_list); + // Can't break here because we need to keep iterating to unref the other + // nodes. } - g_free(executable); } - - g_object_unref(app_info_from_list); - apps_p = apps_p->next; } + g_list_free(apps); - if (app_info) { - nsGIOMimeApp* app = new nsGIOMimeApp(app_info); - NS_ADDREF(*aAppInfo = app); - return NS_OK; + if (!app_info) { + *aAppInfo = nullptr; + return NS_ERROR_NOT_AVAILABLE; } - - *aAppInfo = nullptr; - return NS_ERROR_NOT_AVAILABLE; + RefPtr app = new nsGIOMimeApp(app_info.forget()); + app.forget(aAppInfo); + return NS_OK; } /** @@ -673,7 +654,6 @@ NS_IMETHODIMP nsGIOService::CreateAppFromCommand(nsACString const& cmd, nsACString const& appName, nsIGIOMimeApp** appInfo) { - GError* error = nullptr; *appInfo = nullptr; // Using G_APP_INFO_CREATE_SUPPORTS_URIS calling @@ -683,25 +663,24 @@ nsGIOService::CreateAppFromCommand(nsACString const& cmd, nsAutoCString commandWithoutArgs; nsresult rv = GetCommandFromCommandline(cmd, commandWithoutArgs); NS_ENSURE_SUCCESS(rv, rv); - GAppInfo* app_info = g_app_info_create_from_commandline( + + GUniquePtr error; + RefPtr app_info = dont_AddRef(g_app_info_create_from_commandline( commandWithoutArgs.BeginReading(), PromiseFlatCString(appName).get(), - G_APP_INFO_CREATE_SUPPORTS_URIS, &error); + G_APP_INFO_CREATE_SUPPORTS_URIS, getter_Transfers(error))); if (!app_info) { g_warning("Cannot create application info from command: %s", error->message); - g_error_free(error); return NS_ERROR_FAILURE; } // Check if executable exist in path - gchar* executableWithFullPath = - g_find_program_in_path(commandWithoutArgs.BeginReading()); + GUniquePtr executableWithFullPath( + g_find_program_in_path(commandWithoutArgs.BeginReading())); if (!executableWithFullPath) { return NS_ERROR_FILE_NOT_FOUND; } - g_free(executableWithFullPath); - - nsGIOMimeApp* mozApp = new nsGIOMimeApp(app_info); - NS_ADDREF(*appInfo = mozApp); + RefPtr mozApp = new nsGIOMimeApp(app_info.forget()); + mozApp.forget(appInfo); return NS_OK; } diff --git a/widget/gtk/GRefPtr.h b/widget/gtk/GRefPtr.h index 5b6260f3dbee..aa48467feeeb 100644 --- a/widget/gtk/GRefPtr.h +++ b/widget/gtk/GRefPtr.h @@ -12,6 +12,9 @@ #include #include "mozilla/RefPtr.h" +// TODO: Remove this (we should use GDBus instead, which is not deprecated). +#include + namespace mozilla { template @@ -25,12 +28,17 @@ struct GObjectRefPtrTraits { struct RefPtrTraits : public GObjectRefPtrTraits {}; GOBJECT_TRAITS(GtkWidget) +GOBJECT_TRAITS(GFile) GOBJECT_TRAITS(GMenu) GOBJECT_TRAITS(GMenuItem) GOBJECT_TRAITS(GSimpleAction) GOBJECT_TRAITS(GSimpleActionGroup) GOBJECT_TRAITS(GDBusProxy) +GOBJECT_TRAITS(GAppInfo) GOBJECT_TRAITS(GdkDragContext) +GOBJECT_TRAITS(GdkPixbuf) + +GOBJECT_TRAITS(DBusGProxy) #undef GOBJECT_TRAITS @@ -40,6 +48,30 @@ struct RefPtrTraits { static void Release(GVariant* aVariant) { g_variant_unref(aVariant); } }; +template <> +struct RefPtrTraits { + static void AddRef(GHashTable* aObject) { g_hash_table_ref(aObject); } + static void Release(GHashTable* aObject) { g_hash_table_unref(aObject); } +}; + +template <> +struct RefPtrTraits { + static void AddRef(GDBusNodeInfo* aObject) { g_dbus_node_info_ref(aObject); } + static void Release(GDBusNodeInfo* aObject) { + g_dbus_node_info_unref(aObject); + } +}; + +template <> +struct RefPtrTraits { + static void AddRef(DBusGConnection* aObject) { + dbus_g_connection_ref(aObject); + } + static void Release(DBusGConnection* aObject) { + dbus_g_connection_unref(aObject); + } +}; + } // namespace mozilla #endif diff --git a/widget/gtk/MPRISServiceHandler.cpp b/widget/gtk/MPRISServiceHandler.cpp index 4daf3c8f7e83..ad85082f78c5 100644 --- a/widget/gtk/MPRISServiceHandler.cpp +++ b/widget/gtk/MPRISServiceHandler.cpp @@ -12,14 +12,18 @@ #include "MPRISInterfaceDescription.h" #include "mozilla/dom/MediaControlUtils.h" +#include "mozilla/GUniquePtr.h" +#include "mozilla/UniquePtrExtensions.h" #include "mozilla/Maybe.h" #include "mozilla/ScopeExit.h" #include "mozilla/Sprintf.h" +#include "nsXULAppAPI.h" #include "nsIXULAppInfo.h" #include "nsIOutputStream.h" #include "nsNetUtil.h" #include "nsServiceManagerUtils.h" #include "WidgetUtilsGtk.h" +#include "prio.h" #define LOGMPRIS(msg, ...) \ MOZ_LOG(gMediaControlLog, LogLevel::Debug, \ @@ -32,19 +36,19 @@ namespace widget { // used to form a unique image file name. static uint32_t gImageNumber = 0; -static inline Maybe GetMediaControlKey( +static inline Maybe GetMediaControlKey( const gchar* aMethodName) { - const std::unordered_map map = { - {"Raise", mozilla::dom::MediaControlKey::Focus}, - {"Next", mozilla::dom::MediaControlKey::Nexttrack}, - {"Previous", mozilla::dom::MediaControlKey::Previoustrack}, - {"Pause", mozilla::dom::MediaControlKey::Pause}, - {"PlayPause", mozilla::dom::MediaControlKey::Playpause}, - {"Stop", mozilla::dom::MediaControlKey::Stop}, - {"Play", mozilla::dom::MediaControlKey::Play}}; + const std::unordered_map map = { + {"Raise", dom::MediaControlKey::Focus}, + {"Next", dom::MediaControlKey::Nexttrack}, + {"Previous", dom::MediaControlKey::Previoustrack}, + {"Pause", dom::MediaControlKey::Pause}, + {"PlayPause", dom::MediaControlKey::Playpause}, + {"Stop", dom::MediaControlKey::Stop}, + {"Play", dom::MediaControlKey::Play}}; auto it = map.find(aMethodName); - return (it == map.end() ? Nothing() : Some(it->second)); + return it == map.end() ? Nothing() : Some(it->second); } static void HandleMethodCall(GDBusConnection* aConnection, const gchar* aSender, @@ -56,7 +60,7 @@ static void HandleMethodCall(GDBusConnection* aConnection, const gchar* aSender, MOZ_ASSERT(aUserData); MOZ_ASSERT(NS_IsMainThread()); - Maybe key = GetMediaControlKey(aMethodName); + Maybe key = GetMediaControlKey(aMethodName); if (key.isNothing()) { g_dbus_method_invocation_return_error( aInvocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, @@ -94,19 +98,18 @@ enum class Property : uint8_t { eGetMetadata, }; -static inline Maybe GetPairedKey( - Property aProperty) { +static inline Maybe GetPairedKey(Property aProperty) { switch (aProperty) { case Property::eCanRaise: - return Some(mozilla::dom::MediaControlKey::Focus); + return Some(dom::MediaControlKey::Focus); case Property::eCanGoNext: - return Some(mozilla::dom::MediaControlKey::Nexttrack); + return Some(dom::MediaControlKey::Nexttrack); case Property::eCanGoPrevious: - return Some(mozilla::dom::MediaControlKey::Previoustrack); + return Some(dom::MediaControlKey::Previoustrack); case Property::eCanPlay: - return Some(mozilla::dom::MediaControlKey::Play); + return Some(dom::MediaControlKey::Play); case Property::eCanPause: - return Some(mozilla::dom::MediaControlKey::Pause); + return Some(dom::MediaControlKey::Pause); default: return Nothing(); } @@ -179,7 +182,7 @@ static GVariant* HandleGetProperty(GDBusConnection* aConnection, case Property::eCanGoPrevious: case Property::eCanPlay: case Property::eCanPause: - Maybe key = GetPairedKey(property.value()); + Maybe key = GetPairedKey(property.value()); MOZ_ASSERT(key.isSome()); return g_variant_new_boolean(handler->IsMediaKeySupported(key.value())); } @@ -266,43 +269,37 @@ void MPRISServiceHandler::OnNameLost(GDBusConnection* aConnection, void MPRISServiceHandler::OnBusAcquired(GDBusConnection* aConnection, const gchar* aName) { - GError* error = nullptr; + GUniquePtr error; LOGMPRIS("OnBusAcquired: %s", aName); mRootRegistrationId = g_dbus_connection_register_object( aConnection, DBUS_MPRIS_OBJECT_PATH, mIntrospectionData->interfaces[0], - &gInterfaceVTable, this, /* user_data */ - nullptr, /* user_data_free_func */ - &error); /* GError** */ + &gInterfaceVTable, this, /* user_data */ + nullptr, /* user_data_free_func */ + getter_Transfers(error)); /* GError** */ if (mRootRegistrationId == 0) { LOGMPRIS("Failed at root registration: %s", error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } return; } mPlayerRegistrationId = g_dbus_connection_register_object( aConnection, DBUS_MPRIS_OBJECT_PATH, mIntrospectionData->interfaces[1], - &gInterfaceVTable, this, /* user_data */ - nullptr, /* user_data_free_func */ - &error); /* GError** */ + &gInterfaceVTable, this, /* user_data */ + nullptr, /* user_data_free_func */ + getter_Transfers(error)); /* GError** */ if (mPlayerRegistrationId == 0) { LOGMPRIS("Failed at object registration: %s", error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } } } bool MPRISServiceHandler::Open() { MOZ_ASSERT(!mInitialized); MOZ_ASSERT(NS_IsMainThread()); - GError* error = nullptr; + GUniquePtr error; gchar serviceName[256]; InitIdentity(); @@ -315,14 +312,12 @@ bool MPRISServiceHandler::Open() { OnNameAcquiredStatic, OnNameLostStatic, this, nullptr); /* parse introspection data */ - mIntrospectionData = g_dbus_node_info_new_for_xml(introspection_xml, &error); + mIntrospectionData = dont_AddRef( + g_dbus_node_info_new_for_xml(introspection_xml, getter_Transfers(error))); if (!mIntrospectionData) { LOGMPRIS("Failed at parsing XML Interface definition: %s", error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } return false; } @@ -330,8 +325,9 @@ bool MPRISServiceHandler::Open() { return true; } +MPRISServiceHandler::MPRISServiceHandler() = default; MPRISServiceHandler::~MPRISServiceHandler() { - MOZ_ASSERT(!mInitialized); // Close hasn't been called! + MOZ_ASSERT(!mInitialized, "Close hasn't been called!"); } void MPRISServiceHandler::Close() { @@ -347,9 +343,8 @@ void MPRISServiceHandler::Close() { if (mOwnerId != 0) { g_bus_unown_name(mOwnerId); } - if (mIntrospectionData) { - g_dbus_node_info_unref(mIntrospectionData); - } + + mIntrospectionData = nullptr; mInitialized = false; MediaControlKeySource::Close(); @@ -385,7 +380,7 @@ const char* MPRISServiceHandler::DesktopEntry() const { return mDesktopEntry.get(); } -bool MPRISServiceHandler::PressKey(mozilla::dom::MediaControlKey aKey) const { +bool MPRISServiceHandler::PressKey(dom::MediaControlKey aKey) const { MOZ_ASSERT(mInitialized); if (!IsMediaKeySupported(aKey)) { LOGMPRIS("%s is not supported", ToMediaControlKeyStr(aKey)); @@ -444,7 +439,7 @@ void MPRISServiceHandler::SetMediaMetadata( // 1) MPRIS image is being fetched, and the one in fetching is in the artwork // 2) MPRIS image is not being fetched, and the one in use is in the artwork if (!mFetchingUrl.IsEmpty()) { - if (mozilla::dom::IsImageIn(aMetadata.mArtwork, mFetchingUrl)) { + if (dom::IsImageIn(aMetadata.mArtwork, mFetchingUrl)) { LOGMPRIS( "No need to load MPRIS image. The one being processed is in the " "artwork"); @@ -454,7 +449,7 @@ void MPRISServiceHandler::SetMediaMetadata( return; } } else if (!mCurrentImageUrl.IsEmpty()) { - if (mozilla::dom::IsImageIn(aMetadata.mArtwork, mCurrentImageUrl)) { + if (dom::IsImageIn(aMetadata.mArtwork, mCurrentImageUrl)) { LOGMPRIS("No need to load MPRIS image. The one in use is in the artwork"); SetMediaMetadataInternal(aMetadata, false); return; @@ -508,9 +503,9 @@ void MPRISServiceHandler::LoadImageAtIndex(const size_t aIndex) { return; } - const mozilla::dom::MediaImage& image = mMPRISMetadata.mArtwork[aIndex]; + const dom::MediaImage& image = mMPRISMetadata.mArtwork[aIndex]; - if (!mozilla::dom::IsValidImageUrl(image.mSrc)) { + if (!dom::IsValidImageUrl(image.mSrc)) { LOGMPRIS("Skip the image with invalid URL. Try next image"); LoadImageAtIndex(mNextImageIndex++); return; @@ -519,7 +514,7 @@ void MPRISServiceHandler::LoadImageAtIndex(const size_t aIndex) { mImageFetchRequest.DisconnectIfExists(); mFetchingUrl = image.mSrc; - mImageFetcher = mozilla::MakeUnique(image); + mImageFetcher = MakeUnique(image); RefPtr self = this; mImageFetcher->FetchImage() ->Then( @@ -532,7 +527,7 @@ void MPRISServiceHandler::LoadImageAtIndex(const size_t aIndex) { char* data = nullptr; // Only used to hold the image data nsCOMPtr inputStream; - nsresult rv = mozilla::dom::GetEncodedImageBuffer( + nsresult rv = dom::GetEncodedImageBuffer( aImage, mMimeType, getter_AddRefs(inputStream), &size, &data); if (NS_FAILED(rv) || !inputStream || size == 0 || !data) { LOGMPRIS("Failed to get the image buffer info. Try next image"); @@ -754,9 +749,9 @@ GVariant* MPRISServiceHandler::GetMetadataAsGVariant() const { return g_variant_builder_end(&builder); } -void MPRISServiceHandler::EmitEvent(mozilla::dom::MediaControlKey aKey) const { +void MPRISServiceHandler::EmitEvent(dom::MediaControlKey aKey) const { for (const auto& listener : mListeners) { - listener->OnActionPerformed(mozilla::dom::MediaControlAction(aKey)); + listener->OnActionPerformed(dom::MediaControlAction(aKey)); } } @@ -764,23 +759,21 @@ struct InterfaceProperty { const char* interface; const char* property; }; -static const std::unordered_map - gKeyProperty = {{mozilla::dom::MediaControlKey::Focus, - {DBUS_MPRIS_INTERFACE, "CanRaise"}}, - {mozilla::dom::MediaControlKey::Nexttrack, - {DBUS_MPRIS_PLAYER_INTERFACE, "CanGoNext"}}, - {mozilla::dom::MediaControlKey::Previoustrack, - {DBUS_MPRIS_PLAYER_INTERFACE, "CanGoPrevious"}}, - {mozilla::dom::MediaControlKey::Play, - {DBUS_MPRIS_PLAYER_INTERFACE, "CanPlay"}}, - {mozilla::dom::MediaControlKey::Pause, - {DBUS_MPRIS_PLAYER_INTERFACE, "CanPause"}}}; +static const std::unordered_map + gKeyProperty = { + {dom::MediaControlKey::Focus, {DBUS_MPRIS_INTERFACE, "CanRaise"}}, + {dom::MediaControlKey::Nexttrack, + {DBUS_MPRIS_PLAYER_INTERFACE, "CanGoNext"}}, + {dom::MediaControlKey::Previoustrack, + {DBUS_MPRIS_PLAYER_INTERFACE, "CanGoPrevious"}}, + {dom::MediaControlKey::Play, {DBUS_MPRIS_PLAYER_INTERFACE, "CanPlay"}}, + {dom::MediaControlKey::Pause, + {DBUS_MPRIS_PLAYER_INTERFACE, "CanPause"}}}; void MPRISServiceHandler::SetSupportedMediaKeys( const MediaKeysArray& aSupportedKeys) { uint32_t supportedKeys = 0; - for (const mozilla::dom::MediaControlKey& key : aSupportedKeys) { + for (const dom::MediaControlKey& key : aSupportedKeys) { supportedKeys |= GetMediaKeyMask(key); } @@ -804,13 +797,12 @@ void MPRISServiceHandler::SetSupportedMediaKeys( } } -bool MPRISServiceHandler::IsMediaKeySupported( - mozilla::dom::MediaControlKey aKey) const { +bool MPRISServiceHandler::IsMediaKeySupported(dom::MediaControlKey aKey) const { return mSupportedKeys & GetMediaKeyMask(aKey); } -bool MPRISServiceHandler::EmitSupportedKeyChanged( - mozilla::dom::MediaControlKey aKey, bool aSupported) const { +bool MPRISServiceHandler::EmitSupportedKeyChanged(dom::MediaControlKey aKey, + bool aSupported) const { auto it = gKeyProperty.find(aKey); if (it == gKeyProperty.end()) { LOGMPRIS("No property for %s", ToMediaControlKeyStr(aKey)); diff --git a/widget/gtk/MPRISServiceHandler.h b/widget/gtk/MPRISServiceHandler.h index 6d6c89808846..f2b171c87eea 100644 --- a/widget/gtk/MPRISServiceHandler.h +++ b/widget/gtk/MPRISServiceHandler.h @@ -58,11 +58,7 @@ class MPRISServiceHandler final : public dom::MediaControlKeySource { // Note that this constructor does NOT initialize the MPRIS Service but only // this class. The method Open() is responsible for registering and MAY FAIL. - // The image format used in MPRIS is based on the mMimeType here. Although - // IMAGE_JPEG or IMAGE_BMP are valid types as well but a png image with - // transparent background will be converted into a jpeg/bmp file with a - // colored background IMAGE_PNG format seems to be the best choice for now. - MPRISServiceHandler() : mMimeType(IMAGE_PNG){}; + MPRISServiceHandler(); bool Open() override; void Close() override; bool IsOpened() const override; @@ -97,13 +93,17 @@ class MPRISServiceHandler final : public dom::MediaControlKeySource { guint mRootRegistrationId = 0; // This is for the interface org.mpris.MediaPlayer2.Player guint mPlayerRegistrationId = 0; - GDBusNodeInfo* mIntrospectionData = nullptr; + RefPtr mIntrospectionData; GDBusConnection* mConnection = nullptr; bool mInitialized = false; nsAutoCString mIdentity; nsAutoCString mDesktopEntry; - nsCString mMimeType; + // The image format used in MPRIS is based on the mMimeType here. Although + // IMAGE_JPEG or IMAGE_BMP are valid types as well but a png image with + // transparent background will be converted into a jpeg/bmp file with a + // colored background IMAGE_PNG format seems to be the best choice for now. + nsCString mMimeType{IMAGE_PNG}; // A bitmask indicating what keys are enabled uint32_t mSupportedKeys = 0; @@ -132,9 +132,8 @@ class MPRISServiceHandler final : public dom::MediaControlKeySource { nsCOMPtr mLocalImageFile; nsCOMPtr mLocalImageFolder; - mozilla::UniquePtr mImageFetcher; - mozilla::MozPromiseRequestHolder - mImageFetchRequest; + UniquePtr mImageFetcher; + MozPromiseRequestHolder mImageFetchRequest; nsString mFetchingUrl; nsString mCurrentImageUrl; @@ -174,7 +173,7 @@ class MPRISServiceHandler final : public dom::MediaControlKeySource { void SetMediaMetadataInternal(const dom::MediaMetadataBase& aMetadata, bool aClearArtUrl = true); - bool EmitSupportedKeyChanged(mozilla::dom::MediaControlKey aKey, + bool EmitSupportedKeyChanged(dom::MediaControlKey aKey, bool aSupported) const; bool EmitPropertiesChangedSignal(GVariant* aParameters) const; diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp index 8311fc3ef2ee..0b3c0e18d19f 100644 --- a/widget/gtk/nsAppShell.cpp +++ b/widget/gtk/nsAppShell.cpp @@ -19,6 +19,7 @@ #include "mozilla/ProfilerLabels.h" #include "mozilla/ProfilerThreadSleep.h" #include "mozilla/Unused.h" +#include "mozilla/GUniquePtr.h" #include "mozilla/WidgetUtils.h" #include "nsIPowerManagerService.h" #ifdef MOZ_ENABLE_DBUS @@ -37,8 +38,7 @@ # include "nsWaylandDisplay.h" #endif -using mozilla::LazyLogModule; -using mozilla::Unused; +using namespace mozilla; using mozilla::widget::HeadlessScreenHelper; using mozilla::widget::ScreenHelperGTK; using mozilla::widget::ScreenManager; @@ -195,13 +195,12 @@ static DBusHandlerResult ConnectionSignalFilter(DBusConnection* aConnection, // https://github.com/lcp/NetworkManager/blob/240f47c892b4e935a3e92fc09eb15163d1fa28d8/src/nm-sleep-monitor-systemd.c // Use login1 to signal sleep and wake notifications. void nsAppShell::StartDBusListening() { - GError* error = nullptr; - mDBusConnection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + GUniquePtr error; + mDBusConnection = dbus_g_bus_get(DBUS_BUS_SYSTEM, getter_Transfers(error)); if (!mDBusConnection) { NS_WARNING(nsPrintfCString("gds: Failed to open connection to bus %s\n", error->message) .get()); - g_error_free(error); return; } diff --git a/widget/gtk/nsClipboard.cpp b/widget/gtk/nsClipboard.cpp index a7d58c5665b7..ba9a06a3fdd1 100644 --- a/widget/gtk/nsClipboard.cpp +++ b/widget/gtk/nsClipboard.cpp @@ -833,7 +833,7 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } - GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image); + RefPtr pixbuf = nsImageToPixbuf::ImageToPixbuf(image); if (!pixbuf) { LOGCLIP(" nsImageToPixbuf::ImageToPixbuf() failed!\n"); return; @@ -842,7 +842,6 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, LOGCLIP(" Setting pixbuf image data as %s\n", GUniquePtr(gdk_atom_name(selectionTarget)).get()); gtk_selection_data_set_pixbuf(aSelectionData, pixbuf); - g_object_unref(pixbuf); return; } diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index 68d4c6a83496..93a59e6cd0e0 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -1820,14 +1820,13 @@ void nsDragService::SourceDataGet(GtkWidget* aWidget, GdkDragContext* aContext, LOGDRAGSERVICE((" do_QueryInterface failed\n")); return; } - GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image); + RefPtr pixbuf = nsImageToPixbuf::ImageToPixbuf(image); if (!pixbuf) { LOGDRAGSERVICE((" ImageToPixbuf failed\n")); return; } gtk_selection_data_set_pixbuf(aSelectionData, pixbuf); LOGDRAGSERVICE((" image data set\n")); - g_object_unref(pixbuf); } else { void* tmpData = nullptr; uint32_t tmpDataLen = 0; @@ -1955,12 +1954,11 @@ void nsDragService::SetDragIcon(GdkDragContext* aContext) { } } else if (surface) { if (!SetAlphaPixmap(surface, aContext, offsetX, offsetY, dragRect)) { - GdkPixbuf* dragPixbuf = nsImageToPixbuf::SourceSurfaceToPixbuf( + RefPtr dragPixbuf = nsImageToPixbuf::SourceSurfaceToPixbuf( surface, dragRect.width, dragRect.height); if (dragPixbuf) { LOGDRAGSERVICE((" set drag pixbuf")); gtk_drag_set_icon_pixbuf(aContext, dragPixbuf, offsetX, offsetY); - g_object_unref(dragPixbuf); } } } diff --git a/widget/gtk/nsImageToPixbuf.cpp b/widget/gtk/nsImageToPixbuf.cpp index 57d19e46c210..73094b74ef6e 100644 --- a/widget/gtk/nsImageToPixbuf.cpp +++ b/widget/gtk/nsImageToPixbuf.cpp @@ -10,6 +10,8 @@ #include "imgIContainer.h" #include "mozilla/gfx/2D.h" #include "mozilla/RefPtr.h" +#include "GRefPtr.h" +#include "nsCOMPtr.h" using mozilla::gfx::DataSourceSurface; using mozilla::gfx::SurfaceFormat; @@ -20,7 +22,7 @@ inline unsigned char unpremultiply(unsigned char color, unsigned char alpha) { return (color * 255 + alpha / 2) / alpha; } -GdkPixbuf* nsImageToPixbuf::ImageToPixbuf( +already_AddRefed nsImageToPixbuf::ImageToPixbuf( imgIContainer* aImage, const mozilla::Maybe& aOverrideSize) { RefPtr surface; @@ -55,15 +57,14 @@ GdkPixbuf* nsImageToPixbuf::ImageToPixbuf( surface->GetSize().height); } -GdkPixbuf* nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface, - int32_t aWidth, - int32_t aHeight) { +already_AddRefed nsImageToPixbuf::SourceSurfaceToPixbuf( + SourceSurface* aSurface, int32_t aWidth, int32_t aHeight) { MOZ_ASSERT(aWidth <= aSurface->GetSize().width && aHeight <= aSurface->GetSize().height, "Requested rect is bigger than the supplied surface"); - GdkPixbuf* pixbuf = - gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, aWidth, aHeight); + RefPtr pixbuf = + dont_AddRef(gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, aWidth, aHeight)); if (!pixbuf) { return nullptr; } @@ -116,5 +117,5 @@ GdkPixbuf* nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface, dataSurface->Unmap(); - return pixbuf; + return pixbuf.forget(); } diff --git a/widget/gtk/nsImageToPixbuf.h b/widget/gtk/nsImageToPixbuf.h index 381827cc1066..500489d7ebaf 100644 --- a/widget/gtk/nsImageToPixbuf.h +++ b/widget/gtk/nsImageToPixbuf.h @@ -8,6 +8,7 @@ #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" #include "nsSize.h" class imgIContainer; @@ -23,15 +24,11 @@ class nsImageToPixbuf final { public: // Friendlier version of ConvertImageToPixbuf for callers inside of // widget - /** - * The return value of all these, if not null, should be - * released as needed by the caller using g_object_unref. - */ - static GdkPixbuf* ImageToPixbuf( + static already_AddRefed ImageToPixbuf( imgIContainer* aImage, const mozilla::Maybe& aOverrideSize = mozilla::Nothing()); - static GdkPixbuf* SourceSurfaceToPixbuf(SourceSurface* aSurface, - int32_t aWidth, int32_t aHeight); + static already_AddRefed SourceSurfaceToPixbuf( + SourceSurface* aSurface, int32_t aWidth, int32_t aHeight); private: ~nsImageToPixbuf() = default; diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index f51ed1bb3d2a..73e64b8c7553 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -176,17 +176,16 @@ nsLookAndFeel::nsLookAndFeel() { nsWindow::GetSystemGtkWindowDecoration() != nsWindow::GTK_DECORATION_NONE; if (ShouldUsePortal(PortalKind::Settings)) { - GError* error = nullptr; - mDBusSettingsProxy = g_dbus_proxy_new_for_bus_sync( + GUniquePtr error; + mDBusSettingsProxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync( G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, nullptr, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", - "org.freedesktop.portal.Settings", nullptr, &error); + "org.freedesktop.portal.Settings", nullptr, getter_Transfers(error))); if (mDBusSettingsProxy) { g_signal_connect(mDBusSettingsProxy, "g-signal", G_CALLBACK(settings_changed_signal_cb), nullptr); } else { LOGLNF("Can't create DBus proxy for settings: %s\n", error->message); - g_error_free(error); } } } @@ -196,7 +195,7 @@ nsLookAndFeel::~nsLookAndFeel() { g_signal_handlers_disconnect_by_func( mDBusSettingsProxy, FuncToGpointer(settings_changed_signal_cb), nullptr); - g_object_unref(mDBusSettingsProxy); + mDBusSettingsProxy = nullptr; } g_signal_handlers_disconnect_by_func( gtk_settings_get_default(), FuncToGpointer(settings_changed_cb), nullptr); @@ -1316,15 +1315,15 @@ Maybe nsLookAndFeel::ComputeColorSchemeSetting() { if (!mDBusSettingsProxy) { return Nothing(); } - GError* error = nullptr; + GUniquePtr error; RefPtr variant = dont_AddRef(g_dbus_proxy_call_sync( mDBusSettingsProxy, "Read", g_variant_new("(ss)", "org.freedesktop.appearance", "color-scheme"), G_DBUS_CALL_FLAGS_NONE, - StaticPrefs::widget_gtk_settings_portal_timeout_ms(), nullptr, &error)); + StaticPrefs::widget_gtk_settings_portal_timeout_ms(), nullptr, + getter_Transfers(error))); if (!variant) { LOGLNF("color-scheme query error: %s\n", error->message); - g_error_free(error); return Nothing(); } LOGLNF("color-scheme query result: %s\n", GVariantToString(variant).get()); diff --git a/widget/gtk/nsLookAndFeel.h b/widget/gtk/nsLookAndFeel.h index a9a3869a9786..be5caf0dd6f1 100644 --- a/widget/gtk/nsLookAndFeel.h +++ b/widget/gtk/nsLookAndFeel.h @@ -150,7 +150,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel { return mSystemThemeOverridden ? mAltTheme : mSystemTheme; } - GDBusProxy* mDBusSettingsProxy = nullptr; + RefPtr mDBusSettingsProxy; mozilla::Maybe mColorSchemePreference; int32_t mCaretBlinkTime = 0; int32_t mCaretBlinkCount = -1; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 2821666ed072..4f0e7311282c 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -27,6 +27,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/Assertions.h" #include "mozilla/Components.h" +#include "mozilla/GRefPtr.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/WheelEventBinding.h" #include "mozilla/gfx/2D.h" @@ -3064,7 +3065,7 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor, } nsIntSize rasterSize = size * gtkScale; - GdkPixbuf* pixbuf = + RefPtr pixbuf = nsImageToPixbuf::ImageToPixbuf(aCursor.mContainer, Some(rasterSize)); if (!pixbuf) { return nullptr; @@ -3074,17 +3075,14 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor, // is of course not documented anywhere... // So add one if there isn't one yet if (!gdk_pixbuf_get_has_alpha(pixbuf)) { - GdkPixbuf* alphaBuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0); - g_object_unref(pixbuf); - pixbuf = alphaBuf; - if (!alphaBuf) { + RefPtr alphaBuf = + dont_AddRef(gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0)); + pixbuf = std::move(alphaBuf); + if (!pixbuf) { return nullptr; } } - auto CleanupPixBuf = - mozilla::MakeScopeExit([&]() { g_object_unref(pixbuf); }); - cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, gtkScale, nullptr); if (!surface) { @@ -3092,7 +3090,7 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor, } auto CleanupSurface = - mozilla::MakeScopeExit([&]() { cairo_surface_destroy(surface); }); + MakeScopeExit([&]() { cairo_surface_destroy(surface); }); return gdk_cursor_new_from_surface(gdk_display_get_default(), surface, aCursor.mHotspotX, aCursor.mHotspotY);