More work on cthulhu recognizing focused items that should be read.
This commit is contained in:
1 parent
9374b5a2e5
commit
300f4a7504
9 files changed
+456
-9
No files matched your search
@@ -609,37 +609,68 @@ gboolean cthulhu_may_be_background_notification(AtspiAccessible *source) {
|
||||
|
||||
// Return the containing top-level window. An embedded web dialog is part of
|
||||
// its frame; a standalone dialog directly below the application owns itself.
|
||||
// GTK plugs also publish a frame, but its parent chain crosses the socket's
|
||||
// provider before reaching the host window. Keep that host as the owner while
|
||||
// retaining the source object's provider identity. Same-provider nested frames
|
||||
// retain their existing nearest-window behavior.
|
||||
AtspiAccessible *cthulhu_window_ancestor(AtspiAccessible *source) {
|
||||
if (source == NULL) return NULL;
|
||||
AtspiAccessible *current = g_object_ref(source);
|
||||
AtspiAccessible *window = NULL;
|
||||
for (gint depth = 0; current != NULL && depth < 256; depth++) {
|
||||
GError *error = NULL;
|
||||
AtspiRole role = atspi_accessible_get_role(current, &error);
|
||||
if (error != NULL) {
|
||||
g_clear_error(&error);
|
||||
g_object_unref(current);
|
||||
if (window != NULL) g_object_unref(window);
|
||||
return NULL;
|
||||
}
|
||||
if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) {
|
||||
return current;
|
||||
if (role == ATSPI_ROLE_APPLICATION) {
|
||||
g_object_unref(current);
|
||||
return window;
|
||||
}
|
||||
if ((role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) &&
|
||||
(window == NULL || g_strcmp0(cthulhu_accessible_bus_name(window),
|
||||
cthulhu_accessible_bus_name(current)) != 0)) {
|
||||
if (window != NULL) g_object_unref(window);
|
||||
window = g_object_ref(current);
|
||||
}
|
||||
AtspiAccessible *parent = atspi_accessible_get_parent(current, &error);
|
||||
// Only a frame with parents below the application can be a plug.
|
||||
// Refresh that chain to reject detached sockets, without invalidating
|
||||
// every ordinary top-level window for every accessibility event.
|
||||
if (window != NULL && parent != NULL && error == NULL &&
|
||||
atspi_accessible_get_role(parent, NULL) != ATSPI_ROLE_APPLICATION) {
|
||||
g_object_unref(parent);
|
||||
atspi_accessible_clear_cache_single(current);
|
||||
parent = atspi_accessible_get_parent(current, &error);
|
||||
}
|
||||
// Qt can expose a top-level QWidget as a filler rather than a frame.
|
||||
// Python's Qt utilities use the application-child boundary here.
|
||||
if (parent != NULL && error == NULL && role != ATSPI_ROLE_APPLICATION &&
|
||||
atspi_accessible_get_role(parent, NULL) == ATSPI_ROLE_APPLICATION) {
|
||||
g_object_unref(parent);
|
||||
return current;
|
||||
if (window == NULL || g_strcmp0(cthulhu_accessible_bus_name(window),
|
||||
cthulhu_accessible_bus_name(current)) != 0) {
|
||||
if (window != NULL) g_object_unref(window);
|
||||
return current;
|
||||
}
|
||||
g_object_unref(current);
|
||||
return window;
|
||||
}
|
||||
g_object_unref(current);
|
||||
if (error != NULL) {
|
||||
g_clear_error(&error);
|
||||
if (parent != NULL) g_object_unref(parent);
|
||||
if (window != NULL) g_object_unref(window);
|
||||
return NULL;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (current != NULL) g_object_unref(current);
|
||||
if (current == NULL) return window;
|
||||
if (window != NULL) g_object_unref(window);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user