Announce the initial row in unselected GTK menus
This commit is contained in:
1 parent
090ac9dbeb
commit
ae53f23c63
6 files changed
+190
-3
No files matched your search
@@ -219,6 +219,44 @@ AtspiAccessible *cthulhu_table_selected_child(AtspiAccessible *source) {
|
||||
return child;
|
||||
}
|
||||
|
||||
// GTK lists populated through stdin can have no selected row at focus time.
|
||||
// Their first navigation starts at row zero. Present that initial row without
|
||||
// selecting it or moving the application's cursor. Selection-change queries
|
||||
// must continue to return only actual selections.
|
||||
AtspiAccessible *cthulhu_table_focus_child(AtspiAccessible *source) {
|
||||
AtspiAccessible *child = cthulhu_table_selected_child(source);
|
||||
if (child != NULL) return child;
|
||||
gchar *toolkit = atspi_accessible_get_toolkit_name(source, NULL);
|
||||
gboolean gtk = g_ascii_strcasecmp(toolkit != NULL ? toolkit : "", "gtk") == 0;
|
||||
g_free(toolkit);
|
||||
if (!gtk) return NULL;
|
||||
AtspiStateSet *states = atspi_accessible_get_state_set(source);
|
||||
gboolean initial = states != NULL &&
|
||||
atspi_state_set_contains(states, ATSPI_STATE_FOCUSED) &&
|
||||
!atspi_state_set_contains(states, ATSPI_STATE_MULTISELECTABLE);
|
||||
if (states != NULL) g_object_unref(states);
|
||||
if (!initial) return NULL;
|
||||
AtspiTable *table = atspi_accessible_get_table_iface(source);
|
||||
if (table == NULL) return NULL;
|
||||
GError *error = NULL;
|
||||
gint selected = atspi_table_get_n_selected_rows(table, &error);
|
||||
if (error == NULL && selected == 0 && atspi_table_get_n_rows(table, NULL) > 0 &&
|
||||
atspi_table_get_n_columns(table, NULL) == 1) {
|
||||
child = atspi_table_get_accessible_at(table, 0, 0, NULL);
|
||||
if (child != NULL) {
|
||||
states = atspi_accessible_get_state_set(child);
|
||||
gboolean showing = states != NULL &&
|
||||
atspi_state_set_contains(states, ATSPI_STATE_SHOWING) &&
|
||||
!atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT);
|
||||
if (states != NULL) g_object_unref(states);
|
||||
if (!showing) { g_object_unref(child); child = NULL; }
|
||||
}
|
||||
}
|
||||
g_clear_error(&error);
|
||||
g_object_unref(table);
|
||||
return child;
|
||||
}
|
||||
|
||||
// Resolve the focused descendant at a window-activation boundary. Providers
|
||||
// such as Steam's Chromium UI can activate a frame without emitting a usable
|
||||
// object-focus event. Keep the synchronous callback work bounded so a broken
|
||||
|
||||
Reference in new issue
Block a user