mirror of
https://github.com/yshui/picom.git
synced 2024-11-18 13:55:36 -05:00
Merge pull request #769 from yshui/dbus-window-object
This commit is contained in:
commit
928963721c
3 changed files with 390 additions and 24 deletions
|
@ -203,6 +203,9 @@ blur-background-exclude = [
|
||||||
# General Settings #
|
# General Settings #
|
||||||
#################################
|
#################################
|
||||||
|
|
||||||
|
# Enable remote control via D-Bus. See the man page for more details.
|
||||||
|
# dbus = true
|
||||||
|
|
||||||
# Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers.
|
# Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers.
|
||||||
# daemon = false
|
# daemon = false
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,9 @@ static inline int lcfg_lookup_bool(const config_t *config, const char *path, boo
|
||||||
int ival;
|
int ival;
|
||||||
|
|
||||||
int ret = config_lookup_bool(config, path, &ival);
|
int ret = config_lookup_bool(config, path, &ival);
|
||||||
if (ret)
|
if (ret) {
|
||||||
*value = ival;
|
*value = ival;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -360,15 +361,21 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
||||||
// Get options from the configuration file. We don't do range checking
|
// Get options from the configuration file. We don't do range checking
|
||||||
// right now. It will be done later
|
// right now. It will be done later
|
||||||
|
|
||||||
|
// --dbus
|
||||||
|
lcfg_lookup_bool(&cfg, "dbus", &opt->dbus);
|
||||||
|
|
||||||
// -D (fade_delta)
|
// -D (fade_delta)
|
||||||
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
if (config_lookup_int(&cfg, "fade-delta", &ival)) {
|
||||||
opt->fade_delta = ival;
|
opt->fade_delta = ival;
|
||||||
|
}
|
||||||
// -I (fade_in_step)
|
// -I (fade_in_step)
|
||||||
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
if (config_lookup_float(&cfg, "fade-in-step", &dval)) {
|
||||||
opt->fade_in_step = normalize_d(dval);
|
opt->fade_in_step = normalize_d(dval);
|
||||||
|
}
|
||||||
// -O (fade_out_step)
|
// -O (fade_out_step)
|
||||||
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
if (config_lookup_float(&cfg, "fade-out-step", &dval)) {
|
||||||
opt->fade_out_step = normalize_d(dval);
|
opt->fade_out_step = normalize_d(dval);
|
||||||
|
}
|
||||||
// -r (shadow_radius)
|
// -r (shadow_radius)
|
||||||
config_lookup_int(&cfg, "shadow-radius", &opt->shadow_radius);
|
config_lookup_int(&cfg, "shadow-radius", &opt->shadow_radius);
|
||||||
// -o (shadow_opacity)
|
// -o (shadow_opacity)
|
||||||
|
@ -378,11 +385,13 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
||||||
// -t (shadow_offset_y)
|
// -t (shadow_offset_y)
|
||||||
config_lookup_int(&cfg, "shadow-offset-y", &opt->shadow_offset_y);
|
config_lookup_int(&cfg, "shadow-offset-y", &opt->shadow_offset_y);
|
||||||
// -i (inactive_opacity)
|
// -i (inactive_opacity)
|
||||||
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
if (config_lookup_float(&cfg, "inactive-opacity", &dval)) {
|
||||||
opt->inactive_opacity = normalize_d(dval);
|
opt->inactive_opacity = normalize_d(dval);
|
||||||
|
}
|
||||||
// --active_opacity
|
// --active_opacity
|
||||||
if (config_lookup_float(&cfg, "active-opacity", &dval))
|
if (config_lookup_float(&cfg, "active-opacity", &dval)) {
|
||||||
opt->active_opacity = normalize_d(dval);
|
opt->active_opacity = normalize_d(dval);
|
||||||
|
}
|
||||||
// --corner-radius
|
// --corner-radius
|
||||||
config_lookup_int(&cfg, "corner-radius", &opt->corner_radius);
|
config_lookup_int(&cfg, "corner-radius", &opt->corner_radius);
|
||||||
// --rounded-corners-exclude
|
// --rounded-corners-exclude
|
||||||
|
@ -390,8 +399,7 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
||||||
// -e (frame_opacity)
|
// -e (frame_opacity)
|
||||||
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
||||||
// -c (shadow_enable)
|
// -c (shadow_enable)
|
||||||
if (config_lookup_bool(&cfg, "shadow", &ival))
|
lcfg_lookup_bool(&cfg, "shadow", shadow_enable);
|
||||||
*shadow_enable = ival;
|
|
||||||
// -m (menu_opacity)
|
// -m (menu_opacity)
|
||||||
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
||||||
log_warn("Option `menu-opacity` is deprecated, and will be removed."
|
log_warn("Option `menu-opacity` is deprecated, and will be removed."
|
||||||
|
|
387
src/dbus.c
387
src/dbus.c
|
@ -72,7 +72,11 @@ typedef uint32_t cdbus_enum_t;
|
||||||
cdbus_reply_errm((ps), dbus_message_new_error_printf( \
|
cdbus_reply_errm((ps), dbus_message_new_error_printf( \
|
||||||
(srcmsg), (err_name), (err_format), ##__VA_ARGS__))
|
(srcmsg), (err_name), (err_format), ##__VA_ARGS__))
|
||||||
|
|
||||||
|
#define PICOM_WINDOW_INTERFACE "picom.Window"
|
||||||
|
#define PICOM_COMPOSITOR_INTERFACE "picom.Compositor"
|
||||||
|
|
||||||
static DBusHandlerResult cdbus_process(DBusConnection *conn, DBusMessage *m, void *);
|
static DBusHandlerResult cdbus_process(DBusConnection *conn, DBusMessage *m, void *);
|
||||||
|
static DBusHandlerResult cdbus_process_windows(DBusConnection *c, DBusMessage *msg, void *ud);
|
||||||
|
|
||||||
static dbus_bool_t cdbus_callback_add_timeout(DBusTimeout *timeout, void *data);
|
static dbus_bool_t cdbus_callback_add_timeout(DBusTimeout *timeout, void *data);
|
||||||
|
|
||||||
|
@ -182,6 +186,9 @@ bool cdbus_init(session_t *ps, const char *uniq) {
|
||||||
dbus_connection_register_object_path(
|
dbus_connection_register_object_path(
|
||||||
cd->dbus_conn, CDBUS_OBJECT_NAME,
|
cd->dbus_conn, CDBUS_OBJECT_NAME,
|
||||||
(DBusObjectPathVTable[]){{NULL, cdbus_process}}, ps);
|
(DBusObjectPathVTable[]){{NULL, cdbus_process}}, ps);
|
||||||
|
dbus_connection_register_fallback(
|
||||||
|
cd->dbus_conn, CDBUS_OBJECT_NAME "/windows",
|
||||||
|
(DBusObjectPathVTable[]){{NULL, cdbus_process_windows}}, ps);
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
ps->dbus_data = NULL;
|
ps->dbus_data = NULL;
|
||||||
|
@ -437,6 +444,56 @@ static bool cdbus_apdarg_wid(session_t *ps attr_unused, DBusMessage *msg, const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to append a Window argument to a message as a variant.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
cdbus_append_wid_variant(session_t *ps attr_unused, DBusMessage *msg, const void *data) {
|
||||||
|
assert(data);
|
||||||
|
cdbus_window_t val = *(const xcb_window_t *)data;
|
||||||
|
|
||||||
|
DBusMessageIter it, it2;
|
||||||
|
dbus_message_iter_init_append(msg, &it);
|
||||||
|
if (!dbus_message_iter_open_container(&it, DBUS_TYPE_VARIANT,
|
||||||
|
CDBUS_TYPE_WINDOW_STR, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_append_basic(&it2, CDBUS_TYPE_WINDOW, &val)) {
|
||||||
|
log_error("Failed to append argument.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_close_container(&it, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to append a bool argument to a message as a variant.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
cdbus_append_bool_variant(session_t *ps attr_unused, DBusMessage *msg, const void *data) {
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
dbus_bool_t val = *(const bool *)data;
|
||||||
|
DBusMessageIter it, it2;
|
||||||
|
dbus_message_iter_init_append(msg, &it);
|
||||||
|
if (!dbus_message_iter_open_container(&it, DBUS_TYPE_VARIANT,
|
||||||
|
DBUS_TYPE_BOOLEAN_AS_STRING, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_append_basic(&it2, DBUS_TYPE_BOOLEAN, &val)) {
|
||||||
|
log_error("Failed to append argument.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_close_container(&it, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to append an cdbus_enum_t argument to a message.
|
* Callback to append an cdbus_enum_t argument to a message.
|
||||||
*/
|
*/
|
||||||
|
@ -467,6 +524,46 @@ cdbus_apdarg_string(session_t *ps attr_unused, DBusMessage *msg, const void *dat
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to append a string argument to a message as a variant.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
cdbus_append_string_variant(session_t *ps attr_unused, DBusMessage *msg, const void *data) {
|
||||||
|
const char *str = *(const char **)data;
|
||||||
|
if (!str) {
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusMessageIter it, it2;
|
||||||
|
dbus_message_iter_init_append(msg, &it);
|
||||||
|
if (!dbus_message_iter_open_container(&it, DBUS_TYPE_VARIANT,
|
||||||
|
DBUS_TYPE_STRING_AS_STRING, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_append_basic(&it2, DBUS_TYPE_STRING, &str)) {
|
||||||
|
log_error("Failed to append argument.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_close_container(&it, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool cdbus_append_empty_dict(session_t *ps attr_unused, DBusMessage *msg,
|
||||||
|
const void *data attr_unused) {
|
||||||
|
DBusMessageIter it, it2;
|
||||||
|
dbus_message_iter_init_append(msg, &it);
|
||||||
|
if (!dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "{sv}", &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dbus_message_iter_close_container(&it, &it2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to append all window IDs to a message.
|
* Callback to append all window IDs to a message.
|
||||||
*/
|
*/
|
||||||
|
@ -517,14 +614,14 @@ static bool cdbus_apdarg_wids(session_t *ps, DBusMessage *msg, const void *data
|
||||||
* add an argument
|
* add an argument
|
||||||
* @param data data pointer to pass to the function
|
* @param data data pointer to pass to the function
|
||||||
*/
|
*/
|
||||||
static bool cdbus_signal(session_t *ps, const char *name,
|
static bool cdbus_signal(session_t *ps, const char *interface, const char *name,
|
||||||
bool (*func)(session_t *ps, DBusMessage *msg, const void *data),
|
bool (*func)(session_t *ps, DBusMessage *msg, const void *data),
|
||||||
const void *data) {
|
const void *data) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
DBusMessage *msg = NULL;
|
DBusMessage *msg = NULL;
|
||||||
|
|
||||||
// Create a signal
|
// Create a signal
|
||||||
msg = dbus_message_new_signal(CDBUS_OBJECT_NAME, CDBUS_INTERFACE_NAME, name);
|
msg = dbus_message_new_signal(CDBUS_OBJECT_NAME, interface, name);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
log_error("Failed to create D-Bus signal.");
|
log_error("Failed to create D-Bus signal.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -553,8 +650,9 @@ static bool cdbus_signal(session_t *ps, const char *name,
|
||||||
/**
|
/**
|
||||||
* Send a signal with a Window ID as argument.
|
* Send a signal with a Window ID as argument.
|
||||||
*/
|
*/
|
||||||
static inline bool cdbus_signal_wid(session_t *ps, const char *name, xcb_window_t wid) {
|
static inline bool
|
||||||
return cdbus_signal(ps, name, cdbus_apdarg_wid, &wid);
|
cdbus_signal_wid(session_t *ps, const char *interface, const char *name, xcb_window_t wid) {
|
||||||
|
return cdbus_signal(ps, interface, name, cdbus_apdarg_wid, &wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -734,6 +832,84 @@ static bool cdbus_process_list_win(session_t *ps, DBusMessage *msg) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a win_get D-Bus request.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
cdbus_process_window_property_get(session_t *ps, DBusMessage *msg, cdbus_window_t wid) {
|
||||||
|
const char *target = NULL;
|
||||||
|
const char *interface = NULL;
|
||||||
|
DBusError err = {};
|
||||||
|
|
||||||
|
if (!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &interface,
|
||||||
|
DBUS_TYPE_STRING, &target, DBUS_TYPE_INVALID)) {
|
||||||
|
log_error("Failed to parse argument of \"Get\" (%s).", err.message);
|
||||||
|
dbus_error_free(&err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(interface, PICOM_WINDOW_INTERFACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto w = find_managed_win(ps, wid);
|
||||||
|
|
||||||
|
if (!w) {
|
||||||
|
log_error("Window %#010x not found.", wid);
|
||||||
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADWIN, CDBUS_ERROR_BADWIN_S, wid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cdbus_m_win_get_do(tgt, member, apdarg_func) \
|
||||||
|
if (!strcmp(#tgt, target)) { \
|
||||||
|
cdbus_reply(ps, msg, apdarg_func, &w->member); \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp("Mapped", target)) {
|
||||||
|
cdbus_reply(ps, msg, cdbus_append_bool_variant,
|
||||||
|
(bool[]){win_is_mapped_in_x(w)});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(target, "Id")) {
|
||||||
|
cdbus_reply(ps, msg, cdbus_append_wid_variant, &w->base.id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// next
|
||||||
|
if (!strcmp("Next", target)) {
|
||||||
|
cdbus_window_t next_id = 0;
|
||||||
|
if (!list_node_is_last(&ps->window_stack, &w->base.stack_neighbour)) {
|
||||||
|
next_id = list_entry(w->base.stack_neighbour.next, struct win,
|
||||||
|
stack_neighbour)
|
||||||
|
->id;
|
||||||
|
}
|
||||||
|
cdbus_reply(ps, msg, cdbus_append_wid_variant, &next_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdbus_m_win_get_do(ClientWin, client_win, cdbus_append_wid_variant);
|
||||||
|
cdbus_m_win_get_do(Leader, leader, cdbus_append_wid_variant);
|
||||||
|
cdbus_m_win_get_do(Name, name, cdbus_append_string_variant);
|
||||||
|
if (!strcmp("Type", target)) {
|
||||||
|
cdbus_reply(ps, msg, cdbus_append_string_variant, &WINTYPES[w->window_type]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcmp("RawFocused", target)) {
|
||||||
|
cdbus_reply(ps, msg, cdbus_append_bool_variant,
|
||||||
|
(bool[]){win_is_focused_raw(ps, w)});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef cdbus_m_win_get_do
|
||||||
|
|
||||||
|
log_error(CDBUS_ERROR_BADTGT_S, target);
|
||||||
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a win_get D-Bus request.
|
* Process a win_get D-Bus request.
|
||||||
*/
|
*/
|
||||||
|
@ -1212,6 +1388,21 @@ static bool cdbus_process_introspect(session_t *ps, DBusMessage *msg) {
|
||||||
" <method name='reset' />\n"
|
" <method name='reset' />\n"
|
||||||
" <method name='repaint' />\n"
|
" <method name='repaint' />\n"
|
||||||
" </interface>\n"
|
" </interface>\n"
|
||||||
|
" <interface name='" PICOM_COMPOSITOR_INTERFACE "'>\n"
|
||||||
|
" <signal name='WinAdded'>\n"
|
||||||
|
" <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" <signal name='WinDestroyed'>\n"
|
||||||
|
" <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" <signal name='WinMapped'>\n"
|
||||||
|
" <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" <signal name='WinUnmapped'>\n"
|
||||||
|
" <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" </interface>\n"
|
||||||
|
" <node name='windows' />\n"
|
||||||
"</node>\n";
|
"</node>\n";
|
||||||
|
|
||||||
cdbus_reply_string(ps, msg, str_introspect);
|
cdbus_reply_string(ps, msg, str_introspect);
|
||||||
|
@ -1220,6 +1411,90 @@ static bool cdbus_process_introspect(session_t *ps, DBusMessage *msg) {
|
||||||
}
|
}
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an D-Bus Introspect request, for /windows.
|
||||||
|
*/
|
||||||
|
static bool cdbus_process_windows_root_introspect(session_t *ps, DBusMessage *msg) {
|
||||||
|
static const char *str_introspect =
|
||||||
|
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||||
|
"1.0//EN\"\n"
|
||||||
|
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||||
|
"<node>\n"
|
||||||
|
" <interface name='org.freedesktop.DBus.Introspectable'>\n"
|
||||||
|
" <method name='Introspect'>\n"
|
||||||
|
" <arg name='data' direction='out' type='s' />\n"
|
||||||
|
" </method>\n"
|
||||||
|
" </interface>\n";
|
||||||
|
|
||||||
|
char *ret = NULL;
|
||||||
|
mstrextend(&ret, str_introspect);
|
||||||
|
|
||||||
|
HASH_ITER2(ps->windows, w) {
|
||||||
|
assert(!w->destroyed);
|
||||||
|
if (!w->managed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *tmp = NULL;
|
||||||
|
asprintf(&tmp, "<node name='%#010x'/>\n", w->id);
|
||||||
|
mstrextend(&ret, tmp);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
mstrextend(&ret, "</node>");
|
||||||
|
|
||||||
|
bool success = cdbus_reply_string(ps, msg, ret);
|
||||||
|
free(ret);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool cdbus_process_window_introspect(session_t *ps, DBusMessage *msg) {
|
||||||
|
// clang-format off
|
||||||
|
static const char *str_introspect =
|
||||||
|
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||||
|
"1.0//EN\"\n"
|
||||||
|
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||||
|
"<node>\n"
|
||||||
|
" <interface name='org.freedesktop.DBus.Introspectable'>\n"
|
||||||
|
" <method name='Introspect'>\n"
|
||||||
|
" <arg name='data' direction='out' type='s' />\n"
|
||||||
|
" </method>\n"
|
||||||
|
" </interface>\n"
|
||||||
|
" <interface name='org.freedesktop.DBus.Properties'>\n"
|
||||||
|
" <method name='Get'>\n"
|
||||||
|
" <arg type='s' name='interface_name' direction='in'/>\n"
|
||||||
|
" <arg type='s' name='property_name' direction='in'/>\n"
|
||||||
|
" <arg type='v' name='value' direction='out'/>\n"
|
||||||
|
" </method>\n"
|
||||||
|
" <method name='GetAll'>\n"
|
||||||
|
" <arg type='s' name='interface_name' direction='in'/>\n"
|
||||||
|
" <arg type='a{sv}' name='properties' direction='out'/>\n"
|
||||||
|
" </method>\n"
|
||||||
|
" <method name='Set'>\n"
|
||||||
|
" <arg type='s' name='interface_name' direction='in'/>\n"
|
||||||
|
" <arg type='s' name='property_name' direction='in'/>\n"
|
||||||
|
" <arg type='v' name='value' direction='in'/>\n"
|
||||||
|
" </method>\n"
|
||||||
|
" <signal name='PropertiesChanged'>\n"
|
||||||
|
" <arg type='s' name='interface_name'/>\n"
|
||||||
|
" <arg type='a{sv}' name='changed_properties'/>\n"
|
||||||
|
" <arg type='as' name='invalidated_properties'/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" </interface>\n"
|
||||||
|
" <interface name='" PICOM_WINDOW_INTERFACE "'>\n"
|
||||||
|
" <property type='" CDBUS_TYPE_WINDOW_STR "' name='Leader' access='read'/>\n"
|
||||||
|
" <property type='" CDBUS_TYPE_WINDOW_STR "' name='ClientWin' access='read'/>\n"
|
||||||
|
" <property type='" CDBUS_TYPE_WINDOW_STR "' name='Id' access='read'/>\n"
|
||||||
|
" <property type='" CDBUS_TYPE_WINDOW_STR "' name='Next' access='read'/>\n"
|
||||||
|
" <property type='b' name='RawFocused' access='read'/>\n"
|
||||||
|
" <property type='b' name='Mapped' access='read'/>\n"
|
||||||
|
" <property type='s' name='Name' access='read'/>\n"
|
||||||
|
" <property type='s' name='Type' access='read'/>\n"
|
||||||
|
" </interface>\n"
|
||||||
|
"</node>\n";
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return cdbus_reply_string(ps, msg, str_introspect);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a message from D-Bus.
|
* Process a message from D-Bus.
|
||||||
*/
|
*/
|
||||||
|
@ -1304,42 +1579,122 @@ cdbus_process(DBusConnection *c attr_unused, DBusMessage *msg, void *ud) {
|
||||||
return handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a message from D-Bus, for /windows path.
|
||||||
|
*/
|
||||||
|
static DBusHandlerResult
|
||||||
|
cdbus_process_windows(DBusConnection *c attr_unused, DBusMessage *msg, void *ud) {
|
||||||
|
session_t *ps = ud;
|
||||||
|
bool handled = false;
|
||||||
|
const char *path = dbus_message_get_path(msg);
|
||||||
|
const char *last_segment = strrchr(path, '/');
|
||||||
|
if (last_segment == NULL) {
|
||||||
|
if (DBUS_MESSAGE_TYPE_METHOD_CALL == dbus_message_get_type(msg) &&
|
||||||
|
!dbus_message_get_no_reply(msg))
|
||||||
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADMSG, CDBUS_ERROR_BADMSG_S);
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
bool is_root = strncmp(last_segment, "/windows", 8) == 0;
|
||||||
|
if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable",
|
||||||
|
"Introspect")) {
|
||||||
|
if (is_root) {
|
||||||
|
handled = cdbus_process_windows_root_introspect(ps, msg);
|
||||||
|
} else {
|
||||||
|
handled = cdbus_process_window_introspect(ps, msg);
|
||||||
|
}
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_root) {
|
||||||
|
auto wid = (cdbus_window_t)strtol(last_segment + 1, NULL, 0);
|
||||||
|
if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties",
|
||||||
|
"GetAll")) {
|
||||||
|
handled = cdbus_reply(ps, msg, cdbus_append_empty_dict, NULL);
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) {
|
||||||
|
handled = cdbus_process_window_property_get(ps, msg, wid);
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameAcquired") ||
|
||||||
|
dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameLost")) {
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DBUS_MESSAGE_TYPE_ERROR == dbus_message_get_type(msg)) {
|
||||||
|
log_error("Error message of path \"%s\" "
|
||||||
|
"interface \"%s\", member \"%s\", error \"%s\"",
|
||||||
|
dbus_message_get_path(msg), dbus_message_get_interface(msg),
|
||||||
|
dbus_message_get_member(msg), dbus_message_get_error_name(msg));
|
||||||
|
} else {
|
||||||
|
log_error("Illegal message of type \"%s\", path \"%s\" "
|
||||||
|
"interface \"%s\", member \"%s\"",
|
||||||
|
cdbus_repr_msgtype(msg), dbus_message_get_path(msg),
|
||||||
|
dbus_message_get_interface(msg), dbus_message_get_member(msg));
|
||||||
|
}
|
||||||
|
if (DBUS_MESSAGE_TYPE_METHOD_CALL == dbus_message_get_type(msg) &&
|
||||||
|
!dbus_message_get_no_reply(msg)) {
|
||||||
|
handled = cdbus_reply_err(ps, msg, CDBUS_ERROR_BADMSG, CDBUS_ERROR_BADMSG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
finished:
|
||||||
|
if (!handled && dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
|
||||||
|
!dbus_message_get_no_reply(msg)) {
|
||||||
|
handled =
|
||||||
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_UNKNOWN, CDBUS_ERROR_UNKNOWN_S);
|
||||||
|
}
|
||||||
|
return handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
/** @name Core callbacks
|
/** @name Core callbacks
|
||||||
*/
|
*/
|
||||||
///@{
|
///@{
|
||||||
void cdbus_ev_win_added(session_t *ps, struct win *w) {
|
void cdbus_ev_win_added(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_added", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_added", w->id);
|
||||||
|
cdbus_signal_wid(ps, PICOM_COMPOSITOR_INTERFACE, "WinAdded", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_destroyed(session_t *ps, struct win *w) {
|
void cdbus_ev_win_destroyed(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_destroyed", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_destroyed", w->id);
|
||||||
|
cdbus_signal_wid(ps, PICOM_COMPOSITOR_INTERFACE, "WinDestroyed", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_mapped(session_t *ps, struct win *w) {
|
void cdbus_ev_win_mapped(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_mapped", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_mapped", w->id);
|
||||||
|
cdbus_signal_wid(ps, PICOM_COMPOSITOR_INTERFACE, "WinMapped", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_unmapped(session_t *ps, struct win *w) {
|
void cdbus_ev_win_unmapped(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_unmapped", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_unmapped", w->id);
|
||||||
|
cdbus_signal_wid(ps, PICOM_COMPOSITOR_INTERFACE, "WinUnmapped", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_focusout(session_t *ps, struct win *w) {
|
void cdbus_ev_win_focusout(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_focusout", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_focusout", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_focusin(session_t *ps, struct win *w) {
|
void cdbus_ev_win_focusin(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn) {
|
||||||
cdbus_signal_wid(ps, "win_focusin", w->id);
|
cdbus_signal_wid(ps, CDBUS_INTERFACE_NAME, "win_focusin", w->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
Loading…
Reference in a new issue