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