mirror of
https://github.com/swaywm/sway.git
synced 2026-04-21 06:46:22 -04:00
Fix get_icon
Property reply functions are now notified if there was an error with the property instead of silent failure. Also issues in `get_item` were resolved.
This commit is contained in:
parent
87035380e3
commit
13b81f9fb9
4 changed files with 47 additions and 17 deletions
|
|
@ -5,6 +5,13 @@
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
extern DBusConnection *conn;
|
extern DBusConnection *conn;
|
||||||
|
|
||||||
|
enum property_status {
|
||||||
|
PROP_EXISTS, /* Will give iter */
|
||||||
|
PROP_ERROR, /* Will not give iter */
|
||||||
|
PROP_BAD_DATA, /* Will not give iter */
|
||||||
|
PROP_WRONG_SIG, /* Will give iter, please be careful */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the signature of the given iter against `sig`. Prefer to
|
* Checks the signature of the given iter against `sig`. Prefer to
|
||||||
* `dbus_message_iter_get_signature` as this one frees the intermediate string.
|
* `dbus_message_iter_get_signature` as this one frees the intermediate string.
|
||||||
|
|
@ -15,8 +22,9 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig);
|
||||||
* Fetches the property and calls `callback` with a message iter pointing it.
|
* Fetches the property and calls `callback` with a message iter pointing it.
|
||||||
* Performs error handling and signature checking.
|
* Performs error handling and signature checking.
|
||||||
*
|
*
|
||||||
* Returns: true if message is successfully sent (will not necessarily arrive)
|
* Returns: true if message is successfully sent and false otherwise. If there
|
||||||
* and false otherwise
|
* is an error getting a property, `callback` will still be run, but with
|
||||||
|
* `status` set to the error.
|
||||||
*
|
*
|
||||||
* NOTE: `expected_signature` must remain valid until the message reply is
|
* NOTE: `expected_signature` must remain valid until the message reply is
|
||||||
* received, please only use 'static signatures.
|
* received, please only use 'static signatures.
|
||||||
|
|
@ -26,7 +34,7 @@ bool dbus_get_prop_async(const char *destination,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
const char *prop,
|
const char *prop,
|
||||||
const char *expected_signature,
|
const char *expected_signature,
|
||||||
void(*callback)(DBusMessageIter *iter, void *data),
|
void(*callback)(DBusMessageIter *iter, void *data, enum property_status status),
|
||||||
void *data);
|
void *data);
|
||||||
/**
|
/**
|
||||||
* Should be called in main loop to dispatch events
|
* Should be called in main loop to dispatch events
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_s
|
||||||
|
|
||||||
struct async_prop_data {
|
struct async_prop_data {
|
||||||
char const *sig;
|
char const *sig;
|
||||||
void(*callback)(DBusMessageIter *, void *);
|
void(*callback)(DBusMessageIter *, void *, enum property_status);
|
||||||
void *usr_data;
|
void *usr_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -160,6 +160,7 @@ static void get_prop_callback(DBusPendingCall *pending, void *_data) {
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
sway_log(L_INFO, "Failure to get property: %s", msg);
|
sway_log(L_INFO, "Failure to get property: %s", msg);
|
||||||
|
data->callback(NULL, data->usr_data, PROP_ERROR);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,16 +170,18 @@ static void get_prop_callback(DBusPendingCall *pending, void *_data) {
|
||||||
dbus_message_iter_init(reply, &iter);
|
dbus_message_iter_init(reply, &iter);
|
||||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
|
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
|
||||||
sway_log(L_ERROR, "Property relpy type incorrect");
|
sway_log(L_ERROR, "Property relpy type incorrect");
|
||||||
|
data->callback(NULL, data->usr_data, PROP_BAD_DATA);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
dbus_message_iter_recurse(&iter, &variant);
|
dbus_message_iter_recurse(&iter, &variant);
|
||||||
|
|
||||||
if (!dbus_message_iter_check_signature(&variant, data->sig)) {
|
if (!dbus_message_iter_check_signature(&variant, data->sig)) {
|
||||||
sway_log(L_INFO, "Property returned has incorrect signatue.");
|
sway_log(L_INFO, "Property returned has incorrect signatue.");
|
||||||
|
data->callback(&variant, data->usr_data, PROP_WRONG_SIG);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->callback(&variant, data->usr_data);
|
data->callback(&variant, data->usr_data, PROP_EXISTS);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
|
@ -199,7 +202,8 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) {
|
||||||
bool dbus_get_prop_async(const char *destination,
|
bool dbus_get_prop_async(const char *destination,
|
||||||
const char *path, const char *iface,
|
const char *path, const char *iface,
|
||||||
const char *prop, const char *expected_signature,
|
const char *prop, const char *expected_signature,
|
||||||
void(*callback)(DBusMessageIter *, void *), void *usr_data) {
|
void(*callback)(DBusMessageIter *, void *, enum property_status),
|
||||||
|
void *usr_data) {
|
||||||
struct async_prop_data *data = malloc(sizeof(struct async_prop_data));
|
struct async_prop_data *data = malloc(sizeof(struct async_prop_data));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,15 @@ void sni_icon_ref_free(struct sni_icon_ref *sni_ref) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gets the pixmap of an icon */
|
/* Gets the pixmap of an icon */
|
||||||
static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) {
|
static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data, enum property_status status) {
|
||||||
|
if (status != PROP_EXISTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct StatusNotifierItem *item = _data;
|
struct StatusNotifierItem *item = _data;
|
||||||
|
|
||||||
DBusMessageIter d_struct; /* (iiay) */
|
DBusMessageIter d_struct; /* (iiay) */
|
||||||
DBusMessageIter icon; /* ay */
|
DBusMessageIter struct_items;
|
||||||
|
DBusMessageIter icon;
|
||||||
|
|
||||||
if (dbus_message_iter_get_element_count(iter) == 0) {
|
if (dbus_message_iter_get_element_count(iter) == 0) {
|
||||||
// Can't recurse if there are no items
|
// Can't recurse if there are no items
|
||||||
|
|
@ -54,16 +58,17 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_iter_recurse(iter, &d_struct);
|
dbus_message_iter_recurse(iter, &d_struct);
|
||||||
|
dbus_message_iter_recurse(&d_struct, &struct_items);
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
dbus_message_iter_get_basic(&d_struct, &width);
|
dbus_message_iter_get_basic(&struct_items, &width);
|
||||||
dbus_message_iter_next(&d_struct);
|
dbus_message_iter_next(&struct_items);
|
||||||
|
|
||||||
int height;
|
int height;
|
||||||
dbus_message_iter_get_basic(&d_struct, &height);
|
dbus_message_iter_get_basic(&struct_items, &height);
|
||||||
dbus_message_iter_next(&d_struct);
|
dbus_message_iter_next(&struct_items);
|
||||||
|
|
||||||
int len = dbus_message_iter_get_element_count(&d_struct);
|
int len = dbus_message_iter_get_element_count(&struct_items);
|
||||||
|
|
||||||
if (!len) {
|
if (!len) {
|
||||||
sway_log(L_ERROR, "No icon data");
|
sway_log(L_ERROR, "No icon data");
|
||||||
|
|
@ -76,7 +81,7 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_iter_recurse(&d_struct, &icon);
|
dbus_message_iter_recurse(&struct_items, &icon);
|
||||||
|
|
||||||
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
|
||||||
// FIXME support a variable stride
|
// FIXME support a variable stride
|
||||||
|
|
@ -131,9 +136,16 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get an icon by its name */
|
/* Get an icon by its name */
|
||||||
static void reply_icon_name(DBusMessageIter *iter, void *_data) {
|
static void reply_icon_name(DBusMessageIter *iter, void *_data, enum property_status status) {
|
||||||
struct StatusNotifierItem *item = _data;
|
struct StatusNotifierItem *item = _data;
|
||||||
|
|
||||||
|
if (status != PROP_EXISTS) {
|
||||||
|
dbus_get_prop_async(item->name, item->object_path,
|
||||||
|
(item->kde_special_snowflake ? KDE_IFACE : FD_IFACE),
|
||||||
|
"IconPixmap", "a(iiay)", reply_icon, item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
dbus_message_iter_get_basic(iter, &icon_name);
|
dbus_message_iter_get_basic(iter, &icon_name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,10 @@ static void register_host(char *name) {
|
||||||
dbus_message_unref(message);
|
dbus_message_unref(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_items_reply(DBusMessageIter *iter, void *_data) {
|
static void get_items_reply(DBusMessageIter *iter, void *_data, enum property_status status) {
|
||||||
|
if (status != PROP_EXISTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
DBusMessageIter array;
|
DBusMessageIter array;
|
||||||
|
|
||||||
// O(n) function, could be faster dynamically reading values
|
// O(n) function, could be faster dynamically reading values
|
||||||
|
|
@ -60,7 +63,10 @@ static void get_items_reply(DBusMessageIter *iter, void *_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void get_obj_items_reply(DBusMessageIter *iter, void *_data) {
|
static void get_obj_items_reply(DBusMessageIter *iter, void *_data, enum property_status status) {
|
||||||
|
if (status != PROP_EXISTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
DBusMessageIter array;
|
DBusMessageIter array;
|
||||||
DBusMessageIter dstruct;
|
DBusMessageIter dstruct;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue