a11y: Track window states more closely

Orca ignores events unless the object is inside an object
with role window and states ACTIVE and SHOWING. To arrange
for this, introduce a new ACTIVE platform state, and set it
for windows when they are active.

This gets orca to be a lot more talkative.
This commit is contained in:
Matthias Clasen 2021-04-17 15:23:04 -04:00 committed by Emmanuele Bassi
parent 9fbd11e1be
commit 9e8187bdc4
9 changed files with 64 additions and 0 deletions

View File

@ -150,6 +150,13 @@ collect_states (GtkAtSpiContext *self,
set_atspi_state (&states, ATSPI_STATE_VISIBLE);
if (ctx->accessible_role == GTK_ACCESSIBLE_ROLE_WINDOW)
{
set_atspi_state (&states, ATSPI_STATE_SHOWING);
if (gtk_accessible_get_platform_state (accessible, GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE))
set_atspi_state (&states, ATSPI_STATE_ACTIVE);
}
if (ctx->accessible_role == GTK_ACCESSIBLE_ROLE_TEXT_BOX ||
ctx->accessible_role == GTK_ACCESSIBLE_ROLE_SEARCH_BOX ||
ctx->accessible_role == GTK_ACCESSIBLE_ROLE_SPIN_BUTTON)
@ -888,6 +895,7 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
if (GTK_IS_ROOT (accessible))
{
gtk_at_spi_root_child_changed (self->root, change, accessible);
emit_state_changed (self, "showing", gtk_boolean_accessible_value_get (value));
}
else
{
@ -1084,6 +1092,13 @@ gtk_at_spi_context_platform_change (GtkATContext *ctx,
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED);
emit_state_changed (self, "focused", state);
}
if (changed_platform & GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE)
{
gboolean state = gtk_accessible_get_platform_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE);
emit_state_changed (self, "active", state);
}
}
static void

View File

@ -83,11 +83,13 @@ typedef enum {
typedef enum {
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE
} GtkAccessiblePlatformState;
typedef enum {
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE,
} GtkAccessiblePlatformChange;
typedef enum {

View File

@ -351,6 +351,8 @@ gtk_entry_accessible_get_platform_state (GtkAccessible *self,
return gtk_widget_get_focusable (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}

View File

@ -532,6 +532,8 @@ gtk_password_entry_accessible_get_platform_state (GtkAccessible *se
return gtk_widget_get_focusable (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}

View File

@ -475,6 +475,8 @@ gtk_search_entry_accessible_get_platform_state (GtkAccessible *self
return gtk_widget_get_focusable (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}

View File

@ -633,6 +633,8 @@ gtk_spin_button_accessible_get_platform_state (GtkAccessible *self,
return gtk_widget_get_focusable (spin_button->entry);
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (spin_button->entry);
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}

View File

@ -96,6 +96,9 @@ gtk_test_at_context_platform_change (GtkATContext *self,
if (changed_platform & GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED)
g_print ("*** focused = %d\n",
gtk_accessible_get_platform_state (accessible, GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED));
if (changed_platform & GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE)
g_print ("*** active = %d\n",
gtk_accessible_get_platform_state (accessible, GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE));
}
}

View File

@ -8492,6 +8492,8 @@ gtk_widget_accessible_get_platform_state (GtkAccessible *self,
return gtk_widget_get_focusable (GTK_WIDGET (self));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (self));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}

View File

@ -26,6 +26,7 @@
#include "gtkwindowprivate.h"
#include "gtkaccessibleprivate.h"
#include "gtkaccelgroupprivate.h"
#include "gtkactionable.h"
#include "gtkapplicationprivate.h"
@ -479,6 +480,9 @@ static void gtk_window_shortcut_manager_interface_init (GtkShor
static void gtk_window_root_interface_init (GtkRootInterface *iface);
static void gtk_window_native_interface_init (GtkNativeInterface *iface);
static void gtk_window_accessible_interface_init (GtkAccessibleInterface *iface);
static void ensure_state_flag_backdrop (GtkWidget *widget);
static void unset_titlebar (GtkWindow *window);
@ -493,6 +497,8 @@ gtk_window_update_csd_size (GtkWindow *window,
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkWindow)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE,
gtk_window_accessible_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_window_buildable_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_NATIVE,
@ -502,6 +508,32 @@ G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ROOT,
gtk_window_root_interface_init))
static GtkAccessibleInterface *parent_accessible_iface;
static gboolean
gtk_window_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return parent_accessible_iface->get_platform_state (self, state);
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return gtk_window_is_active (GTK_WINDOW (self));
default:
g_assert_not_reached ();
}
}
static void
gtk_window_accessible_interface_init (GtkAccessibleInterface *iface)
{
parent_accessible_iface = g_type_interface_peek_parent (iface);
iface->get_at_context = parent_accessible_iface->get_at_context;
iface->get_platform_state = gtk_window_accessible_get_platform_state;
}
static void
add_tab_bindings (GtkWidgetClass *widget_class,
GdkModifierType modifiers,
@ -5828,6 +5860,8 @@ _gtk_window_set_is_active (GtkWindow *window,
g_object_unref (focus);
}
gtk_accessible_platform_changed (GTK_ACCESSIBLE (window), GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE);
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_IS_ACTIVE]);
}