return _directional_depth_first_search(ctx->root, NULL, SEARCH_BACKWARD, _accept_object);
}
+static void _on_chain_end_loop(FlatNaviContext *ctx, search_direction direction)
+{
+ AtspiAccessible *result = (direction == SEARCH_FORWARD) ? _first(ctx) : _last(ctx);
+ g_object_unref(ctx->current);
+ ctx->current = result;
+ ctx->last_entry = LAST_ENTRY_NONE;
+}
+
+static void _on_chain_end_escape(FlatNaviContext *ctx, search_direction direction)
+{
+ static const char action_name[] = "escape";
+
+ gboolean success = FALSE;
+
+ AtspiAction *action = atspi_accessible_get_action_iface(ctx->root);
+ if (!action) {
+ ERROR("Object does not have Action interface");
+ goto end;
+ }
+
+ GError *err = NULL;
+ success = atspi_action_do_action_name(action, action_name, &err);
+ GERROR_CHECK(err);
+ g_object_unref(action);
+
+end:
+ if (success) {
+ DEBUG("Action %s invoked successfully", action_name);
+ } else {
+ ERROR("Action %s failed, falling back to looping over", action_name);
+ _on_chain_end_loop(ctx, direction);
+ }
+}
+
+static void _on_chain_end(FlatNaviContext *ctx, search_direction direction)
+{
+ AtspiRole role = atspi_accessible_get_role(ctx->root, NULL);
+
+ // The default is to loop over when the user makes a flick gesture again
+ // after reaching the end of the focus chain, unless the current context
+ // is a drop-down menu, in which case we try to close it instead.
+
+ if (role == ATSPI_ROLE_COMBO_BOX)
+ _on_chain_end_escape(ctx, direction);
+ else
+ _on_chain_end_loop(ctx, direction);
+}
+
static void _navigate_by_one(FlatNaviContext *ctx, search_direction direction)
{
if (direction != SEARCH_FORWARD && direction != SEARCH_BACKWARD) {
"first item reached or failed");
if (ctx->last_entry == (direction == SEARCH_FORWARD ? LAST_ENTRY_LAST : LAST_ENTRY_FIRST)) {
- AtspiAccessible *result = (direction == SEARCH_FORWARD) ? _first(ctx) : _last(ctx);
- g_object_unref(ctx->current);
- ctx->current = result;
- ctx->last_entry = LAST_ENTRY_NONE;
+ _on_chain_end(ctx, direction);
}
else {
/* TODO Is it a proper place for sound generation? */