*/
#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()
}
#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);
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 ) {
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
}
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",
}
}
-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;
}
}
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;
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;
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;
}
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);
/* 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");
}
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);
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"))) {
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);
}
}
}
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);
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);
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;
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;
+}
+