Support null context 28/306728/1
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 23 Sep 2022 10:47:50 +0000 (12:47 +0200)
committerMaria Bialota <m.bialota@samsung.com>
Mon, 26 Feb 2024 15:34:40 +0000 (16:34 +0100)
Null context allows the Screen Reader to yield control to applications
whose existence it is not aware of, like ones using unknown toolkits.
The null context is not actually a NULL pointer, but a special desktop
object, because the code expects a non-NULL pointer in so many places.

Change-Id: I41901899a84315cc92507c09e8471195b721ede3

include/app_tracker.h
src/app_tracker.c
src/navigator.c
src/window_tracker.c

index 0b039447ef876cecf623822f19faa853a76a5319..7cea472a5a626613e019f2475a99bf586912e9eb 100644 (file)
@@ -80,4 +80,25 @@ AtspiAccessible* app_tracker_resource_id_window_get(App_Tracker_Data *atd, uint3
  */
 WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd);
 
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+AtspiAccessible* app_tracker_desktop_get(App_Tracker_Data *atd);
+
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+bool app_tracker_null_context_is(App_Tracker_Data *atd);
+
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+void app_tracker_null_context_switch(App_Tracker_Data *atd);
+
 #endif /* end of include guard: APP_TRACKER_H_ */
index e10a2c3b18ea320733b5bb84791f95748e546d58..6aac528276d759c79e8d3d1d5354fc7020701fcd 100644 (file)
@@ -52,6 +52,7 @@ struct _App_Tracker_Data {
        AtspiAccessible *scroll_gesture_required_obj;
 #endif
        WindowTrackerData *window_tracker_data;
+       AtspiAccessible *desktop;
 };
 
 #ifndef SCREEN_READER_TV
@@ -638,6 +639,10 @@ app_tracker_init(AppTrackerEventWithDefaultLabelInfoCB view_content_changed_cb,
        navigator_set_context_switch_cb(nd, app_tracker_context_switch, atd);
 #endif
 
+       atd->desktop = atspi_get_desktop(0);
+       if (!atd->desktop)
+               ERROR("atspi_get_desktop() failed");
+
        atd->new_obj_highlighted_callback = NULL;
        atd->new_obj_highlighted_callback_user_data = NULL;
        atd->listener = atspi_event_listener_new(_on_atspi_event_cb, atd, NULL);
@@ -676,6 +681,8 @@ void app_tracker_shutdown(App_Tracker_Data *atd)
        g_object_unref(atd->listener);
        atd->listener = NULL;
 
+       g_object_unref(atd->desktop);
+
        atd->new_obj_highlighted_callback = NULL;
        if (atd->new_obj_highlighted_callback_user_data) {
                WARNING("You should deregister new_obj_highlighted_callback before shutdown!");
@@ -813,3 +820,25 @@ WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd)
 {
        return atd ? window_tracker_top_window_info_get(atd->window_tracker_data) : NULL;
 }
+
+AtspiAccessible* app_tracker_desktop_get(App_Tracker_Data *atd)
+{
+       return atd ? atd->desktop : NULL;
+}
+
+bool app_tracker_null_context_is(App_Tracker_Data *atd)
+{
+       FlatNaviContext *ctx = navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data);
+
+       return flat_navi_context_root_get(ctx) == app_tracker_desktop_get(atd);
+}
+
+void app_tracker_null_context_switch(App_Tracker_Data *atd)
+{
+       FlatNaviContext *ctx = navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data);
+
+       DEBUG("Setting null context");
+
+       flat_navi_context_root_change(ctx, app_tracker_desktop_get(atd));
+}
+
index c2d9ced3338c7b7d3d06c89cefc2cf13038284e3..9f272ce3712b3b7c50827d70b136fa707200cb44 100644 (file)
@@ -534,7 +534,10 @@ TIZEN_PROD_STATIC void _window_of_resource_id_check(NavigatorData *nd, uint32_t
 
        touched_window = app_tracker_resource_id_window_get(nd->app_tracker_data, resource_id);
 
-       if (!touched_window) return;
+       if (!touched_window) {
+               app_tracker_null_context_switch(nd->app_tracker_data);
+               return;
+       }
 
        if (nd->context_switch_cb)
                nd->context_switch_cb(nd->context_switch_data, touched_window);
@@ -2222,6 +2225,12 @@ TIZEN_PROD_STATIC void on_gesture_detected(void *data, const Eldbus_Message *msg
        DEBUG("Incoming gesture name is %s : %d %d %d %d %d %u", utils_enum_to_string(info->type),
                  info->x_beg, info->y_beg, info->x_end, info->y_end, info->state, info->resource_id);
 
+       if (info->type != ONE_FINGER_SINGLE_TAP && app_tracker_null_context_is(nd->app_tracker_data)) {
+               DEBUG("Ignoring gesture because of null context");
+               g_free(info);
+               return;
+       }
+
        _on_auto_review_stop(nd);
 
        if (info->type == ONE_FINGER_SINGLE_TAP && info->state == 3) {
@@ -2786,3 +2795,4 @@ void navigator_set_last_table_unique_id(NavigatorData *nd, gchar *table_unique_i
                nd->last_table_unique_id = g_strdup(table_unique_id);
        }
 }
+
index aeffc04be5baf94ec4932f1621da7d6bee5a4430..e59945c2011bfd94230e016312d50ad4e5e84561 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <string.h>
 
+#include <app_tracker.h>
 #include <logger.h>
 #include <screen_reader.h>
 #include <utils.h>
@@ -29,7 +30,7 @@
 struct WindowTrackerDataImpl
 {
        WindowTrackerCb user_cb;
-       void *user_data;
+       void *user_data; // App_Tracker_Data *
        AtspiEventListener *listener;
        AtspiAccessible *last_active_win;
        AtspiAccessible *top_win;
@@ -145,6 +146,9 @@ static void _purge_windows_list(WindowTrackerData *wtd)
                                wtd->user_cb(wtd->user_data, top_window);
                        }
                }
+
+               if (!wi_top)
+                       app_tracker_null_context_switch(wtd->user_data);
        }
 }
 
@@ -307,6 +311,10 @@ static void _window_remove(WindowTrackerData *wtd, AtspiAccessible *window)
                                if (top_window)
                                        wtd->user_cb(wtd->user_data, top_window);
                        }
+
+                       if (!top_window)
+                               app_tracker_null_context_switch(wtd->user_data);
+
                        gchar *id = atspi_accessible_get_unique_id(top_window, NULL);
                        DEBUG("top window: %s", id);
                        g_free(id);