forked from AuroraMiddleware/gtk
a11y: Redo notebook page management
Previously, the code tried to track the indexes of the pages and keep them up to date in a list and tracking the index in the GtkNotebookPage. Now, we store the widget we are tracking in the GailNotebookPage and keep a hash table of widget=>GailNotebookPage in the GailNotebook. This frees us from the burden of tracking page changes.
This commit is contained in:
parent
9cf9abd5b0
commit
790d8e324b
@ -43,20 +43,9 @@ static AtkObject* gail_notebook_ref_selection (AtkSelection *selection
|
|||||||
static gint gail_notebook_get_selection_count (AtkSelection *selection);
|
static gint gail_notebook_get_selection_count (AtkSelection *selection);
|
||||||
static gboolean gail_notebook_is_child_selected (AtkSelection *selection,
|
static gboolean gail_notebook_is_child_selected (AtkSelection *selection,
|
||||||
gint i);
|
gint i);
|
||||||
static AtkObject* find_child_in_list (GList *list,
|
|
||||||
gint index);
|
|
||||||
static void check_cache (GailNotebook *gail_notebook,
|
|
||||||
GtkNotebook *notebook);
|
|
||||||
static void reset_cache (GailNotebook *gail_notebook,
|
|
||||||
gint index);
|
|
||||||
static void create_notebook_page_accessible (GailNotebook *gail_notebook,
|
static void create_notebook_page_accessible (GailNotebook *gail_notebook,
|
||||||
GtkNotebook *notebook,
|
GtkNotebook *notebook,
|
||||||
gint index,
|
GtkWidget *child);
|
||||||
gboolean insert_before,
|
|
||||||
GList *list);
|
|
||||||
static void gail_notebook_child_parent_set (GtkWidget *widget,
|
|
||||||
GtkWidget *old_parent,
|
|
||||||
gpointer data);
|
|
||||||
static gboolean gail_notebook_focus_cb (GtkWidget *widget,
|
static gboolean gail_notebook_focus_cb (GtkWidget *widget,
|
||||||
GtkDirectionType type);
|
GtkDirectionType type);
|
||||||
static gboolean gail_notebook_check_focus_tab (gpointer data);
|
static gboolean gail_notebook_check_focus_tab (gpointer data);
|
||||||
@ -91,10 +80,12 @@ gail_notebook_class_init (GailNotebookClass *klass)
|
|||||||
static void
|
static void
|
||||||
gail_notebook_init (GailNotebook *notebook)
|
gail_notebook_init (GailNotebook *notebook)
|
||||||
{
|
{
|
||||||
notebook->page_cache = NULL;
|
notebook->pages = g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
g_object_unref);
|
||||||
notebook->selected_page = -1;
|
notebook->selected_page = -1;
|
||||||
notebook->focus_tab_page = -1;
|
notebook->focus_tab_page = -1;
|
||||||
notebook->remove_index = -1;
|
|
||||||
notebook->idle_focus_id = 0;
|
notebook->idle_focus_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,15 +106,13 @@ gail_notebook_ref_child (AtkObject *obj,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gail_notebook = GAIL_NOTEBOOK (obj);
|
gail_notebook = GAIL_NOTEBOOK (obj);
|
||||||
|
|
||||||
gtk_notebook = GTK_NOTEBOOK (widget);
|
gtk_notebook = GTK_NOTEBOOK (widget);
|
||||||
|
|
||||||
if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
|
accessible = g_hash_table_lookup (gail_notebook->pages,
|
||||||
check_cache (gail_notebook, gtk_notebook);
|
gtk_notebook_get_nth_page (gtk_notebook, i));
|
||||||
|
/* can return NULL when i >= n_children */
|
||||||
|
|
||||||
accessible = find_child_in_list (gail_notebook->page_cache, i);
|
if (accessible)
|
||||||
|
|
||||||
if (accessible != NULL)
|
|
||||||
g_object_ref (accessible);
|
g_object_ref (accessible);
|
||||||
|
|
||||||
return accessible;
|
return accessible;
|
||||||
@ -140,8 +129,7 @@ gail_notebook_page_added (GtkNotebook *gtk_notebook,
|
|||||||
|
|
||||||
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook));
|
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook));
|
||||||
notebook = GAIL_NOTEBOOK (atk_obj);
|
notebook = GAIL_NOTEBOOK (atk_obj);
|
||||||
create_notebook_page_accessible (notebook, gtk_notebook, page_num, FALSE, NULL);
|
create_notebook_page_accessible (notebook, gtk_notebook, child);
|
||||||
notebook->page_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -152,24 +140,18 @@ gail_notebook_page_removed (GtkNotebook *notebook,
|
|||||||
{
|
{
|
||||||
GailNotebook *gail_notebook;
|
GailNotebook *gail_notebook;
|
||||||
AtkObject *obj;
|
AtkObject *obj;
|
||||||
gint index;
|
|
||||||
|
|
||||||
gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (notebook)));
|
gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (notebook)));
|
||||||
index = gail_notebook->remove_index;
|
|
||||||
gail_notebook->remove_index = -1;
|
|
||||||
|
|
||||||
obj = find_child_in_list (gail_notebook->page_cache, index);
|
obj = g_hash_table_lookup (gail_notebook->pages, widget);
|
||||||
g_return_if_fail (obj);
|
g_return_if_fail (obj);
|
||||||
gail_notebook->page_cache = g_list_remove (gail_notebook->page_cache, obj);
|
|
||||||
gail_notebook->page_count -= 1;
|
|
||||||
reset_cache (gail_notebook, index);
|
|
||||||
g_signal_emit_by_name (gail_notebook,
|
g_signal_emit_by_name (gail_notebook,
|
||||||
"children_changed::remove",
|
"children_changed::remove",
|
||||||
page_num,
|
page_num,
|
||||||
obj,
|
obj,
|
||||||
NULL);
|
NULL);
|
||||||
gail_notebook_page_invalidate (GAIL_NOTEBOOK_PAGE (obj));
|
gail_notebook_page_invalidate (GAIL_NOTEBOOK_PAGE (obj));
|
||||||
g_object_unref (obj);
|
g_hash_table_remove (gail_notebook->pages, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -186,9 +168,10 @@ gail_notebook_real_initialize (AtkObject *obj,
|
|||||||
gtk_notebook = GTK_NOTEBOOK (data);
|
gtk_notebook = GTK_NOTEBOOK (data);
|
||||||
for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++)
|
for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++)
|
||||||
{
|
{
|
||||||
create_notebook_page_accessible (notebook, gtk_notebook, i, FALSE, NULL);
|
create_notebook_page_accessible (notebook,
|
||||||
|
gtk_notebook,
|
||||||
|
gtk_notebook_get_nth_page (gtk_notebook, i));
|
||||||
}
|
}
|
||||||
notebook->page_count = i;
|
|
||||||
notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook);
|
notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook);
|
||||||
|
|
||||||
g_signal_connect (gtk_notebook,
|
g_signal_connect (gtk_notebook,
|
||||||
@ -231,8 +214,6 @@ gail_notebook_real_notify_gtk (GObject *obj,
|
|||||||
gail_notebook = GAIL_NOTEBOOK (atk_obj);
|
gail_notebook = GAIL_NOTEBOOK (atk_obj);
|
||||||
gtk_notebook = GTK_NOTEBOOK (widget);
|
gtk_notebook = GTK_NOTEBOOK (widget);
|
||||||
|
|
||||||
if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
|
|
||||||
check_cache (gail_notebook, gtk_notebook);
|
|
||||||
/*
|
/*
|
||||||
* Notify SELECTED state change for old and new page
|
* Notify SELECTED state change for old and new page
|
||||||
*/
|
*/
|
||||||
@ -290,22 +271,8 @@ static void
|
|||||||
gail_notebook_finalize (GObject *object)
|
gail_notebook_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GailNotebook *notebook = GAIL_NOTEBOOK (object);
|
GailNotebook *notebook = GAIL_NOTEBOOK (object);
|
||||||
GList *list;
|
|
||||||
|
|
||||||
/*
|
g_hash_table_destroy (notebook->pages);
|
||||||
* Get rid of the GailNotebookPage objects which we have cached.
|
|
||||||
*/
|
|
||||||
list = notebook->page_cache;
|
|
||||||
if (list != NULL)
|
|
||||||
{
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
g_object_unref (list->data);
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (notebook->page_cache);
|
|
||||||
|
|
||||||
if (notebook->idle_focus_id)
|
if (notebook->idle_focus_id)
|
||||||
g_source_remove (notebook->idle_focus_id);
|
g_source_remove (notebook->idle_focus_id);
|
||||||
@ -428,103 +395,17 @@ gail_notebook_is_child_selected (AtkSelection *selection,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AtkObject*
|
|
||||||
find_child_in_list (GList *list,
|
|
||||||
gint index)
|
|
||||||
{
|
|
||||||
AtkObject *obj = NULL;
|
|
||||||
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
if (GAIL_NOTEBOOK_PAGE (list->data)->index == index)
|
|
||||||
{
|
|
||||||
obj = ATK_OBJECT (list->data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_cache (GailNotebook *gail_notebook,
|
|
||||||
GtkNotebook *notebook)
|
|
||||||
{
|
|
||||||
GList *gtk_list;
|
|
||||||
GList *gail_list;
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
gtk_list = gtk_container_get_children (GTK_CONTAINER (notebook));
|
|
||||||
gail_list = gail_notebook->page_cache;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (gtk_list)
|
|
||||||
{
|
|
||||||
if (!gail_list)
|
|
||||||
{
|
|
||||||
create_notebook_page_accessible (gail_notebook, notebook, i, FALSE, NULL);
|
|
||||||
}
|
|
||||||
else if (GAIL_NOTEBOOK_PAGE (gail_list->data)->page != gtk_list->data)
|
|
||||||
{
|
|
||||||
create_notebook_page_accessible (gail_notebook, notebook, i, TRUE, gail_list);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gail_list = gail_list->next;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
gtk_list = gtk_list->next;
|
|
||||||
}
|
|
||||||
g_list_free (gtk_list);
|
|
||||||
|
|
||||||
gail_notebook->page_count = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
reset_cache (GailNotebook *gail_notebook,
|
|
||||||
gint index)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
for (l = gail_notebook->page_cache; l; l = l->next)
|
|
||||||
{
|
|
||||||
if (GAIL_NOTEBOOK_PAGE (l->data)->index > index)
|
|
||||||
GAIL_NOTEBOOK_PAGE (l->data)->index -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_notebook_page_accessible (GailNotebook *gail_notebook,
|
create_notebook_page_accessible (GailNotebook *gail_notebook,
|
||||||
GtkNotebook *notebook,
|
GtkNotebook *notebook,
|
||||||
gint index,
|
GtkWidget *child)
|
||||||
gboolean insert_before,
|
|
||||||
GList *list)
|
|
||||||
{
|
{
|
||||||
AtkObject *obj;
|
AtkObject *obj;
|
||||||
|
|
||||||
obj = gail_notebook_page_new (notebook, index);
|
obj = gail_notebook_page_new (notebook, child);
|
||||||
g_object_ref (obj);
|
g_hash_table_insert (gail_notebook->pages,
|
||||||
if (insert_before)
|
child,
|
||||||
gail_notebook->page_cache = g_list_insert_before (gail_notebook->page_cache, list, obj);
|
obj);
|
||||||
else
|
|
||||||
gail_notebook->page_cache = g_list_append (gail_notebook->page_cache, obj);
|
|
||||||
g_signal_connect (gtk_notebook_get_nth_page (notebook, index),
|
|
||||||
"parent_set",
|
|
||||||
G_CALLBACK (gail_notebook_child_parent_set),
|
|
||||||
obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gail_notebook_child_parent_set (GtkWidget *widget,
|
|
||||||
GtkWidget *old_parent,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GailNotebook *gail_notebook;
|
|
||||||
|
|
||||||
if (!old_parent)
|
|
||||||
return;
|
|
||||||
gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (old_parent));
|
|
||||||
gail_notebook->remove_index = GAIL_NOTEBOOK_PAGE (data)->index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -44,13 +44,10 @@ struct _GailNotebook
|
|||||||
* If the page is found in the list then a new page does not
|
* If the page is found in the list then a new page does not
|
||||||
* need to be created
|
* need to be created
|
||||||
*/
|
*/
|
||||||
GList* page_cache;
|
GHashTable * pages;
|
||||||
gint selected_page;
|
gint selected_page;
|
||||||
gint focus_tab_page;
|
gint focus_tab_page;
|
||||||
gint page_count;
|
|
||||||
guint idle_focus_id;
|
guint idle_focus_id;
|
||||||
|
|
||||||
gint remove_index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gail_notebook_get_type (void);
|
GType gail_notebook_get_type (void);
|
||||||
|
@ -156,7 +156,11 @@ notify_child_added (gpointer data)
|
|||||||
{
|
{
|
||||||
atk_parent = gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
|
atk_parent = gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
|
||||||
atk_object_set_parent (atk_object, atk_parent);
|
atk_object_set_parent (atk_object, atk_parent);
|
||||||
g_signal_emit_by_name (atk_parent, "children_changed::add", page->index, atk_object, NULL);
|
g_signal_emit_by_name (atk_parent,
|
||||||
|
"children_changed::add",
|
||||||
|
gtk_notebook_page_num (page->notebook, page->child),
|
||||||
|
atk_object,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -164,30 +168,20 @@ notify_child_added (gpointer data)
|
|||||||
|
|
||||||
AtkObject*
|
AtkObject*
|
||||||
gail_notebook_page_new (GtkNotebook *notebook,
|
gail_notebook_page_new (GtkNotebook *notebook,
|
||||||
gint pagenum)
|
GtkWidget *child)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
AtkObject *atk_object;
|
AtkObject *atk_object;
|
||||||
GailNotebookPage *page;
|
GailNotebookPage *page;
|
||||||
GtkWidget *child;
|
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *widget_page;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
|
g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
|
||||||
|
|
||||||
child = gtk_notebook_get_nth_page (notebook, pagenum);
|
|
||||||
|
|
||||||
if (!child)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL);
|
object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL);
|
||||||
g_return_val_if_fail (object != NULL, NULL);
|
|
||||||
|
|
||||||
page = GAIL_NOTEBOOK_PAGE (object);
|
page = GAIL_NOTEBOOK_PAGE (object);
|
||||||
page->notebook = notebook;
|
page->notebook = notebook;
|
||||||
page->index = pagenum;
|
page->child = child;
|
||||||
widget_page = gtk_notebook_get_nth_page (notebook, pagenum);
|
|
||||||
page->page = widget_page;
|
|
||||||
page->textutil = NULL;
|
page->textutil = NULL;
|
||||||
|
|
||||||
atk_object = ATK_OBJECT (page);
|
atk_object = ATK_OBJECT (page);
|
||||||
@ -223,6 +217,7 @@ gail_notebook_page_invalidate (GailNotebookPage *page)
|
|||||||
TRUE);
|
TRUE);
|
||||||
atk_object_set_parent (ATK_OBJECT (page), NULL);
|
atk_object_set_parent (ATK_OBJECT (page), NULL);
|
||||||
page->notebook = NULL;
|
page->notebook = NULL;
|
||||||
|
page->child = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -349,7 +344,6 @@ static AtkObject*
|
|||||||
gail_notebook_page_ref_child (AtkObject *accessible,
|
gail_notebook_page_ref_child (AtkObject *accessible,
|
||||||
gint i)
|
gint i)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
AtkObject *child_obj;
|
AtkObject *child_obj;
|
||||||
GailNotebookPage *page = NULL;
|
GailNotebookPage *page = NULL;
|
||||||
|
|
||||||
@ -361,11 +355,7 @@ gail_notebook_page_ref_child (AtkObject *accessible,
|
|||||||
if (!page->notebook)
|
if (!page->notebook)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
child = gtk_notebook_get_nth_page (page->notebook, page->index);
|
child_obj = gtk_widget_get_accessible (page->child);
|
||||||
if (!GTK_IS_WIDGET (child))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
child_obj = gtk_widget_get_accessible (child);
|
|
||||||
g_object_ref (child_obj);
|
g_object_ref (child_obj);
|
||||||
return child_obj;
|
return child_obj;
|
||||||
}
|
}
|
||||||
@ -375,10 +365,11 @@ gail_notebook_page_get_index_in_parent (AtkObject *accessible)
|
|||||||
{
|
{
|
||||||
GailNotebookPage *page;
|
GailNotebookPage *page;
|
||||||
|
|
||||||
g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), -1);
|
|
||||||
page = GAIL_NOTEBOOK_PAGE (accessible);
|
page = GAIL_NOTEBOOK_PAGE (accessible);
|
||||||
|
if (!page->notebook || !page->child)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return page->index;
|
return gtk_notebook_page_num (page->notebook, page->child);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AtkStateSet*
|
static AtkStateSet*
|
||||||
@ -794,11 +785,7 @@ get_label_from_notebook_page (GailNotebookPage *page)
|
|||||||
if (!gtk_notebook_get_show_tabs (notebook))
|
if (!gtk_notebook_get_show_tabs (notebook))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
child = gtk_notebook_get_nth_page (notebook, page->index);
|
child = gtk_notebook_get_tab_label (notebook, page->child);
|
||||||
if (child == NULL) return NULL;
|
|
||||||
g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
|
|
||||||
|
|
||||||
child = gtk_notebook_get_tab_label (notebook, child);
|
|
||||||
|
|
||||||
if (GTK_IS_LABEL (child))
|
if (GTK_IS_LABEL (child))
|
||||||
return child;
|
return child;
|
||||||
|
@ -40,13 +40,8 @@ struct _GailNotebookPage
|
|||||||
AtkObject parent;
|
AtkObject parent;
|
||||||
|
|
||||||
GtkNotebook *notebook;
|
GtkNotebook *notebook;
|
||||||
#ifndef GTK_DISABLE_DEPRECATED
|
|
||||||
GtkNotebookPage *page;
|
|
||||||
#else
|
|
||||||
gpointer page;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint index;
|
GtkWidget *child;
|
||||||
guint notify_child_added_id;
|
guint notify_child_added_id;
|
||||||
|
|
||||||
GailTextUtil *textutil;
|
GailTextUtil *textutil;
|
||||||
@ -59,7 +54,7 @@ struct _GailNotebookPageClass
|
|||||||
AtkObjectClass parent_class;
|
AtkObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
AtkObject *gail_notebook_page_new(GtkNotebook *notebook, gint pagenum);
|
AtkObject *gail_notebook_page_new(GtkNotebook *notebook, GtkWidget *child);
|
||||||
|
|
||||||
void gail_notebook_page_invalidate (GailNotebookPage *page);
|
void gail_notebook_page_invalidate (GailNotebookPage *page);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user