56 lines
2.6 KiB
C
56 lines
2.6 KiB
C
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include <atspi/atspi.h>
|
|
#include <dbus/dbus.h>
|
|
|
|
// Use GTK's actual accessibility connection, bypassing the ATK bridge's
|
|
// producer-side event compression. The reader must handle a provider which
|
|
// delivers every stale claim, as in the captured timeline refresh.
|
|
static void emit_event(DBusConnection *bus, const char *path, const char *member,
|
|
const char *detail, int detail1, const char *child) {
|
|
DBusMessage *message = dbus_message_new_signal(path, "org.a11y.atspi.Event.Object", member);
|
|
DBusMessageIter body, variant, reference, properties;
|
|
int zero = 0;
|
|
dbus_message_iter_init_append(message, &body);
|
|
dbus_message_iter_append_basic(&body, DBUS_TYPE_STRING, &detail);
|
|
dbus_message_iter_append_basic(&body, DBUS_TYPE_INT32, &detail1);
|
|
dbus_message_iter_append_basic(&body, DBUS_TYPE_INT32, &zero);
|
|
dbus_message_iter_open_container(&body, DBUS_TYPE_VARIANT, child != NULL ? "(so)" : "i", &variant);
|
|
if (child != NULL) {
|
|
const char *sender = dbus_bus_get_unique_name(bus);
|
|
dbus_message_iter_open_container(&variant, DBUS_TYPE_STRUCT, NULL, &reference);
|
|
dbus_message_iter_append_basic(&reference, DBUS_TYPE_STRING, &sender);
|
|
dbus_message_iter_append_basic(&reference, DBUS_TYPE_OBJECT_PATH, &child);
|
|
dbus_message_iter_close_container(&variant, &reference);
|
|
} else {
|
|
dbus_message_iter_append_basic(&variant, DBUS_TYPE_INT32, &zero);
|
|
}
|
|
dbus_message_iter_close_container(&body, &variant);
|
|
dbus_message_iter_open_container(&body, DBUS_TYPE_ARRAY, "{sv}", &properties);
|
|
dbus_message_iter_close_container(&body, &properties);
|
|
dbus_connection_send(bus, message, NULL);
|
|
dbus_message_unref(message);
|
|
}
|
|
|
|
const char *refresh_bus_name(void) {
|
|
return dbus_bus_get_unique_name(atspi_get_a11y_bus());
|
|
}
|
|
|
|
void emit_refresh(const char *tablePath, const char *cellPaths) {
|
|
DBusConnection *bus = atspi_get_a11y_bus();
|
|
gchar **paths = g_strsplit(cellPaths, ",", -1);
|
|
for (guint index = 0; paths[index] != NULL; index++) {
|
|
emit_event(bus, paths[index], "StateChanged", "defunct", 1, NULL);
|
|
}
|
|
for (guint index = 0; paths[index] != NULL; index++) {
|
|
emit_event(bus, paths[index], "StateChanged", "selected", 1, NULL);
|
|
emit_event(bus, tablePath, "SelectionChanged", "", 0, NULL);
|
|
emit_event(bus, paths[index], "StateChanged", "focused", 1, NULL);
|
|
emit_event(bus, tablePath, "ActiveDescendantChanged", "", 1, paths[index]);
|
|
}
|
|
g_strfreev(paths);
|
|
dbus_connection_flush(bus);
|
|
}
|