Bug 1760839 - Use more automatic memory management in GTK code. r=stransky
This fixes a couple potential leaks (e.g., see the UPowerClient changes, we weren't freeing all the devices properly). Differential Revision: https://phabricator.services.mozilla.com/D141775
This commit is contained in:
@@ -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<GdkPixbuf> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,26 +9,13 @@
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
#include <mozilla/Attributes.h>
|
||||
#include <mozilla/dom/battery/Constants.h>
|
||||
#include "nsAutoRef.h"
|
||||
#include "mozilla/GRefPtr.h"
|
||||
#include "mozilla/GUniquePtr.h"
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
* Helper that manages the destruction of glib objects as soon as they leave
|
||||
* the current scope.
|
||||
*
|
||||
* We are specializing nsAutoRef class.
|
||||
*/
|
||||
|
||||
template <>
|
||||
class nsAutoRefTraits<GHashTable> : public nsPointerRefTraits<GHashTable> {
|
||||
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<GHashTable> 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<DBusGConnection> mDBusConnection;
|
||||
|
||||
// The DBus proxy object to upower.
|
||||
DBusGProxy* mUPowerProxy;
|
||||
RefPtr<DBusGProxy> mUPowerProxy;
|
||||
|
||||
// The path of the tracked device.
|
||||
gchar* mTrackedDevice;
|
||||
GUniquePtr<gchar> mTrackedDevice;
|
||||
|
||||
// The DBusGProxy for the tracked device.
|
||||
DBusGProxy* mTrackedDeviceProxy;
|
||||
RefPtr<DBusGProxy> 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<GError> 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<GError> 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<gchar*>(g_ptr_array_index(devices, i));
|
||||
GUniquePtr<gchar> devicePath(
|
||||
static_cast<gchar*>(g_ptr_array_index(devices, i)));
|
||||
if (mTrackedDevice) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DBusGProxy* proxy = dbus_g_proxy_new_from_proxy(
|
||||
mUPowerProxy, "org.freedesktop.DBus.Properties", devicePath);
|
||||
RefPtr<DBusGProxy> proxy = dont_AddRef(dbus_g_proxy_new_from_proxy(
|
||||
mUPowerProxy, "org.freedesktop.DBus.Properties", devicePath.get()));
|
||||
|
||||
nsAutoRef<GHashTable> hashTable(GetDevicePropertiesSync(proxy));
|
||||
RefPtr<GHashTable> hashTable(GetDevicePropertiesSync(proxy));
|
||||
|
||||
if (g_value_get_uint(static_cast<const GValue*>(
|
||||
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<GHashTable> UPowerClient::GetDevicePropertiesSync(
|
||||
DBusGProxy* aProxy) {
|
||||
GUniquePtr<GError> error;
|
||||
RefPtr<GHashTable> 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<GError> error;
|
||||
RefPtr<GHashTable> 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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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 <dlfcn.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
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<GdkPixbuf> GetPixbufFromImgRequest(
|
||||
imgIRequest* aRequest) {
|
||||
nsCOMPtr<imgIContainer> 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 {
|
||||
RefPtr<GdkPixbuf> imagePixbuf = GetPixbufFromImgRequest(aRequest);
|
||||
ShowAlert(imagePixbuf);
|
||||
g_object_unref(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<GError> 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<GError> error;
|
||||
if (!notify_notification_close(mNotification, getter_Transfers(error))) {
|
||||
NS_WARNING(error->message);
|
||||
g_error_free(error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ nsFlatpakHandlerApp::LaunchWithURI(
|
||||
nsIURI* aUri, mozilla::dom::BrowsingContext* aBrowsingContext) {
|
||||
nsCString spec;
|
||||
aUri->GetSpec(spec);
|
||||
GError* error = nullptr;
|
||||
GUniquePtr<GError> 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<GError> 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<GAppInfo> aApp) : mApp(aApp) {}
|
||||
|
||||
private:
|
||||
~nsGIOMimeApp() { g_object_unref(mApp); }
|
||||
~nsGIOMimeApp() = default;
|
||||
|
||||
GAppInfo* mApp;
|
||||
RefPtr<GAppInfo> mApp;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsGIOMimeApp, nsIGIOMimeApp, nsIHandlerApp)
|
||||
@@ -224,12 +222,12 @@ nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
|
||||
// nsPromiseFlatCString flatUri(aUri);
|
||||
uris.data = const_cast<char*>(spec.get());
|
||||
|
||||
GError* error = nullptr;
|
||||
gboolean result = g_app_info_launch_uris(mApp, &uris, nullptr, &error);
|
||||
GUniquePtr<GError> 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<char> 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<GError> 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<GError> error;
|
||||
GUniquePtr<char> 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<GError> 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<char> 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<char> 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<nsFlatpakHandlerApp> 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<GAppInfo> app_info = dont_AddRef(g_app_info_get_default_for_uri_scheme(
|
||||
PromiseFlatCString(aURIScheme).get()));
|
||||
if (!app_info) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
RefPtr<nsGIOMimeApp> 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<nsIGIOMimeApp> 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<nsFlatpakHandlerApp> 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<char> 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<GAppInfo> 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<GAppInfo> 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<nsGIOMimeApp> 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<char> 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<char> 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<GError> 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<GFile> file = dont_AddRef(
|
||||
g_file_new_for_commandline_arg(PromiseFlatCString(aUri).get()));
|
||||
GUniquePtr<char> spec(g_file_get_uri(file));
|
||||
GUniquePtr<GError> 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,40 +608,38 @@ nsGIOService::OrgFreedesktopFileManager1ShowItems(const nsACString& aPath) {
|
||||
NS_IMETHODIMP
|
||||
nsGIOService::FindAppFromCommand(nsACString const& aCmd,
|
||||
nsIGIOMimeApp** aAppInfo) {
|
||||
GAppInfo *app_info = nullptr, *app_info_from_list = nullptr;
|
||||
RefPtr<GAppInfo> 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<GAppInfo> 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<char> 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;
|
||||
}
|
||||
RefPtr<nsGIOMimeApp> app = new nsGIOMimeApp(app_info.forget());
|
||||
app.forget(aAppInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create application info for specified command and application name.
|
||||
@@ -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<GError> error;
|
||||
RefPtr<GAppInfo> 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<gchar> 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<nsGIOMimeApp> mozApp = new nsGIOMimeApp(app_info.forget());
|
||||
mozApp.forget(appInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
// TODO: Remove this (we should use GDBus instead, which is not deprecated).
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template <typename T>
|
||||
@@ -25,12 +28,17 @@ struct GObjectRefPtrTraits {
|
||||
struct RefPtrTraits<type_> : public GObjectRefPtrTraits<type_> {};
|
||||
|
||||
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<GVariant> {
|
||||
static void Release(GVariant* aVariant) { g_variant_unref(aVariant); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RefPtrTraits<GHashTable> {
|
||||
static void AddRef(GHashTable* aObject) { g_hash_table_ref(aObject); }
|
||||
static void Release(GHashTable* aObject) { g_hash_table_unref(aObject); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RefPtrTraits<GDBusNodeInfo> {
|
||||
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<DBusGConnection> {
|
||||
static void AddRef(DBusGConnection* aObject) {
|
||||
dbus_g_connection_ref(aObject);
|
||||
}
|
||||
static void Release(DBusGConnection* aObject) {
|
||||
dbus_g_connection_unref(aObject);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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<mozilla::dom::MediaControlKey> GetMediaControlKey(
|
||||
static inline Maybe<dom::MediaControlKey> GetMediaControlKey(
|
||||
const gchar* aMethodName) {
|
||||
const std::unordered_map<std::string, mozilla::dom::MediaControlKey> 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<std::string, dom::MediaControlKey> 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<mozilla::dom::MediaControlKey> key = GetMediaControlKey(aMethodName);
|
||||
Maybe<dom::MediaControlKey> 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<mozilla::dom::MediaControlKey> GetPairedKey(
|
||||
Property aProperty) {
|
||||
static inline Maybe<dom::MediaControlKey> 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<mozilla::dom::MediaControlKey> key = GetPairedKey(property.value());
|
||||
Maybe<dom::MediaControlKey> key = GetPairedKey(property.value());
|
||||
MOZ_ASSERT(key.isSome());
|
||||
return g_variant_new_boolean(handler->IsMediaKeySupported(key.value()));
|
||||
}
|
||||
@@ -266,21 +269,18 @@ void MPRISServiceHandler::OnNameLost(GDBusConnection* aConnection,
|
||||
|
||||
void MPRISServiceHandler::OnBusAcquired(GDBusConnection* aConnection,
|
||||
const gchar* aName) {
|
||||
GError* error = nullptr;
|
||||
GUniquePtr<GError> 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** */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -288,21 +288,18 @@ void MPRISServiceHandler::OnBusAcquired(GDBusConnection* aConnection,
|
||||
aConnection, DBUS_MPRIS_OBJECT_PATH, mIntrospectionData->interfaces[1],
|
||||
&gInterfaceVTable, this, /* user_data */
|
||||
nullptr, /* user_data_free_func */
|
||||
&error); /* GError** */
|
||||
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<GError> 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<mozilla::dom::FetchImageHelper>(image);
|
||||
mImageFetcher = MakeUnique<dom::FetchImageHelper>(image);
|
||||
RefPtr<MPRISServiceHandler> 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<nsIInputStream> 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<mozilla::dom::MediaControlKey,
|
||||
InterfaceProperty>
|
||||
gKeyProperty = {{mozilla::dom::MediaControlKey::Focus,
|
||||
{DBUS_MPRIS_INTERFACE, "CanRaise"}},
|
||||
{mozilla::dom::MediaControlKey::Nexttrack,
|
||||
static const std::unordered_map<dom::MediaControlKey, InterfaceProperty>
|
||||
gKeyProperty = {
|
||||
{dom::MediaControlKey::Focus, {DBUS_MPRIS_INTERFACE, "CanRaise"}},
|
||||
{dom::MediaControlKey::Nexttrack,
|
||||
{DBUS_MPRIS_PLAYER_INTERFACE, "CanGoNext"}},
|
||||
{mozilla::dom::MediaControlKey::Previoustrack,
|
||||
{dom::MediaControlKey::Previoustrack,
|
||||
{DBUS_MPRIS_PLAYER_INTERFACE, "CanGoPrevious"}},
|
||||
{mozilla::dom::MediaControlKey::Play,
|
||||
{DBUS_MPRIS_PLAYER_INTERFACE, "CanPlay"}},
|
||||
{mozilla::dom::MediaControlKey::Pause,
|
||||
{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));
|
||||
|
||||
@@ -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<GDBusNodeInfo> 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<nsIFile> mLocalImageFile;
|
||||
nsCOMPtr<nsIFile> mLocalImageFolder;
|
||||
|
||||
mozilla::UniquePtr<mozilla::dom::FetchImageHelper> mImageFetcher;
|
||||
mozilla::MozPromiseRequestHolder<mozilla::dom::ImagePromise>
|
||||
mImageFetchRequest;
|
||||
UniquePtr<dom::FetchImageHelper> mImageFetcher;
|
||||
MozPromiseRequestHolder<dom::ImagePromise> 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;
|
||||
|
||||
@@ -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<GError> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -833,7 +833,7 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard,
|
||||
return;
|
||||
}
|
||||
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image);
|
||||
RefPtr<GdkPixbuf> 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<gchar>(gdk_atom_name(selectionTarget)).get());
|
||||
gtk_selection_data_set_pixbuf(aSelectionData, pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1820,14 +1820,13 @@ void nsDragService::SourceDataGet(GtkWidget* aWidget, GdkDragContext* aContext,
|
||||
LOGDRAGSERVICE((" do_QueryInterface failed\n"));
|
||||
return;
|
||||
}
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image);
|
||||
RefPtr<GdkPixbuf> 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<GdkPixbuf> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GdkPixbuf> nsImageToPixbuf::ImageToPixbuf(
|
||||
imgIContainer* aImage, const mozilla::Maybe<nsIntSize>& aOverrideSize) {
|
||||
RefPtr<SourceSurface> surface;
|
||||
|
||||
@@ -55,15 +57,14 @@ GdkPixbuf* nsImageToPixbuf::ImageToPixbuf(
|
||||
surface->GetSize().height);
|
||||
}
|
||||
|
||||
GdkPixbuf* nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface,
|
||||
int32_t aWidth,
|
||||
int32_t aHeight) {
|
||||
already_AddRefed<GdkPixbuf> 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<GdkPixbuf> 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();
|
||||
}
|
||||
|
||||
@@ -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<GdkPixbuf> ImageToPixbuf(
|
||||
imgIContainer* aImage,
|
||||
const mozilla::Maybe<nsIntSize>& aOverrideSize = mozilla::Nothing());
|
||||
static GdkPixbuf* SourceSurfaceToPixbuf(SourceSurface* aSurface,
|
||||
int32_t aWidth, int32_t aHeight);
|
||||
static already_AddRefed<GdkPixbuf> SourceSurfaceToPixbuf(
|
||||
SourceSurface* aSurface, int32_t aWidth, int32_t aHeight);
|
||||
|
||||
private:
|
||||
~nsImageToPixbuf() = default;
|
||||
|
||||
@@ -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<GError> 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<ColorScheme> nsLookAndFeel::ComputeColorSchemeSetting() {
|
||||
if (!mDBusSettingsProxy) {
|
||||
return Nothing();
|
||||
}
|
||||
GError* error = nullptr;
|
||||
GUniquePtr<GError> error;
|
||||
RefPtr<GVariant> 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());
|
||||
|
||||
@@ -150,7 +150,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
||||
return mSystemThemeOverridden ? mAltTheme : mSystemTheme;
|
||||
}
|
||||
|
||||
GDBusProxy* mDBusSettingsProxy = nullptr;
|
||||
RefPtr<GDBusProxy> mDBusSettingsProxy;
|
||||
mozilla::Maybe<ColorScheme> mColorSchemePreference;
|
||||
int32_t mCaretBlinkTime = 0;
|
||||
int32_t mCaretBlinkCount = -1;
|
||||
|
||||
@@ -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<GdkPixbuf> 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<GdkPixbuf> 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);
|
||||
|
||||
Reference in New Issue
Block a user