Linux: Handle desktop settings portals that are so old they don't implement ReadOne

Sigh, outdated Linux software, just creating busy work for everyone.
This commit is contained in:
Kovid Goyal 2025-05-08 15:22:42 +05:30
parent 97f9d16046
commit 2fed0ec562
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
5 changed files with 49 additions and 25 deletions

11
glfw/dbus_glfw.c vendored
View file

@ -214,13 +214,6 @@ typedef struct {
void *user_data;
} MethodResponse;
static const char*
format_message_error(DBusError *err) {
static char buf[1024];
snprintf(buf, sizeof(buf), "[%s] %s", err->name ? err->name : "", err->message);
return buf;
}
static void
method_reply_received(DBusPendingCall *pending, void *user_data) {
MethodResponse *res = (MethodResponse*)user_data;
@ -228,7 +221,7 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
if (msg) {
DBusError err;
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, msg)) res->callback(NULL, format_message_error(&err), res->user_data);
if (dbus_set_error_from_message(&err, msg)) res->callback(NULL, &err, res->user_data);
else res->callback(msg, NULL, res->user_data);
}
}
@ -243,7 +236,7 @@ call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_p
DBusError error; dbus_error_init(&error);
RAII_MSG(reply, dbus_connection_send_with_reply_and_block(session_bus, msg, timeout, &error));
if (dbus_error_is_set(&error)) {
callback(reply, error.message, user_data);
callback(reply, &error, user_data);
return false;
} else if (reply) {
callback(reply, NULL, user_data);

2
glfw/dbus_glfw.h vendored
View file

@ -33,7 +33,7 @@
static inline void cleanup_msg(void *p) { DBusMessage *m = *(DBusMessage**)p; if (m) dbus_message_unref(m); m = NULL; }
#define RAII_MSG(name, initializer) __attribute__((cleanup(cleanup_msg))) DBusMessage *name = initializer
typedef void(*dbus_pending_callback)(DBusMessage *msg, const char* err, void* data);
typedef void(*dbus_pending_callback)(DBusMessage *msg, const DBusError *err, void* data);
typedef struct {
EventLoopData* eld;

12
glfw/ibus_glfw.c vendored
View file

@ -373,9 +373,9 @@ read_ibus_address(_GLFWIBUSData *ibus) {
}
void
input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to create input context with error: %s", errmsg);
input_context_created(DBusMessage *msg, const DBusError *err, void *data) {
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to create input context with error: %s: %s", err->name, err->message);
return;
}
const char *path = NULL;
@ -488,15 +488,15 @@ glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h) {
}
void
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
key_event_processed(DBusMessage *msg, const DBusError *err, void *data) {
uint32_t handled = 0;
_GLFWIBUSKeyEvent *ev = (_GLFWIBUSKeyEvent*)data;
// Restore key's text from the text embedded in the structure.
ev->glfw_ev.text = ev->__embedded_text;
bool is_release = ev->glfw_ev.action == GLFW_RELEASE;
bool failed = false;
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s: %s", err->name, err->message);
failed = true;
} else {
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);

View file

@ -24,15 +24,46 @@ static int theme_size = -1;
static GLFWColorScheme appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
static bool cursor_theme_changed = false, appearance_initialized = false;
#define HANDLER(name) static void name(DBusMessage *msg, const char* errmsg, void *data) { \
#define HANDLER(name_) static void name_(DBusMessage *msg, const DBusError* err, void *data) { \
(void)data; \
if (errmsg) { \
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s", #name, errmsg); \
if (err) { \
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s: %s", #name_, err->name, err->message); \
return; \
}
HANDLER(get_color_scheme_legacy)
DBusMessageIter iter, variant_iter, variant_iter2;
if (!dbus_message_iter_init(msg, &iter)) return;
dbus_message_iter_recurse(&iter, &variant_iter);
int type = dbus_message_iter_get_arg_type(&variant_iter);
if (type != DBUS_TYPE_VARIANT) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Read for color-scheme did not return a variant"); return;
}
dbus_message_iter_recurse(&variant_iter, &variant_iter2);
if (type != DBUS_TYPE_VARIANT) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Read for color-scheme did not return a nested variant"); return;
}
uint32_t val;
dbus_message_iter_get_basic(&variant_iter2, &val);
if (val < 3) appearance = val;
}
HANDLER(get_color_scheme)
static void get_color_scheme(DBusMessage *msg, const DBusError* err, void *data) {
(void) data;
if (err) {
if (strcmp("org.freedesktop.DBus.Error.UnknownMethod", err->name) == 0) {
DBusConnection *session_bus = glfw_dbus_session_bus();
if (session_bus) {
const char *namespace = FDO_DESKTOP_NAMESPACE, *key = FDO_APPEARANCE_KEY;
glfw_dbus_call_blocking_method(session_bus, DESKTOP_SERVICE, DESKTOP_PATH, DESKTOP_INTERFACE, "Read", DBUS_TIMEOUT_USE_DEFAULT,
get_color_scheme_legacy, NULL, DBUS_TYPE_STRING, &namespace, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID);
}
return;
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s: %s", "get_color_scheme", err->name, err->message);
return;
}
}
uint32_t val;
DBusMessageIter iter, variant_iter;
if (!dbus_message_iter_init(msg, &iter)) return;

10
glfw/linux_notify.c vendored
View file

@ -32,9 +32,9 @@ glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedf
}
void
notification_created(DBusMessage *msg, const char* errmsg, void *data) {
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s", errmsg);
notification_created(DBusMessage *msg, const DBusError* err, void *data) {
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s: %s", err->name, err->message);
if (data) free(data);
return;
}
@ -95,9 +95,9 @@ cancel_user_notification(DBusConnection *session_bus, uint32_t *id) {
}
static void
got_capabilities(DBusMessage *msg, const char* err, void* data UNUSED) {
got_capabilities(DBusMessage *msg, const DBusError* err, void* data UNUSED) {
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to get server capabilities error: %s", err);
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to get server capabilities error: %s: %s", err->name, err->message);
return;
}
#define check_call(func, err, ...) if (!func(__VA_ARGS__)) { _glfwInputError(GLFW_PLATFORM_ERROR, "Notify: GetCapabilities: %s", err); return; }