[screen reader] Code refactoring: window tracker 00/238700/12
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 16 Jul 2020 09:39:00 +0000 (11:39 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Mon, 20 Jul 2020 10:18:00 +0000 (12:18 +0200)
* reduce number of global values inside window tracker

Change-Id: I15a482ad0d3d735e75e2d486d9b1e486f397934d

include/app_tracker.h
include/keyboard_tracker.h
include/navigator.h
include/window_info.h [new file with mode: 0644]
include/window_tracker.h
src/app_tracker.c
src/keyboard_tracker.c
src/navigator.c
src/window_tracker.c

index a434db24891cdd88e3149c94d76b76a2fae34d8c..ba7961a99287a48e792ce39fc33b12205db62c69 100644 (file)
@@ -5,6 +5,7 @@
 #include <atspi/atspi.h>
 
 #include <navigator.h>
+#include <window_info.h>
 
 typedef struct _App_Tracker_Data App_Tracker_Data;
 
@@ -51,4 +52,25 @@ AppTrackerContextValidility app_tracker_context_valid_check(App_Tracker_Data *at
 
 void app_tracker_scroll_gesture_required_object_info_send(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_top_window_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_at_point_window_get(App_Tracker_Data *atd, int x, int y);
+
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd);
+
 #endif /* end of include guard: APP_TRACKER_H_ */
index d62258d9656840082371b2bb4df8f10763ae4278..37d9f32218be5448a6e3f50737cee91e549fd7f9 100644 (file)
@@ -1,7 +1,10 @@
 #ifndef KEYBOARD_TRACKER_H_
 #define KEYBOARD_TRACKER_H_
 
+#include <window_info.h>
+
 typedef struct _KeyboardTrackerData KeyboardTrackerData;
+typedef WindowInfo* (*TopWindowInfoGetCb)(void *);
 
 /*
  * @brief Creates listener and initializes eldbus.
@@ -33,7 +36,7 @@ void keyboard_geometry_set(KeyboardTrackerData *ktd, int x, int y, int width, in
 /*
  * @brief Gets keyboard geometry
  *
- * @param ktd internal data struct
+ * @param ktd internal keyboard tracker data struct
  * @param x int pointer to coordinate of left top corner
  * @param y int pointer to coordinate of left top corner
  * @param width int pointer
@@ -48,7 +51,7 @@ Eina_Bool keyboard_geometry_get(const KeyboardTrackerData *ktd, int *x, int *y,
 /*
  * @brief Return EINA_TRUE if the top window is Quickpanel Window
  *
- * @param ktd internal data struct
+ * @param ktd internal keyboard tracker data struct
  * @param x int coordinate
  * @param y int coordinate
  *
@@ -56,12 +59,12 @@ Eina_Bool keyboard_geometry_get(const KeyboardTrackerData *ktd, int *x, int *y,
  *
  * @note If SCREEN_READER_TV is undefined returns EINA_FALSE
  */
-Eina_Bool keyboard_event_status(const KeyboardTrackerData *ktd, int x, int y);
+Eina_Bool keyboard_event_status(KeyboardTrackerData *ktd, int x, int y);
 
 /*
  * @brief Emits signal to eldbus interface
  *
- * @param ktd internal data struct
+ * @param ktd internal keyboard tracker data struct
  * @param type int type of signals
  * @param type x int coordinate
  * @param type y int coordinate
@@ -70,4 +73,25 @@ Eina_Bool keyboard_event_status(const KeyboardTrackerData *ktd, int x, int y);
  */
 void keyboard_signal_emit(KeyboardTrackerData *ktd, int type, int x, int y);
 
+/*
+ * @brief Register function for getting information about top window.
+ *        This callback allows to remove dependency from window tracker.
+ *
+ * @param ktd internal keyboard tracker data struct
+ * @param type cb callback
+ * @param user_data data that should be passed to cb
+ *
+ */
+void keyboard_tracker_register_top_window_info_get(KeyboardTrackerData *ktd, TopWindowInfoGetCb cb, void *user_data);
+
+/*
+ * @brief Unregister function.
+ *        TODO replace this with NULL call of register function!
+ *
+ * @param ktd internal keyboard tracker data struct
+ *
+ * @return user_data that should be freed.
+ */
+void* keyboard_tracker_unregister_top_window_info_get(KeyboardTrackerData *ktd);
+
 #endif //KEYBOARD_TRACKER_H_
index 721686403ba8bf1065b483e56711cd5a0e590eb5..243cc8c3f291e4d362991942a6a8f1aff0699735 100644 (file)
@@ -26,6 +26,7 @@ Navigator_Data *navigator_init();
 /**
  * @brief Closes all subservices opened in initialization
  *
+ * @param nd internal data struct of Navigator
  */
 void navigator_shutdown(Navigator_Data *nd);
 
diff --git a/include/window_info.h b/include/window_info.h
new file mode 100644 (file)
index 0000000..84eaf0c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef WINDOW_INFO_H
+#define WINDOW_INFO_H
+
+#include <atspi/atspi.h>
+#include <Eina.h>
+
+typedef enum {
+       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED = 0,
+       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED_WITHOUT_WINDOW = 1 << 0,
+       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_DISABLED = 1 << 1,
+       ACCESSIBLE_WINDOW_ACTIVATE_INFO_KEYBOARD = 1 << 2,
+} WindowActivateInfoType;
+
+typedef struct {
+       AtspiAccessible *window;
+       AtspiRect *rect;
+       Eina_Bool keyboard_window_is;
+       Eina_Bool view_change_need; /* Would be not necessary, keep this for later usage */
+       WindowActivateInfoType window_activate_info_type;
+} WindowInfo;
+
+#endif
index 1fe64dcc32dac624b7d60209236ba7efba007aa0..6ae9f965493a8a71ee456a5682aa7ca9c4cb7bc8 100644 (file)
@@ -1,84 +1,89 @@
-#include <atspi/atspi.h>
-#include <Eina.h>
-
-typedef enum {
-       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED = 0,
-       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED_WITHOUT_WINDOW = 1 << 0,
-       ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_DISABLED = 1 << 1,
-       ACCESSIBLE_WINDOW_ACTIVATE_INFO_KEYBOARD = 1 << 2,
-} Window_Activate_Info_Type;
-
-typedef struct {
-       AtspiAccessible *window;
-       AtspiRect *rect;
-       Eina_Bool keyboard_window_is;
-       Eina_Bool view_change_need; /* Would be not necessary, keep this for later usage */
-       Window_Activate_Info_Type window_activate_info_type;
-} Window_Info;
-
-extern AtspiAccessible *subroot; //As widget windows are not registered, default label is not read
+#ifndef WINDOW_TRACKER_H
+#define WINDOW_TRACKER_H
+
+#include <window_info.h>
+
+typedef struct WindowTrackerDataImpl WindowTrackerData;
+typedef void (*WindowTrackerCb)(void *data, AtspiAccessible *window);
 
 /**
  * @brief Creates new listener and assignes it to events
+ *
+ * @param sd internal data struct of screen reader
  */
-void window_tracker_init(void);
+WindowTrackerData *window_tracker_init(void);
 
 /*
  * @brief Deregisters events listener and frees listener object
+ *
+ * @param wtd internal data struct of window tracker
  */
-void window_tracker_shutdown(void);
-
-typedef void (*Window_Tracker_Cb)(void *data, AtspiAccessible *window);
+void window_tracker_shutdown(WindowTrackerData *wtd);
 
 /**
  * @brief Registers callback function for listener
  *
+ * @param wtd internal data struct of window tracker
  * @param cb pointer to function
  * @param data additional data required by function
  */
-void window_tracker_register(Window_Tracker_Cb cb, void *data);
+void window_tracker_register(WindowTrackerData *wtd, WindowTrackerCb cb, void *data);
+
+void* window_tracker_unregister(WindowTrackerData *wtd);
 
 /*
  * @brief Sets top window and invokes for it function registered by window_tracker_register()
+ *
+ * @param wtd internal data struct of window tracker
  */
-void window_tracker_active_window_request(void);
+void window_tracker_active_window_request(WindowTrackerData *wtd);
 
 /*
- * @brief Return information of top window
+ * @brief Passes top_win object
+ *
+ * @param wtd internal data struct of window tracker
+ *
+ * @return AtspiAccessible object
  */
-Window_Info *window_tracker_top_window_info_get(void);
+AtspiAccessible *window_tracker_top_win_get(WindowTrackerData *wtd);
 
 /*
  * @brief Return top accessible window
  */
-AtspiAccessible *window_tracker_top_window_get(void);
+AtspiAccessible *window_tracker_top_window_get(WindowTrackerData *wtd);
 
 /*
  * @brief Appends window from window list
  */
-void window_tracker_window_append(AtspiAccessible *window, AtspiRole role);
+void window_tracker_window_append(WindowTrackerData *wtd, AtspiAccessible *window, AtspiRole role);
 
 /*
  * @brief Removes window from window list
  */
-void window_tracker_window_remove(AtspiAccessible *window);
+void window_tracker_window_remove(WindowTrackerData *wtd, AtspiAccessible *window);
 
 /*
  * @brief Returns window at point x, y
  */
-AtspiAccessible *window_tracker_at_point_window_get(int x, int y);
+AtspiAccessible *window_tracker_at_point_window_get(WindowTrackerData *wtd, int x, int y);
 
 /*
  * @brief Removes keyboard window from window list
  */
-void window_tracker_keyboard_window_remove(void);
+void window_tracker_keyboard_window_remove(WindowTrackerData *wtd);
 
 /*
  * @brief Appends keyboard window to window list
  */
-void window_tracker_keyboard_window_append(void);
+void window_tracker_keyboard_window_append(WindowTrackerData *wtd);
 
 /*
  * @brief Returns Window_Activate_Info_Type
  */
-Window_Activate_Info_Type window_tracker_window_activate_info_type_get(AtspiAccessible *window);
+WindowActivateInfoType window_tracker_window_activate_info_type_get(WindowTrackerData *wtd, AtspiAccessible *window);
+
+WindowInfo* window_tracker_top_window_info_get(WindowTrackerData *wtd);
+
+AtspiAccessible* window_tracker_subroot_get(WindowTrackerData *wtd);
+
+#endif // WINDOW_TRACKER_H
index 90c504340cfd0ad3a4baa9ca529c69e344f8b643..8e88565229318825a2083d219ae4f9fe995cc0c8 100644 (file)
@@ -47,6 +47,7 @@ struct _App_Tracker_Data {
        AtspiAccessible *prev_highlighted_obj;
        AtspiAccessible *scroll_gesture_required_obj;
 #endif
+       WindowTrackerData *window_tracker_data;
 };
 
 #ifndef SCREEN_READER_TV
@@ -87,7 +88,7 @@ static gboolean _on_timeout_rebuild_navigation_context(gpointer user_data)
                        return FALSE;
                }
 
-               Window_Activate_Info_Type window_activate_info_type = window_tracker_window_activate_info_type_get(root);
+               WindowActivateInfoType window_activate_info_type = window_tracker_window_activate_info_type_get(atd->window_tracker_data, root);
 
                root = dli->obj;
                role = dli->role;
@@ -329,7 +330,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                because the 'visible' callback of window tracker is not called on window tracker side,
                                if window object is removed. */
                                DEBUG("Append Window");
-                               window_tracker_window_append(event->source, role);
+                               window_tracker_window_append(atd->window_tracker_data, event->source, role);
                        } else if (role == ATSPI_ROLE_PAGE_TAB) {
                                // refresh default label for newly showing page tab
                                DEBUG("Refreshing TAB");
@@ -344,7 +345,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                        if other popup is showing then rebuild navigation context. */
                                        return;
                                }
-                               if (subroot) {
+                               if (window_tracker_subroot_get(atd->window_tracker_data)) {
                                        char *text_to_speak = NULL;
                                        text_to_speak = generate_what_to_read(event->source);
                                        DEBUG("SPEAK : %s", text_to_speak ? text_to_speak : "text_to_speak nil");
@@ -361,7 +362,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                because the 'visible' callback of window tracker is not called on window tracker side,
                                if window object is removed. */
                                DEBUG("Remove Window");
-                               window_tracker_window_remove(event->source);
+                               window_tracker_window_remove(atd->window_tracker_data, event->source);
                        } else if (object_has_modal_role(role)) {
                                //TODO: check if source is same with modals->data
                                // pop modal
@@ -384,18 +385,18 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                because window_tarcker is working for keyboard window.
                                we have to check this someday. */
                                if (rect->width == 0 || rect->height == 0) {
-                                       window_tracker_keyboard_window_remove();
+                                       window_tracker_keyboard_window_remove(atd->window_tracker_data);
                                        /* change flat_navi context root to next top window */
                                        FlatNaviContext *fn_context;
                                        AtspiAccessible *next_top_window;
                                        fn_context = navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data);
-                                       next_top_window = window_tracker_top_window_get();
+                                       next_top_window = window_tracker_top_window_get(atd->window_tracker_data);
                                        flat_navi_context_root_change(fn_context, next_top_window);
                                        gchar *id = atspi_accessible_get_unique_id(next_top_window, NULL);
                                        DEBUG("Root window is changed to: %s", id);
                                        g_free(id);
                                } else if (rect->width > 0 && rect->height > 0)
-                                       window_tracker_keyboard_window_append();
+                                       window_tracker_keyboard_window_append(atd->window_tracker_data);
                        }
                }
                //On rotation, send the bounds-changed notification to read landscape, portrait view,
@@ -654,15 +655,14 @@ app_tracker_init(AppTrackerEventWithDefaultLabelInfoCB view_content_changed_cb,
        DEBUG("View content changed callback set func=%p data=%p", view_content_changed_cb, nd);
        atd->root = NULL;
        atd->timer = 0;
-       subroot = NULL;
 #ifndef SCREEN_READER_TV
        atd->read_timer = NULL;
        atd->read_timer_user_data = NULL;
        atd->prev_highlighted_obj = NULL;
        atd->scroll_gesture_required_obj = NULL;
-       window_tracker_init();
+       atd->window_tracker_data = window_tracker_init();
        DEBUG("Registering app_tracker_context_switch=%p, for atd=%p", app_tracker_context_switch, atd);
-       window_tracker_register(app_tracker_context_switch, atd);
+       window_tracker_register(atd->window_tracker_data, app_tracker_context_switch, atd);
        /* This function does not affect
           window_tracker_active_window_request();
        */
@@ -715,6 +715,8 @@ void app_tracker_shutdown(App_Tracker_Data *atd)
        if (atd->read_timer)
                ecore_timer_del(atd->read_timer);
        atd->read_timer = NULL;
+       window_tracker_unregister(atd->window_tracker_data);
+       window_tracker_shutdown(atd->window_tracker_data);
 #endif
        if (atd->timer)
                g_source_remove(atd->timer);
@@ -804,3 +806,19 @@ void app_tracker_scroll_gesture_required_object_info_send(App_Tracker_Data *atd)
        _object_needs_scroll_gesture_send(atd, atd->scroll_gesture_required_obj);
 #endif
 }
+
+AtspiAccessible* app_tracker_top_window_get(App_Tracker_Data *atd)
+{
+       return atd ? window_tracker_top_window_get(atd->window_tracker_data) : NULL;
+}
+
+AtspiAccessible* app_tracker_at_point_window_get(App_Tracker_Data *atd, int x, int y)
+{
+       return atd ? window_tracker_at_point_window_get(atd->window_tracker_data, x, y) : NULL;
+}
+
+WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd)
+{
+       return atd ? window_tracker_top_window_info_get(atd->window_tracker_data) : NULL;
+}
+
index b13ad60652d9bf5070e629477c9198815016836a..7168d67e3a365fa6cd11ea10c067adb82fb282b9 100644 (file)
@@ -21,7 +21,7 @@
 #include <keyboard_tracker.h>
 #include <logger.h>
 #include <screen_reader_tts.h>
-#include <window_tracker.h>
+#include <window_info.h>
 
 struct _KeyboardTrackerData
 {
@@ -34,6 +34,8 @@ struct _KeyboardTrackerData
        int keyboardW;
        int keyboardH;
        int prev_keyboard_state;
+       TopWindowInfoGetCb top_window_info_get;
+       void *top_window_info_get_user_data;
 };
 
 #define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard"
@@ -51,6 +53,7 @@ static const Eldbus_Signal signals[] = {
 static const Eldbus_Service_Interface_Desc iface_desc = {
        E_KEYBOARD_SERVICE_NAVI_IFC_NAME, NULL, signals
 };
+
 static gboolean async_keyboard_cb(const AtspiDeviceEvent *stroke, void *data)
 {
        DEBUG("AT-SPI DEVICE EVENT: ID(%d) STRING(%s) TYPE(%d) HW_CODE(%d) MODIFIERS(%d) TIMESTAMP(%d)", stroke->id, stroke->event_string, stroke->type, stroke->hw_code, stroke->modifiers, stroke->timestamp);
@@ -132,6 +135,8 @@ KeyboardTrackerData* keyboard_tracker_init(void)
        ktd->keyboardW = 0;
        ktd->keyboardH = 0;
        ktd->prev_keyboard_state = VCONFKEY_ISF_INPUT_PANEL_STATE_HIDE;
+       ktd->top_window_info_get = NULL;
+       ktd->top_window_info_get_user_data = NULL;
        ktd->async_listener = atspi_device_listener_new(async_keyboard_cb, NULL, NULL);
 
        if (ktd->async_listener == NULL) {
@@ -211,11 +216,13 @@ Eina_Bool keyboard_geometry_get(const KeyboardTrackerData *ktd, int *x, int *y,
        return EINA_TRUE;
 }
 
-Eina_Bool keyboard_event_status(const KeyboardTrackerData *ktd, const int x, const int y)
+Eina_Bool keyboard_event_status(KeyboardTrackerData *ktd, const int x, const int y)
 {
 #ifndef SCREEN_READER_TV
        if (ktd->prev_keyboard_state == VCONFKEY_ISF_INPUT_PANEL_STATE_SHOW) {
-               Window_Info *top_win_info = window_tracker_top_window_info_get();
+               WindowInfo *top_win_info =
+                 ktd->top_window_info_get ? ktd->top_window_info_get(ktd->top_window_info_get_user_data) : NULL;
+
                if (!top_win_info) {
                        ERROR("Top window information is not available");
                        return EINA_FALSE;
@@ -253,3 +260,16 @@ void keyboard_signal_emit(KeyboardTrackerData *ktd, int type, int x, int y)
        eldbus_service_signal_emit(ktd->iface, KB_GESTURE_SIGNAL, type, x, y);
 }
 
+void keyboard_tracker_register_top_window_info_get(KeyboardTrackerData *ktd, TopWindowInfoGetCb cb, void *user_data)
+{
+       ktd->top_window_info_get = cb;
+       ktd->top_window_info_get_user_data = user_data;
+}
+
+void* keyboard_tracker_unregister_top_window_info_get(KeyboardTrackerData *ktd) {
+       void *ret = ktd->top_window_info_get_user_data;
+       ktd->top_window_info_get = NULL;
+       ktd->top_window_info_get_user_data = NULL;
+       return ret;
+}
+
index 2784c8b1ace08f26a947b18d0334344e802b56a1..0f70e599ed083e9b342d3d84beef8c61538d8d88 100644 (file)
@@ -33,7 +33,6 @@
 #include "screen_reader_haptic.h"
 #include "screen_reader_tts.h"
 #include "granularity_read.h"
-#include "window_tracker.h"
 #include "utils.h"
 
 #define QUICKPANEL_DOWN TRUE
@@ -1256,7 +1255,7 @@ static void _window_at_point_check(Navigator_Data *nd, int x, int y)
        gchar *touched_window_bus_name;
        gchar *context_root_bus_name;
 
-       touched_window = window_tracker_at_point_window_get(x, y);
+       touched_window = app_tracker_at_point_window_get(nd->app_tracker_data, x, y);
        context_root = flat_navi_context_root_get(nd->flat_navi_context);
 
        if (!touched_window || !context_root) return;
@@ -2832,7 +2831,7 @@ static Eina_Bool _current_highlight_on_keyboard_is(Navigator_Data *nd)
        gchar *top_bus_name;
        gchar *current_bus_name;
 
-       top_window = window_tracker_top_window_get();
+       top_window = app_tracker_top_window_get(nd->app_tracker_data);
        current = flat_navi_context_current_get(nd->flat_navi_context);
        if (!top_window || !current) return ret;
 
@@ -3279,6 +3278,11 @@ void navigator_gestures_tracker_unregister(void)
        eldbus_shutdown();
 }
 
+static WindowInfo* app_tracker_top_window_info_get_opaque(void *user_data)
+{
+       return app_tracker_top_window_info_get((App_Tracker_Data *)user_data);
+}
+
 Navigator_Data *navigator_init()
 {
        DEBUG("START");
@@ -3314,6 +3318,7 @@ Navigator_Data *navigator_init()
                                                          _new_highlighted_obj_changed,
                                                          nd);
        nd->keyboard_tracker_data = keyboard_tracker_init();
+       keyboard_tracker_register_top_window_info_get(nd->keyboard_tracker_data, app_tracker_top_window_info_get_opaque, nd->app_tracker_data);
        smart_notification_init();
 #ifndef SCREEN_READER_TV
        symbol_text_hash_init();
@@ -3339,6 +3344,7 @@ void navigator_shutdown(Navigator_Data *nd)
                }
        }
 
+       keyboard_tracker_unregister_top_window_info_get(nd->keyboard_tracker_data);
        keyboard_tracker_shutdown(nd->keyboard_tracker_data);
        nd->keyboard_tracker_data = NULL;
 
index 21971cf28897e58921802ec47fa628a9b06d054c..f075b90ae83c854cb12c266dd362afd4623c3725 100644 (file)
  */
 
 #include <string.h>
-#include "window_tracker.h"
-#include "screen_reader.h"
-#include "logger.h"
-#include "utils.h"
 
-static Window_Tracker_Cb user_cb;
-static void *user_data;
-static AtspiEventListener *listener;
-static Eina_List *window_infos = NULL;
-static AtspiAccessible *keyboard_window = NULL;
+#include <logger.h>
+#include <screen_reader.h>
+#include <utils.h>
+#include <window_tracker.h>
 
 #define E_WM_SERVICE_BUS_NAME "org.enlightenment.wm"
 #define E_WM_SERVICE_OBJ_PATH "/org/enlightenment/wm"
 #define E_WM_SERVICE_PROC_IFC_NAME "org.enlightenment.wm.proc"
 #define E_WM_SERVICE_METHOD_NAME "GetFocusProc"
 
-AtspiAccessible *subroot;
+struct WindowTrackerDataImpl
+{
+       WindowTrackerCb user_cb;
+       void *user_data;
+       AtspiEventListener *listener;
+       AtspiAccessible *last_active_win;
+       AtspiAccessible *top_win;
+       AtspiAccessible *subroot;
+       Eina_List *window_infos;
+       AtspiAccessible *keyboard_window;
+};
 
 #if 0 /* This is not used currently */
 static int _get_focus_process_pid()
@@ -87,7 +92,7 @@ fail_con:
 }
 #endif
 
-static Eina_Bool _window_need_to_be_purged(Window_Info *wi)
+static Eina_Bool _window_need_to_be_purged(WindowInfo *wi)
 {
        if (!wi->window || object_has_defunct_state(wi->window)) {
                DEBUG("purging %p because of defunct state or window doesn't exist", wi->window);
@@ -109,15 +114,15 @@ static Eina_Bool _window_need_to_be_purged(Window_Info *wi)
        return EINA_FALSE;
 }
 
-static void _purge_windows_list()
+static void _purge_windows_list(WindowTrackerData *wtd)
 {
        DEBUG("purging");
-       Window_Info *wi;
+       WindowInfo *wi;
        Eina_List *l, *l_prev;
        Eina_Bool view_change_need = EINA_FALSE;
        Eina_Bool keyboard_window_is = EINA_FALSE;
        int removed_index = 0;
-       EINA_LIST_REVERSE_FOREACH_SAFE(window_infos, l, l_prev, wi) {
+       EINA_LIST_REVERSE_FOREACH_SAFE(wtd->window_infos, l, l_prev, wi) {
                if (!wi) continue;
                if (_window_need_to_be_purged(wi)) {
                        if (removed_index == 0 ) {
@@ -127,19 +132,19 @@ static void _purge_windows_list()
                        g_object_unref(wi->window);
                        g_free(wi->rect);
                        g_free(wi);
-                       window_infos = eina_list_remove_list(window_infos, l);
+                       wtd->window_infos = eina_list_remove_list(wtd->window_infos, l);
                        removed_index++;
                }
        }
 
        //if purged window is top window rebuild context
-       if (view_change_need && user_cb && !keyboard_window_is) {
-               Window_Info* wi_top = eina_list_last_data_get(window_infos);
+       if (view_change_need && wtd->user_cb && !keyboard_window_is) {
+               WindowInfo* wi_top = eina_list_last_data_get(wtd->window_infos);
                if (wi_top) {
                        AtspiAccessible *top_window = wi_top->window;
                        if (wi_top->keyboard_window_is) {
-                               int count = eina_list_count(window_infos);
-                               wi_top = (count > 1) ? eina_list_nth(window_infos, count - 2) : NULL;
+                               int count = eina_list_count(wtd->window_infos);
+                               wi_top = (count > 1) ? eina_list_nth(wtd->window_infos, count - 2) : NULL;
                                if (wi_top)
                                        top_window = wi_top->window;
                                else
@@ -147,18 +152,18 @@ static void _purge_windows_list()
                        }
                        if (top_window) {
                                DEBUG("Rebuild context as top window was purged.");
-                               user_cb(user_data, top_window);
+                               wtd->user_cb(wtd->user_data, top_window);
                        }
                }
        }
 }
 
-static void _window_stack_print()
+static void _window_stack_print(WindowTrackerData *wtd)
 {
        Eina_List *l;
-       Window_Info *wi;
+       WindowInfo *wi;
 
-       EINA_LIST_FOREACH(window_infos, l, wi) {
+       EINA_LIST_FOREACH(wtd->window_infos, l, wi) {
                if (!wi) continue;
                gchar *id = atspi_accessible_get_unique_id(wi->window, NULL);
                DEBUG("Window: %s (%d, %d, %d, %d) view change need: %d, keyboard window: %d",
@@ -168,31 +173,31 @@ static void _window_stack_print()
        }
 }
 
-static Eina_Bool _is_window_in_stack(AtspiAccessible *window)
+static Eina_Bool _is_window_in_stack(WindowTrackerData *wtd, AtspiAccessible *window)
 {
        Eina_List *l;
-       Window_Info *wi;
+       WindowInfo *wi;
 
-       EINA_LIST_FOREACH(window_infos, l, wi)
+       EINA_LIST_FOREACH(wtd->window_infos, l, wi)
                if(wi && wi->window == window) return EINA_TRUE;
 
        return EINA_FALSE;
 }
 
-static void _window_append(AtspiAccessible *window, Eina_Bool view_change_need,
-                                                  Eina_Bool keyboard_window_is, Window_Activate_Info_Type window_activate_info_type)
+static void _window_append(WindowTrackerData *wtd, AtspiAccessible *window, Eina_Bool view_change_need,
+                                                  Eina_Bool keyboard_window_is, WindowActivateInfoType window_activate_info_type)
 {
-       _purge_windows_list();
+       _purge_windows_list(wtd);
        /* Remove window first if it exists already */
-       Window_Info *wi;
+       WindowInfo *wi;
        Eina_List *l, *l_prev;
-       EINA_LIST_REVERSE_FOREACH_SAFE(window_infos, l, l_prev, wi) {
+       EINA_LIST_REVERSE_FOREACH_SAFE(wtd->window_infos, l, l_prev, wi) {
                if (!wi) continue;
                if (wi->window == window) {
                        g_object_unref(wi->window);
                        g_free(wi->rect);
                        g_free(wi);
-                       window_infos = eina_list_remove_list(window_infos, l);
+                       wtd->window_infos = eina_list_remove_list(wtd->window_infos, l);
                        break;
                }
        }
@@ -208,7 +213,7 @@ static void _window_append(AtspiAccessible *window, Eina_Bool view_change_need,
        would be same with ecore_evas_geometry for window. so the value is doubled */
        rect = atspi_component_get_extents(comp, ATSPI_COORD_TYPE_SCREEN, NULL);
 
-       wi = g_malloc0(sizeof(Window_Info));
+       wi = g_malloc0(sizeof(WindowInfo));
        if (!wi) {
                DEBUG("Memory allocation by g_malloc0 is failed");
                return;
@@ -219,45 +224,45 @@ static void _window_append(AtspiAccessible *window, Eina_Bool view_change_need,
        wi->view_change_need = view_change_need;
        wi->window_activate_info_type = window_activate_info_type;
 
-       window_infos = eina_list_append(window_infos, wi);
+       wtd->window_infos = eina_list_append(wtd->window_infos, wi);
 
-       if (view_change_need && user_cb)
-               user_cb(user_data, window);
+       if (view_change_need && wtd->user_cb)
+               wtd->user_cb(wtd->user_data, window);
 
        gchar *id = atspi_accessible_get_unique_id(window, NULL);
        DEBUG("Window appended: %s", id);
        g_free(id);
-       _window_stack_print();
+       _window_stack_print(wtd);
 }
 
-static AtspiAccessible *_top_window_get(void)
+static AtspiAccessible *_top_window_get(WindowTrackerData *wtd)
 {
-       Window_Info *wi = NULL;
-       _purge_windows_list();
-       wi = eina_list_last_data_get(window_infos);
+       WindowInfo *wi = NULL;
+       _purge_windows_list(wtd);
+       wi = eina_list_last_data_get(wtd->window_infos);
        if (wi)
                return wi->window;
 
        return NULL;
 }
 
-static void _window_remove(AtspiAccessible *window)
+static void _window_remove(WindowTrackerData *wtd, AtspiAccessible *window)
 {
-       _purge_windows_list();
+       _purge_windows_list(wtd);
 
        Eina_Bool remove_from_top = EINA_FALSE;
        AtspiAccessible *top_window;
 
-       top_window = _top_window_get();
+       top_window = _top_window_get(wtd);
        remove_from_top = (top_window == window);
 
        Eina_Bool window_removed = EINA_FALSE;
        Eina_Bool view_change_need = EINA_FALSE;
        Eina_Bool keyboard_window_is = EINA_FALSE;
        Eina_List *l, *l_prev;
-       Window_Info *wi = NULL;
+       WindowInfo *wi = NULL;
        int removed_index = 0;
-       EINA_LIST_REVERSE_FOREACH_SAFE(window_infos, l, l_prev, wi) {
+       EINA_LIST_REVERSE_FOREACH_SAFE(wtd->window_infos, l, l_prev, wi) {
                if (!wi) continue;
                if (wi->window == window) {
                        view_change_need = wi->view_change_need;
@@ -265,7 +270,7 @@ static void _window_remove(AtspiAccessible *window)
                        g_object_unref(wi->window);
                        g_free(wi->rect);
                        g_free(wi);
-                       window_infos = eina_list_remove_list(window_infos, l);
+                       wtd->window_infos = eina_list_remove_list(wtd->window_infos, l);
                        window_removed = EINA_TRUE;
                        break;
                }
@@ -285,22 +290,22 @@ static void _window_remove(AtspiAccessible *window)
        if (remove_from_top) {
                /* keyboard_window_is would be always FASLE because the
                window_tracker_keyboard_window_remove does not use this function */
-               if (user_cb && !keyboard_window_is) {
-                       top_window = _top_window_get();
+               if (wtd->user_cb && !keyboard_window_is) {
+                       top_window = _top_window_get(wtd);
                        if (top_window) {
                                /* The current top could be keypad window,
                                if so, use the second top window */
-                               wi = eina_list_last_data_get(window_infos);
+                               wi = eina_list_last_data_get(wtd->window_infos);
                                if (wi->keyboard_window_is) {
-                                       int count = eina_list_count(window_infos);
-                                       wi = eina_list_nth(window_infos, count - 2);
+                                       int count = eina_list_count(wtd->window_infos);
+                                       wi = eina_list_nth(wtd->window_infos, count - 2);
                                        if (wi)
                                                top_window = wi->window;
                                        else
                                                top_window = NULL;
                                }
                                if (top_window)
-                                       user_cb(user_data, top_window);
+                                       wtd->user_cb(wtd->user_data, top_window);
                        }
                        gchar *id = atspi_accessible_get_unique_id(top_window, NULL);
                        DEBUG("top window: %s", id);
@@ -310,14 +315,14 @@ static void _window_remove(AtspiAccessible *window)
                /* The removed window could be under the keyboard window,
                in this case the keyboard window should be removed from the list */
                if (removed_index != 0) {
-                       int count = eina_list_count(window_infos);
-                       wi = eina_list_nth(window_infos, count - removed_index - 1);
+                       int count = eina_list_count(wtd->window_infos);
+                       wi = eina_list_nth(wtd->window_infos, count - removed_index - 1);
                        if (wi) {
                                gchar *id = atspi_accessible_get_unique_id(wi->window, NULL);
                                DEBUG("Check upper window: %s, keyboard window: %d", id, wi->keyboard_window_is);
                                g_free(id);
                                if (wi->keyboard_window_is)
-                                       window_infos = eina_list_remove(window_infos, wi);
+                                       wtd->window_infos = eina_list_remove(wtd->window_infos, wi);
                        } else
                                DEBUG("Current window info list is emtpy");
                }
@@ -326,11 +331,13 @@ static void _window_remove(AtspiAccessible *window)
        gchar *id = atspi_accessible_get_unique_id(window, NULL);
        DEBUG("Window removed: %s", id);
        g_free(id);
-       _window_stack_print();
+       _window_stack_print(wtd);
 }
 
-static void _on_atspi_window_cb(const AtspiEvent *event)
+static void _on_atspi_window_cb(AtspiEvent *event, void *user_data)
 {
+       WindowTrackerData *wtd = user_data;
+
        gchar *name = atspi_accessible_get_name(event->source, NULL);
 
        gchar *id = atspi_accessible_get_unique_id(event->source, NULL);
@@ -338,22 +345,22 @@ static void _on_atspi_window_cb(const AtspiEvent *event)
        g_free(id);
 
        if (!g_strcmp0(event->type, "window:activate")) {
-               Window_Activate_Info_Type window_activate_info_type = event->detail1;
+               WindowActivateInfoType window_activate_info_type = event->detail1;
                /* The keyboard window does not use ATSPI when the scree-reader is turning on
                and the keyboard process exsits already. In this case, we are using activate signal.
                This is not informal way, because the keyboard does not use ATSPI. */
                gint keyboard_window_activated =
                        (window_activate_info_type & ACCESSIBLE_WINDOW_ACTIVATE_INFO_KEYBOARD);
                if (keyboard_window_activated) {
-                       keyboard_window = g_object_ref(event->source);
+                       wtd->keyboard_window = g_object_ref(event->source);
                        g_free(name);
                        return;
                }
-               _window_append(event->source, EINA_TRUE, EINA_FALSE, window_activate_info_type);
-               subroot = NULL; //No need to keep subroot if any window gets activated
+               _window_append(wtd, event->source, EINA_TRUE, EINA_FALSE, window_activate_info_type);
+               wtd->subroot = NULL; //No need to keep subroot if any window gets activated
        } else if (!g_strcmp0(event->type, "window:deactivate")) {
                DEBUG("Remove Window");
-               _window_remove(event->source);
+               _window_remove(wtd, event->source);
        } else if (!g_strcmp0("object:state-changed:visible", event->type)
                           && name && (!g_strcmp0(name, "Quickpanel Window") || !g_strcmp0(name, "volume") || !g_strcmp0(name, "Keyboard"))) {
 
@@ -363,12 +370,12 @@ static void _on_atspi_window_cb(const AtspiEvent *event)
                if (event->detail1) { /* Visible */
                        if (role == ATSPI_ROLE_WINDOW || keyboard_is) {
                                DEBUG("Append %sWindow", keyboard_is ? "Keyboard " : "");
-                               _window_append(event->source, !keyboard_is, keyboard_is, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
+                               _window_append(wtd, event->source, !keyboard_is, keyboard_is, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
                        }
                } else { /* Invisible */
                        if (role == ATSPI_ROLE_WINDOW || keyboard_is) {
                                DEBUG("Remove %sWindow", keyboard_is ? "Keyboard " : "");
-                               _window_remove(event->source);
+                               _window_remove(wtd, event->source);
                        }
                }
        }
@@ -376,84 +383,131 @@ static void _on_atspi_window_cb(const AtspiEvent *event)
                AtspiRole role = atspi_accessible_get_role(event->source, NULL);
                if (role == ATSPI_ROLE_FRAME) {
                        if (event->detail1)
-                               _window_append(event->source, EINA_TRUE, EINA_FALSE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
+                               _window_append(wtd, event->source, EINA_TRUE, EINA_FALSE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
                        else
-                               _window_remove(event->source);
+                               _window_remove(wtd, event->source);
                }
 
                if (role == ATSPI_ROLE_WINDOW) {
                        if (event->detail1) { /* Visible */
-                               if (!_is_window_in_stack(event->source)) {
+                               if (!_is_window_in_stack(wtd, event->source)) {
                                        DEBUG("Store subroot window: %p", event->source);
-                                       subroot = event->source;
+                                       wtd->subroot = event->source;
                                }
                        }
                        else {
                                DEBUG("delete subroot window: %p", event->source);
-                               subroot = NULL;
+                               wtd->subroot = NULL;
                        }
                }
        }
        g_free(name);
 }
 
-void window_tracker_init(void)
+WindowTrackerData *window_tracker_init(void)
 {
        DEBUG("START");
-       listener = atspi_event_listener_new_simple(_on_atspi_window_cb, NULL);
-       atspi_event_listener_register(listener, "window:activate", NULL);
-       atspi_event_listener_register(listener, "window:deactivate", NULL);
-       atspi_event_listener_register(listener, "object:state-changed:visible", NULL);
+       WindowTrackerData *wtd = calloc(1, sizeof(WindowTrackerData));
+       if (wtd == NULL) {
+               ERROR("memory allcation failed");
+               return NULL;
+       }
+
+       wtd->user_cb = NULL;
+       wtd->user_data = NULL;
+
+       wtd->listener = atspi_event_listener_new(_on_atspi_window_cb, wtd, NULL);
+
+       if (wtd->listener == NULL) {
+               ERROR("Listener was not created");
+               free(wtd);
+               return NULL;
+       }
+
+       atspi_event_listener_register(wtd->listener, "window:activate", NULL);
+       atspi_event_listener_register(wtd->listener, "window:deactivate", NULL);
+       atspi_event_listener_register(wtd->listener, "object:state-changed:visible", NULL);
+
+       wtd->last_active_win = NULL;
+       wtd->top_win = NULL;
+       wtd->subroot = NULL;
+       wtd->window_infos = NULL;
+       wtd->keyboard_window = NULL;
+
+       return wtd;
 }
 
-void window_tracker_shutdown(void)
+void window_tracker_shutdown(WindowTrackerData *wtd)
 {
        DEBUG("START");
-       atspi_event_listener_deregister(listener, "window:activate", NULL);
-       atspi_event_listener_deregister(listener, "window:deactivate", NULL);
-       atspi_event_listener_deregister(listener, "object:state-changed:visible", NULL);
-       g_object_unref(listener);
-       listener = NULL;
-       user_cb = NULL;
-       user_data = NULL;
-
-       Window_Info *wi;
-       EINA_LIST_FREE(window_infos, wi) {
+
+       if (wtd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       if (wtd->listener) {
+               atspi_event_listener_deregister(wtd->listener, "window:activate", NULL);
+               atspi_event_listener_deregister(wtd->listener, "window:deactivate", NULL);
+               atspi_event_listener_deregister(wtd->listener, "object:state-changed:visible", NULL);
+               g_object_unref(wtd->listener);
+               wtd->listener = NULL;
+       }
+
+       wtd->user_cb = NULL;
+       wtd->user_data = NULL;
+
+       WindowInfo *wi;
+       EINA_LIST_FREE(wtd->window_infos, wi) {
                if (!wi) continue;
                g_object_unref(wi->window);
                g_free(wi->rect);
                g_free(wi);
        }
 
-       if (keyboard_window)
-               g_object_unref(keyboard_window);
+       if (wtd->keyboard_window)
+               g_object_unref(wtd->keyboard_window);
 
+       free(wtd);
        DEBUG("END");
 }
 
-void window_tracker_register(Window_Tracker_Cb cb, void *data)
+void window_tracker_register(WindowTrackerData *wtd, WindowTrackerCb cb, void *data)
 {
        DEBUG("START");
-       user_cb = cb;
-       user_data = data;
+
+       if (!wtd) {
+               ERROR("NULL context");
+               return;
+       }
+
+       wtd->user_cb = cb;
+       wtd->user_data = data;
+}
+
+void* window_tracker_unregister(WindowTrackerData *wtd) {
+       void *res = wtd->user_data;
+       wtd->user_cb = NULL;
+       wtd->user_data = NULL;
+       return res;
 }
 
-void window_tracker_active_window_request(void)
+void window_tracker_active_window_request(WindowTrackerData *wtd)
 {
        DEBUG("START");
 }
 
-Window_Info *window_tracker_top_window_info_get(void)
+WindowInfo *window_tracker_top_window_info_get(WindowTrackerData *wtd)
 {
-       return eina_list_last_data_get(window_infos);
+       return eina_list_last_data_get(wtd->window_infos);
 }
 
-AtspiAccessible *window_tracker_top_window_get(void)
+AtspiAccessible *window_tracker_top_window_get(WindowTrackerData *wtd)
 {
-       return _top_window_get();
+       return _top_window_get(wtd);
 }
 
-void window_tracker_window_append(AtspiAccessible *window, AtspiRole role)
+void window_tracker_window_append(WindowTrackerData *wtd, AtspiAccessible *window, AtspiRole role)
 {
        gchar *name = atspi_accessible_get_name(window, NULL);
 
@@ -462,33 +516,33 @@ void window_tracker_window_append(AtspiAccessible *window, AtspiRole role)
                because window_tracker_window_append is not called from app_tracker
                if role is INPUT_METHOD_WINDOW, when app_tracker handles showing event.*/
                if (role == ATSPI_ROLE_INPUT_METHOD_WINDOW && g_strcmp0(name, "ISF Popup")) {
-                       _window_append(window, EINA_FALSE, EINA_TRUE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
+                       _window_append(wtd, window, EINA_FALSE, EINA_TRUE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
                        /* keep keyboard window reference, because keyboard window exsits always if it shows once. */
-                       if (keyboard_window) g_object_unref(keyboard_window);
-                       keyboard_window = g_object_ref(window);
+                       if (wtd->keyboard_window) g_object_unref(wtd->keyboard_window);
+                       wtd->keyboard_window = g_object_ref(window);
                } else if (!g_strcmp0(name, "ISF Popup"))
                        /*ISF Popup: this would be an indicator window of keyboard.
                        There is a show(hide)_indicator_window in ise-default package.
                        If so, I cannot remember why we are appending this window.*/
-                       _window_append(window, EINA_TRUE, EINA_FALSE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
+                       _window_append(wtd, window, EINA_TRUE, EINA_FALSE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
        }
 
        g_free(name);
 }
 
-void window_tracker_window_remove(AtspiAccessible *window)
+void window_tracker_window_remove(WindowTrackerData *wtd, AtspiAccessible *window)
 {
-       _window_remove(window);
+       _window_remove(wtd, window);
 }
 
-AtspiAccessible *window_tracker_at_point_window_get(int x, int y)
+AtspiAccessible *window_tracker_at_point_window_get(WindowTrackerData *wtd, int x, int y)
 {
-       Window_Info *wi;
+       WindowInfo *wi;
        Eina_List *l;
 
-       DEBUG("Number of window: %d", eina_list_count(window_infos));
+       DEBUG("Number of window: %d", eina_list_count(wtd->window_infos));
 
-       EINA_LIST_REVERSE_FOREACH(window_infos, l, wi) {
+       EINA_LIST_REVERSE_FOREACH(wtd->window_infos, l, wi) {
                if (!wi) continue;
                AtspiRect *rect = wi->rect;
                gchar *id = atspi_accessible_get_unique_id(wi->window, NULL);
@@ -505,36 +559,36 @@ AtspiAccessible *window_tracker_at_point_window_get(int x, int y)
        return NULL;
 }
 
-void window_tracker_keyboard_window_remove(void)
+void window_tracker_keyboard_window_remove(WindowTrackerData *wtd)
 {
-       Window_Info *wi;
+       WindowInfo *wi;
        Eina_List *l, *l_prev;
 
        DEBUG("Remove keyboard window");
 
-       EINA_LIST_REVERSE_FOREACH_SAFE(window_infos, l, l_prev, wi) {
+       EINA_LIST_REVERSE_FOREACH_SAFE(wtd->window_infos, l, l_prev, wi) {
                if (!wi) continue;
                if (wi->keyboard_window_is) {
                        g_object_unref(wi->window);
                        g_free(wi->rect);
                        g_free(wi);
-                       window_infos = eina_list_remove_list(window_infos, l);
+                       wtd->window_infos = eina_list_remove_list(wtd->window_infos, l);
                        break;
                }
        }
 }
 
-void window_tracker_keyboard_window_append(void)
+void window_tracker_keyboard_window_append(WindowTrackerData *wtd)
 {
-       _window_append(keyboard_window, FALSE, EINA_TRUE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
+       _window_append(wtd, wtd->keyboard_window, FALSE, EINA_TRUE, ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED);
 }
 
-Window_Activate_Info_Type window_tracker_window_activate_info_type_get(AtspiAccessible *window)
+WindowActivateInfoType window_tracker_window_activate_info_type_get(WindowTrackerData *wtd, AtspiAccessible *window)
 {
-       Window_Info *wi;
+       WindowInfo *wi;
        Eina_List *l;
 
-       EINA_LIST_REVERSE_FOREACH(window_infos, l, wi) {
+       EINA_LIST_REVERSE_FOREACH(wtd->window_infos, l, wi) {
                if (!wi) continue;
                if (window == wi->window) {
                        return wi->window_activate_info_type;
@@ -543,3 +597,14 @@ Window_Activate_Info_Type window_tracker_window_activate_info_type_get(AtspiAcce
 
        return ACCESSIBLE_WINDOW_ACTIVATE_INFO_DEFAULT_LABEL_ENABLED;
 }
+
+AtspiAccessible* window_tracker_top_win_get(WindowTrackerData *wtd)
+{
+       return wtd ? wtd->top_win : NULL;
+}
+
+AtspiAccessible* window_tracker_subroot_get(WindowTrackerData *wtd)
+{
+       return wtd ? wtd->subroot : NULL;
+}
+