diff options
-rw-r--r-- | gtk/a11y/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/a11y/gail.c | 3 | ||||
-rw-r--r-- | gtk/a11y/gailutil.c | 50 | ||||
-rw-r--r-- | gtk/a11y/gailwindow.c | 940 | ||||
-rw-r--r-- | gtk/a11y/gailwindow.h | 51 | ||||
-rw-r--r-- | gtk/a11y/gtkwindowaccessible.c | 493 | ||||
-rw-r--r-- | gtk/a11y/gtkwindowaccessible.h | 51 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 3 | ||||
-rw-r--r-- | tests/a11y/assistant.txt | 447 |
9 files changed, 906 insertions, 1136 deletions
diff --git a/gtk/a11y/Makefile.am b/gtk/a11y/Makefile.am index bd3e3da86d..7007fa63e8 100644 --- a/gtk/a11y/Makefile.am +++ b/gtk/a11y/Makefile.am @@ -50,7 +50,7 @@ gail_c_sources = \ gtktreeviewaccessible.c \ gailutil.c \ gailwidget.c \ - gailwindow.c + gtkwindowaccessible.c libgailincludedir=$(includedir)/gail-3.0/gail @@ -101,7 +101,7 @@ gail_private_h_sources = \ gailtoplevel.h \ gtktreeviewaccessible.h \ gailutil.h \ - gailwindow.h + gtkwindowaccessible.h gail_public_h_sources = \ gailwidget.h diff --git a/gtk/a11y/gail.c b/gtk/a11y/gail.c index 60d9088d6d..354d81479f 100644 --- a/gtk/a11y/gail.c +++ b/gtk/a11y/gail.c @@ -35,7 +35,6 @@ #include "gailtoplevel.h" #include "gailutil.h" #include "gailwidget.h" -#include "gailwindow.h" #include "gailfactory.h" @@ -85,7 +84,6 @@ GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WIDGET, GailWidget, gail_widget, GTK_TYPE_WIDG GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CONTAINER, GailContainer, gail_container, GTK_TYPE_CONTAINER) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GTK_TYPE_MENU_SHELL) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU) -GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN) GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_RENDERER_CELL, GailRendererCell, gail_renderer_cell, GTK_TYPE_CELL_RENDERER, gail_renderer_cell_new) GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_BOOLEAN_CELL, GailBooleanCell, gail_boolean_cell, GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell_new) GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_IMAGE_CELL, GailImageCell, gail_image_cell, GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell_new) @@ -834,7 +832,6 @@ gail_accessibility_module_init (void) GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CONTAINER, gail_container); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_BAR, gail_menu_shell); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu); - GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell); diff --git a/gtk/a11y/gailutil.c b/gtk/a11y/gailutil.c index 316efff919..d2424dc57f 100644 --- a/gtk/a11y/gailutil.c +++ b/gtk/a11y/gailutil.c @@ -24,7 +24,7 @@ #include <gtk/gtk.h> #include "gailutil.h" #include "gailtoplevel.h" -#include "gailwindow.h" +#include "gtkwindowaccessible.h" static void gail_util_class_init (GailUtilClass *klass); static void gail_util_init (GailUtil *utils); @@ -147,7 +147,7 @@ gail_util_add_global_event_listener (GSignalEmissionHook listener, do_window_event_initialization (); initialized = TRUE; } - rc = add_listener (listener, "GailWindow", split_string[1], event_type); + rc = add_listener (listener, "GtkWindowAccessible", split_string[1], event_type); } else { @@ -403,9 +403,9 @@ do_window_event_initialization (void) AtkObject *root; /* - * Ensure that GailWindowClass exists. + * Ensure that GtkWindowAccessibleClass exists. */ - g_type_class_ref (GAIL_TYPE_WINDOW); + g_type_class_ref (GTK_TYPE_WINDOW_ACCESSIBLE); g_signal_add_emission_hook (g_signal_lookup ("window-state-event", GTK_TYPE_WIDGET), 0, state_event_watcher, NULL, (GDestroyNotify) NULL); g_signal_add_emission_hook (g_signal_lookup ("configure-event", GTK_TYPE_WIDGET), @@ -461,15 +461,15 @@ state_event_watcher (GSignalInvocationHint *hint, atk_obj = gtk_widget_get_accessible (widget); - if (GAIL_IS_WINDOW (atk_obj)) + if (GTK_IS_WINDOW_ACCESSIBLE (atk_obj)) { parent = atk_object_get_parent (atk_obj); if (parent == atk_get_root ()) - { - signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW); - g_signal_emit (atk_obj, signal_id, 0); - } - + { + signal_id = g_signal_lookup (signal_name, GTK_TYPE_WINDOW_ACCESSIBLE); + g_signal_emit (atk_obj, signal_id, 0); + } + return TRUE; } else @@ -485,17 +485,15 @@ window_added (AtkObject *atk_obj, { GtkWidget *widget; - if (!GAIL_IS_WINDOW (child)) return; + if (!GTK_IS_WINDOW_ACCESSIBLE (child)) return; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child)); if (!widget) return; - g_signal_connect (widget, "focus-in-event", - (GCallback) window_focus, NULL); - g_signal_connect (widget, "focus-out-event", - (GCallback) window_focus, NULL); - g_signal_emit (child, g_signal_lookup ("create", GAIL_TYPE_WINDOW), 0); + g_signal_connect (widget, "focus-in-event", (GCallback) window_focus, NULL); + g_signal_connect (widget, "focus-out-event", (GCallback) window_focus, NULL); + g_signal_emit (child, g_signal_lookup ("create", GTK_TYPE_WINDOW_ACCESSIBLE), 0); } @@ -507,7 +505,7 @@ window_removed (AtkObject *atk_obj, GtkWidget *widget; GtkWindow *window; - if (!GAIL_IS_WINDOW (child)) return; + if (!GTK_IS_WINDOW_ACCESSIBLE (child)) return; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child)); if (!widget) @@ -526,11 +524,11 @@ window_removed (AtkObject *atk_obj, atk_obj = gtk_widget_get_accessible (widget); signal_name = "deactivate"; - g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0); + g_signal_emit (atk_obj, g_signal_lookup (signal_name, GTK_TYPE_WINDOW_ACCESSIBLE), 0); } g_signal_handlers_disconnect_by_func (widget, (gpointer) window_focus, NULL); - g_signal_emit (child, g_signal_lookup ("destroy", GAIL_TYPE_WINDOW), 0); + g_signal_emit (child, g_signal_lookup ("destroy", GTK_TYPE_WINDOW_ACCESSIBLE), 0); } static gboolean @@ -544,7 +542,7 @@ window_focus (GtkWidget *widget, atk_obj = gtk_widget_get_accessible (widget); signal_name = (event->in) ? "activate" : "deactivate"; - g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0); + g_signal_emit (atk_obj, g_signal_lookup (signal_name, GTK_TYPE_WINDOW_ACCESSIBLE), 0); return FALSE; } @@ -593,15 +591,15 @@ configure_event_watcher (GSignalInvocationHint *hint, } atk_obj = gtk_widget_get_accessible (widget); - if (GAIL_IS_WINDOW (atk_obj)) + if (GTK_IS_WINDOW_ACCESSIBLE (atk_obj)) { parent = atk_object_get_parent (atk_obj); if (parent == atk_get_root ()) - { - signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW); - g_signal_emit (atk_obj, signal_id, 0); - } - + { + signal_id = g_signal_lookup (signal_name, GTK_TYPE_WINDOW_ACCESSIBLE); + g_signal_emit (atk_obj, signal_id, 0); + } + return TRUE; } else diff --git a/gtk/a11y/gailwindow.c b/gtk/a11y/gailwindow.c deleted file mode 100644 index 70cd56c898..0000000000 --- a/gtk/a11y/gailwindow.c +++ /dev/null @@ -1,940 +0,0 @@ -/* GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include <string.h> - -#include <gtk/gtkx.h> - -#include "gailwindow.h" -#include "gailtoplevel.h" - -enum { - ACTIVATE, - CREATE, - DEACTIVATE, - DESTROY, - MAXIMIZE, - MINIMIZE, - MOVE, - RESIZE, - RESTORE, - LAST_SIGNAL -}; - -static void gail_window_class_init (GailWindowClass *klass); - -static void gail_window_init (GailWindow *accessible); - -static void gail_window_real_initialize (AtkObject *obj, - gpointer data); - -static const gchar* gail_window_get_name (AtkObject *accessible); - -static AtkObject* gail_window_get_parent (AtkObject *accessible); -static gint gail_window_get_index_in_parent (AtkObject *accessible); -static gboolean gail_window_real_focus_gtk (GtkWidget *widget, - GdkEventFocus *event); - -static AtkStateSet* gail_window_ref_state_set (AtkObject *accessible); -static AtkRelationSet* gail_window_ref_relation_set (AtkObject *accessible); -static void gail_window_real_notify_gtk (GObject *obj, - GParamSpec *pspec); -static gint gail_window_get_mdi_zorder (AtkComponent *component); - -static gboolean gail_window_state_event_gtk (GtkWidget *widget, - GdkEventWindowState *event); - -/* atkcomponent.h */ -static void atk_component_interface_init (AtkComponentIface *iface); - -static void gail_window_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type); -static void gail_window_get_size (AtkComponent *component, - gint *width, - gint *height); - -static guint gail_window_signals [LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_CODE (GailWindow, gail_window, GAIL_TYPE_CONTAINER, - G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) - -static void -gail_window_class_init (GailWindowClass *klass) -{ - GailWidgetClass *widget_class; - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - widget_class = (GailWidgetClass*)klass; - widget_class->focus_gtk = gail_window_real_focus_gtk; - widget_class->notify_gtk = gail_window_real_notify_gtk; - - class->get_name = gail_window_get_name; - class->get_parent = gail_window_get_parent; - class->get_index_in_parent = gail_window_get_index_in_parent; - class->ref_relation_set = gail_window_ref_relation_set; - class->ref_state_set = gail_window_ref_state_set; - class->initialize = gail_window_real_initialize; - - gail_window_signals [ACTIVATE] = - g_signal_new ("activate", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [CREATE] = - g_signal_new ("create", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [DEACTIVATE] = - g_signal_new ("deactivate", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [DESTROY] = - g_signal_new ("destroy", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [MAXIMIZE] = - g_signal_new ("maximize", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [MINIMIZE] = - g_signal_new ("minimize", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [MOVE] = - g_signal_new ("move", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [RESIZE] = - g_signal_new ("resize", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - gail_window_signals [RESTORE] = - g_signal_new ("restore", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, /* default signal handler */ - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gail_window_init (GailWindow *accessible) -{ -} - -static void -gail_window_real_initialize (AtkObject *obj, - gpointer data) -{ - GtkWidget *widget = GTK_WIDGET (data); - - /* - * A GailWindow can be created for a GtkHandleBox or a GtkWindow - */ - if (!GTK_IS_WINDOW (widget) && !GTK_IS_HANDLE_BOX (widget)) - return; - - ATK_OBJECT_CLASS (gail_window_parent_class)->initialize (obj, data); - - g_signal_connect (data, - "window_state_event", - G_CALLBACK (gail_window_state_event_gtk), - NULL); - g_object_set_data (G_OBJECT (obj), "atk-component-layer", - GINT_TO_POINTER (ATK_LAYER_WINDOW)); - - if (GTK_IS_FILE_CHOOSER_DIALOG (widget)) - obj->role = ATK_ROLE_FILE_CHOOSER; - else if (GTK_IS_COLOR_SELECTION_DIALOG (widget)) - obj->role = ATK_ROLE_COLOR_CHOOSER; - else if (GTK_IS_FONT_SELECTION_DIALOG (widget)) - obj->role = ATK_ROLE_FONT_CHOOSER; - else if (GTK_IS_MESSAGE_DIALOG (widget)) - obj->role = ATK_ROLE_ALERT; - else if (GTK_IS_DIALOG (widget)) - obj->role = ATK_ROLE_DIALOG; - else - { - const gchar *name; - - name = gtk_widget_get_name (widget); - - if (!g_strcmp0 (name, "gtk-tooltip")) - obj->role = ATK_ROLE_TOOL_TIP; -#ifdef GDK_WINDOWING_X11 - else if (GTK_IS_PLUG (widget)) - obj->role = ATK_ROLE_PANEL; -#endif - else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP) - obj->role = ATK_ROLE_WINDOW; - else - obj->role = ATK_ROLE_FRAME; - } - - /* - * Notify that tooltip is showing - */ - if (obj->role == ATK_ROLE_TOOL_TIP && - gtk_widget_get_mapped (widget)) - atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1); -} - -static const gchar* -gail_window_get_name (AtkObject *accessible) -{ - const gchar* name; - - name = ATK_OBJECT_CLASS (gail_window_parent_class)->get_name (accessible); - if (name == NULL) - { - /* - * Get the window title if it exists - */ - GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - - if (widget == NULL) - return NULL; - - if (GTK_IS_WINDOW (widget)) - { - GtkWindow *window = GTK_WINDOW (widget); - - name = gtk_window_get_title (window); - if (name == NULL && - accessible->role == ATK_ROLE_TOOL_TIP) - { - GtkWidget *child; - - child = gtk_bin_get_child (GTK_BIN (window)); - /* could be some kind of egg notification bubble thingy? */ - - /* Handle new GTK+ GNOME 2.20 tooltips */ - if (GTK_IS_ALIGNMENT(child)) - { - child = gtk_bin_get_child (GTK_BIN (child)); - if (GTK_IS_BOX(child)) - { - GList *children; - guint count; - children = gtk_container_get_children (GTK_CONTAINER (child)); - count = g_list_length (children); - if (count == 2) - { - child = (GtkWidget *) g_list_nth_data (children, 1); - } - g_list_free (children); - } - } - - if (!GTK_IS_LABEL (child)) - { - g_message ("ATK_ROLE_TOOLTIP object found, but doesn't look like a tooltip."); - return NULL; - } - name = gtk_label_get_text (GTK_LABEL (child)); - } - } - } - return name; -} - -static AtkObject* -gail_window_get_parent (AtkObject *accessible) -{ - AtkObject* parent; - - parent = ATK_OBJECT_CLASS (gail_window_parent_class)->get_parent (accessible); - - return parent; -} - -static gint -gail_window_get_index_in_parent (AtkObject *accessible) -{ - GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - AtkObject* atk_obj = atk_get_root (); - gint index = -1; - - if (widget == NULL) - return -1; - - index = ATK_OBJECT_CLASS (gail_window_parent_class)->get_index_in_parent (accessible); - if (index != -1) - return index; - - if (GTK_IS_WINDOW (widget)) - { - GtkWindow *window = GTK_WINDOW (widget); - if (GAIL_IS_TOPLEVEL (atk_obj)) - { - GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj); - index = g_list_index (toplevel->window_list, window); - } - else - { - int i, sibling_count = atk_object_get_n_accessible_children (atk_obj); - for (i = 0; i < sibling_count && index == -1; ++i) - { - AtkObject *child = atk_object_ref_accessible_child (atk_obj, i); - if (accessible == child) index = i; - g_object_unref (G_OBJECT (child)); - } - } - } - return index; -} - -static gboolean -gail_window_real_focus_gtk (GtkWidget *widget, - GdkEventFocus *event) -{ - AtkObject* obj; - - obj = gtk_widget_get_accessible (widget); - atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in); - - return FALSE; -} - -static AtkRelationSet* -gail_window_ref_relation_set (AtkObject *obj) -{ - GtkWidget *widget; - AtkRelationSet *relation_set; - AtkObject *array[1]; - AtkRelation* relation; - GtkWidget *current_widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - return NULL; - - relation_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_relation_set (obj); - - if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP) - { - relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR); - - if (relation) - { - atk_relation_set_remove (relation_set, relation); - } - if (gtk_widget_get_visible(widget) && FALSE /* FIXME gtk_tooltips_get_info_from_tip_window (GTK_WINDOW (widget), NULL, ¤t_widget) */) - { - array [0] = gtk_widget_get_accessible (current_widget); - - relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR); - atk_relation_set_add (relation_set, relation); - g_object_unref (relation); - } - } - return relation_set; -} - -static AtkStateSet* -gail_window_ref_state_set (AtkObject *accessible) -{ - AtkStateSet *state_set; - GtkWidget *widget; - GtkWindow *window; - GdkWindow *gdk_window; - GdkWindowState state; - - state_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_state_set (accessible); - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - - if (widget == NULL) - return state_set; - - window = GTK_WINDOW (widget); - - if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window)) - atk_state_set_add_state (state_set, ATK_STATE_ACTIVE); - - gdk_window = gtk_widget_get_window (widget); - if (window) - { - state = gdk_window_get_state (gdk_window); - if (state & GDK_WINDOW_STATE_ICONIFIED) - atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED); - } - if (gtk_window_get_modal (window)) - atk_state_set_add_state (state_set, ATK_STATE_MODAL); - - if (gtk_window_get_resizable (window)) - atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE); - - return state_set; -} - -static void -gail_window_real_notify_gtk (GObject *obj, - GParamSpec *pspec) -{ - GtkWidget *widget = GTK_WIDGET (obj); - AtkObject* atk_obj = gtk_widget_get_accessible (widget); - - if (strcmp (pspec->name, "title") == 0) - { - g_object_notify (G_OBJECT (atk_obj), "accessible-name"); - g_signal_emit_by_name (atk_obj, "visible_data_changed"); - } - else - GAIL_WIDGET_CLASS (gail_window_parent_class)->notify_gtk (obj, pspec); -} - -static gboolean -gail_window_state_event_gtk (GtkWidget *widget, - GdkEventWindowState *event) -{ - AtkObject* obj; - - obj = gtk_widget_get_accessible (widget); - atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED, - (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0); - return FALSE; -} - -static void -atk_component_interface_init (AtkComponentIface *iface) -{ - iface->get_extents = gail_window_get_extents; - iface->get_size = gail_window_get_size; - iface->get_mdi_zorder = gail_window_get_mdi_zorder; -} - -static void -gail_window_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); - GdkRectangle rect; - gint x_toplevel, y_toplevel; - - if (widget == NULL) - return; - - if (!gtk_widget_is_toplevel (widget)) - { - AtkComponentIface *parent_iface; - - parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component)); - parent_iface->get_extents (component, x, y, width, height, coord_type); - return; - } - - gdk_window_get_frame_extents (gtk_widget_get_window (widget), - &rect); - - *width = rect.width; - *height = rect.height; - if (!gtk_widget_is_drawable (widget)) - { - *x = G_MININT; - *y = G_MININT; - return; - } - *x = rect.x; - *y = rect.y; - if (coord_type == ATK_XY_WINDOW) - { - gdk_window_get_origin (gtk_widget_get_window (widget), - &x_toplevel, &y_toplevel); - *x -= x_toplevel; - *y -= y_toplevel; - } -} - -static void -gail_window_get_size (AtkComponent *component, - gint *width, - gint *height) -{ - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); - GdkRectangle rect; - - if (widget == NULL) - return; - - if (!gtk_widget_is_toplevel (widget)) - { - AtkComponentIface *parent_iface; - - parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component)); - parent_iface->get_size (component, width, height); - return; - } - gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect); - - *width = rect.width; - *height = rect.height; -} - -#if defined (GDK_WINDOWING_X11) - -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <gdk/x11/gdkx.h> - -/* _NET_CLIENT_LIST_STACKING monitoring */ - -typedef struct { - Window *stacked_windows; - int stacked_windows_len; - GdkWindow *root_window; - guint update_handler; - int *desktop; - guint update_desktop_handler; - gboolean *desktop_changed; - - guint screen_initialized : 1; - guint update_stacked_windows : 1; -} GailScreenInfo; - -static GailScreenInfo *gail_screens = NULL; -static int num_screens = 0; -static Atom _net_client_list_stacking = None; -static Atom _net_wm_desktop = None; - -static gint -get_window_desktop (Window window) -{ - Atom ret_type; - int format; - gulong nitems; - gulong bytes_after; - guchar *cardinals; - int error; - int result; - int desktop; - - if (_net_wm_desktop == None) - _net_wm_desktop = - XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_DESKTOP", False); - - gdk_error_trap_push (); - result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), window, _net_wm_desktop, - 0, G_MAXLONG, - False, XA_CARDINAL, - &ret_type, &format, &nitems, - &bytes_after, &cardinals); - error = gdk_error_trap_pop(); - /* nitems < 1 will occur if the property is not set */ - if (error != Success || result != Success || nitems < 1) - return -1; - - desktop = *cardinals; - - XFree (cardinals); - if (nitems != 1) - return -1; - return desktop; -} - -static void -free_screen_info (GailScreenInfo *info) -{ - if (info->stacked_windows) - XFree (info->stacked_windows); - if (info->desktop) - g_free (info->desktop); - if (info->desktop_changed) - g_free (info->desktop_changed); - - info->stacked_windows = NULL; - info->stacked_windows_len = 0; - info->desktop = NULL; - info->desktop_changed = NULL; -} - -static gboolean -get_stacked_windows (GailScreenInfo *info) -{ - Atom ret_type; - int format; - gulong nitems; - gulong bytes_after; - guchar *data; - int error; - int result; - int i; - int j; - int *desktops; - gboolean *desktops_changed; - - if (_net_client_list_stacking == None) - _net_client_list_stacking = - XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_CLIENT_LIST_STACKING", False); - - gdk_error_trap_push (); - ret_type = None; - result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - GDK_WINDOW_XID (info->root_window), - _net_client_list_stacking, - 0, G_MAXLONG, - False, XA_WINDOW, &ret_type, &format, &nitems, - &bytes_after, &data); - error = gdk_error_trap_pop (); - /* nitems < 1 will occur if the property is not set */ - if (error != Success || result != Success || nitems < 1) - { - free_screen_info (info); - return FALSE; - } - - if (ret_type != XA_WINDOW) - { - XFree (data); - free_screen_info (info); - return FALSE; - } - - desktops = g_malloc0 (nitems * sizeof (int)); - desktops_changed = g_malloc0 (nitems * sizeof (gboolean)); - for (i = 0; i < nitems; i++) - { - gboolean window_found = FALSE; - - for (j = 0; j < info->stacked_windows_len; j++) - { - if (info->stacked_windows [j] == data [i]) - { - desktops [i] = info->desktop [j]; - desktops_changed [i] = info->desktop_changed [j]; - window_found = TRUE; - break; - } - } - if (!window_found) - { - desktops [i] = get_window_desktop (data [i]); - desktops_changed [i] = FALSE; - } - } - free_screen_info (info); - info->stacked_windows = (Window*) data; - info->stacked_windows_len = nitems; - info->desktop = desktops; - info->desktop_changed = desktops_changed; - - return TRUE; -} - -static gboolean -update_screen_info (gpointer data) -{ - int screen_n = GPOINTER_TO_INT (data); - - gail_screens [screen_n].update_handler = 0; - gail_screens [screen_n].update_stacked_windows = FALSE; - - get_stacked_windows (&gail_screens [screen_n]); - - return FALSE; -} - -static gboolean -update_desktop_info (gpointer data) -{ - int screen_n = GPOINTER_TO_INT (data); - GailScreenInfo *info; - int i; - - info = &gail_screens [screen_n]; - info->update_desktop_handler = 0; - - for (i = 0; i < info->stacked_windows_len; i++) - { - if (info->desktop_changed [i]) - { - info->desktop [i] = get_window_desktop (info->stacked_windows [i]); - info->desktop_changed [i] = FALSE; - } - } - - return FALSE; -} - -static GdkFilterReturn -filter_func (GdkXEvent *gdkxevent, - GdkEvent *event, - gpointer data) -{ - XEvent *xevent = gdkxevent; - - if (xevent->type == PropertyNotify) - { - if (xevent->xproperty.atom == _net_client_list_stacking) - { - int screen_n; - GdkWindow *window; - - window = event->any.window; - - if (window) - { - screen_n = gdk_screen_get_number (gdk_window_get_screen (window)); - - gail_screens [screen_n].update_stacked_windows = TRUE; - if (!gail_screens [screen_n].update_handler) - { - gail_screens [screen_n].update_handler = gdk_threads_add_idle (update_screen_info, - GINT_TO_POINTER (screen_n)); - } - } - } - else if (xevent->xproperty.atom == _net_wm_desktop) - { - int i; - int j; - GailScreenInfo *info; - - for (i = 0; i < num_screens; i++) - { - info = &gail_screens [i]; - for (j = 0; j < info->stacked_windows_len; j++) - { - if (xevent->xany.window == info->stacked_windows [j]) - { - info->desktop_changed [j] = TRUE; - if (!info->update_desktop_handler) - { - info->update_desktop_handler = gdk_threads_add_idle (update_desktop_info, - GINT_TO_POINTER (i)); - } - break; - } - } - } - } - } - return GDK_FILTER_CONTINUE; -} - -static void -display_closed (GdkDisplay *display, - gboolean is_error) -{ - int i; - - for (i = 0; i < num_screens; i++) - { - if (gail_screens [i].update_handler) - { - g_source_remove (gail_screens [i].update_handler); - gail_screens [i].update_handler = 0; - } - - if (gail_screens [i].update_desktop_handler) - { - g_source_remove (gail_screens [i].update_desktop_handler); - gail_screens [i].update_desktop_handler = 0; - } - - free_screen_info (&gail_screens [i]); - } - - g_free (gail_screens); - gail_screens = NULL; - num_screens = 0; -} - -static void -init_gail_screens (void) -{ - GdkDisplay *display; - - display = gdk_display_get_default (); - - num_screens = gdk_display_get_n_screens (display); - - gail_screens = g_new0 (GailScreenInfo, num_screens); - gdk_window_add_filter (NULL, filter_func, NULL); - - g_signal_connect (display, "closed", G_CALLBACK (display_closed), NULL); -} - -static void -init_gail_screen (GdkScreen *screen, - int screen_n) -{ - XWindowAttributes attrs; - - gail_screens [screen_n].root_window = gdk_screen_get_root_window (screen); - - get_stacked_windows (&gail_screens [screen_n]); - - XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - GDK_WINDOW_XID (gail_screens [screen_n].root_window), - &attrs); - - XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - GDK_WINDOW_XID (gail_screens [screen_n].root_window), - attrs.your_event_mask | PropertyChangeMask); - - gail_screens [screen_n].screen_initialized = TRUE; -} - -static GailScreenInfo * -get_screen_info (GdkScreen *screen) -{ - gint screen_n; - - screen_n = gdk_screen_get_number (screen); - - if (gail_screens && gail_screens [screen_n].screen_initialized) - return &gail_screens [screen_n]; - - if (!gail_screens) - init_gail_screens (); - - g_assert (gail_screens != NULL); - - init_gail_screen (screen, screen_n); - - g_assert (gail_screens [screen_n].screen_initialized); - - return &gail_screens [screen_n]; -} - -static gint -get_window_zorder (GdkWindow *window) -{ - GailScreenInfo *info; - Window xid; - int i; - int zorder; - int w_desktop; - - info = get_screen_info (gdk_window_get_screen (window)); - - if (info->stacked_windows == NULL) - return -1; - - xid = GDK_WINDOW_XID (window); - - w_desktop = -1; - for (i = 0; i < info->stacked_windows_len; i++) - { - if (info->stacked_windows [i] == xid) - { - w_desktop = info->desktop[i]; - break; - } - } - if (w_desktop < 0) - return w_desktop; - - zorder = 0; - for (i = 0; i < info->stacked_windows_len; i++) - { - if (info->stacked_windows [i] == xid) - { - return zorder; - } - else - { - if (info->desktop[i] == w_desktop) - zorder++; - } - } - - return -1; -} - -static gint -gail_window_get_mdi_zorder (AtkComponent *component) -{ - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); - - if (widget == NULL) - return -1; - - return get_window_zorder (gtk_widget_get_window (widget)); -} - -#elif defined (GDK_WINDOWING_WIN32) - -static gint -gail_window_get_mdi_zorder (AtkComponent *component) -{ - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); - - if (widget == NULL) - return -1; - - return 0; /* Punt, FIXME */ -} - -#else - -static gint -gail_window_get_mdi_zorder (AtkComponent *component) -{ - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); - - if (widget == NULL) - return -1; - - return 0; /* Punt, FIXME */ -} - -#endif diff --git a/gtk/a11y/gailwindow.h b/gtk/a11y/gailwindow.h deleted file mode 100644 index 10bf5a7f27..0000000000 --- a/gtk/a11y/gailwindow.h +++ /dev/null @@ -1,51 +0,0 @@ -/* GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GAIL_WINDOW_H__ -#define __GAIL_WINDOW_H__ - -#include "gailcontainer.h" - -G_BEGIN_DECLS - -#define GAIL_TYPE_WINDOW (gail_window_get_type ()) -#define GAIL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_WINDOW, GailWindow)) -#define GAIL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_WINDOW, GailWindowClass)) -#define GAIL_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_WINDOW)) -#define GAIL_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_WINDOW)) -#define GAIL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_WINDOW, GailWindowClass)) - -typedef struct _GailWindow GailWindow; -typedef struct _GailWindowClass GailWindowClass; - -struct _GailWindow -{ - GailContainer parent; -}; - -GType gail_window_get_type (void); - -struct _GailWindowClass -{ - GailContainerClass parent_class; -}; - -G_END_DECLS - -#endif /* __GAIL_WINDOW_H__ */ diff --git a/gtk/a11y/gtkwindowaccessible.c b/gtk/a11y/gtkwindowaccessible.c new file mode 100644 index 0000000000..f07d35f550 --- /dev/null +++ b/gtk/a11y/gtkwindowaccessible.c @@ -0,0 +1,493 @@ +/* GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include <string.h> + +#include <gtk/gtkx.h> + +#include "gtkwindowaccessible.h" +#include "gailtoplevel.h" + +enum { + ACTIVATE, + CREATE, + DEACTIVATE, + DESTROY, + MAXIMIZE, + MINIMIZE, + MOVE, + RESIZE, + RESTORE, + LAST_SIGNAL +}; + + +/* atkcomponent.h */ + +static void gtk_window_accessible_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type); +static void gtk_window_accessible_get_size (AtkComponent *component, + gint *width, + gint *height); + +static guint gtk_window_accessible_signals [LAST_SIGNAL] = { 0, }; + +static void atk_component_interface_init (AtkComponentIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkWindowAccessible, gtk_window_accessible, GAIL_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) + + +static gboolean +gtk_window_accessible_focus_gtk (GtkWidget *widget, + GdkEventFocus *event) +{ + AtkObject* obj; + + obj = gtk_widget_get_accessible (widget); + atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in); + + return FALSE; +} + +static void +gtk_window_accessible_notify_gtk (GObject *obj, + GParamSpec *pspec) +{ + GtkWidget *widget = GTK_WIDGET (obj); + AtkObject* atk_obj = gtk_widget_get_accessible (widget); + + if (strcmp (pspec->name, "title") == 0) + { + g_object_notify (G_OBJECT (atk_obj), "accessible-name"); + g_signal_emit_by_name (atk_obj, "visible_data_changed"); + } + else + GAIL_WIDGET_CLASS (gtk_window_accessible_parent_class)->notify_gtk (obj, pspec); +} + +static gboolean +window_state_event_cb (GtkWidget *widget, + GdkEventWindowState *event) +{ + AtkObject* obj; + + obj = gtk_widget_get_accessible (widget); + atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED, + (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0); + + return FALSE; +} + +static void +gtk_window_accessible_initialize (AtkObject *obj, + gpointer data) +{ + GtkWidget *widget = GTK_WIDGET (data); + + /* A GtkWindowAccessible can be created for a GtkHandleBox or a GtkWindow */ + if (!GTK_IS_WINDOW (widget) && !GTK_IS_HANDLE_BOX (widget)) + return; + + ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->initialize (obj, data); + + g_signal_connect (data, "window_state_event", G_CALLBACK (window_state_event_cb), NULL); + g_object_set_data (G_OBJECT (obj), "atk-component-layer", GINT_TO_POINTER (ATK_LAYER_WINDOW)); + + if (GTK_IS_FILE_CHOOSER_DIALOG (widget)) + obj->role = ATK_ROLE_FILE_CHOOSER; + else if (GTK_IS_COLOR_SELECTION_DIALOG (widget)) + obj->role = ATK_ROLE_COLOR_CHOOSER; + else if (GTK_IS_FONT_SELECTION_DIALOG (widget)) + obj->role = ATK_ROLE_FONT_CHOOSER; + else if (GTK_IS_MESSAGE_DIALOG (widget)) + obj->role = ATK_ROLE_ALERT; + else if (GTK_IS_DIALOG (widget)) + obj->role = ATK_ROLE_DIALOG; + else + { + const gchar *name; + + name = gtk_widget_get_name (widget); + + if (!g_strcmp0 (name, "gtk-tooltip")) + obj->role = ATK_ROLE_TOOL_TIP; +#ifdef GDK_WINDOWING_X11 + else if (GTK_IS_PLUG (widget)) + obj->role = ATK_ROLE_PANEL; +#endif + else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP) + obj->role = ATK_ROLE_WINDOW; + else + obj->role = ATK_ROLE_FRAME; + } + + /* Notify that tooltip is showing */ + if (obj->role == ATK_ROLE_TOOL_TIP && gtk_widget_get_mapped (widget)) + atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1); +} + +static GtkWidget * +find_label_child (GtkContainer *container) +{ + GList *children, *tmp_list; + GtkWidget *child; + + children = gtk_container_get_children (container); + + child = NULL; + for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next) + { + if (GTK_IS_LABEL (tmp_list->data)) + { + child = GTK_WIDGET (tmp_list->data); + break; + } + else if (GTK_IS_CONTAINER (tmp_list->data)) + { + child = find_label_child (GTK_CONTAINER (tmp_list->data)); + if (child) + break; + } + } + g_list_free (children); + return child; +} + +static const gchar * +gtk_window_accessible_get_name (AtkObject *accessible) +{ + const gchar* name; + GtkWidget* widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + if (widget == NULL) + return NULL; + + name = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_name (accessible); + if (name != NULL) + return name; + + if (GTK_IS_WINDOW (widget)) + { + GtkWindow *window = GTK_WINDOW (widget); + + name = gtk_window_get_title (window); + if (name == NULL && accessible->role == ATK_ROLE_TOOL_TIP) + { + GtkWidget *child; + + child = find_label_child (GTK_CONTAINER (window)); + if (GTK_IS_LABEL (child)) + name = gtk_label_get_text (GTK_LABEL (child)); + } + } + return name; +} + +static gint +gtk_window_accessible_get_index_in_parent (AtkObject *accessible) +{ + GtkWidget* widget; + AtkObject* atk_obj; + gint index = -1; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + if (widget == NULL) + return -1; + + index = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_index_in_parent (accessible); + if (index != -1) + return index; + + atk_obj = atk_get_root (); + + if (GTK_IS_WINDOW (widget)) + { + GtkWindow *window = GTK_WINDOW (widget); + if (GAIL_IS_TOPLEVEL (atk_obj)) + { + GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj); + index = g_list_index (toplevel->window_list, window); + } + else + { + gint i, sibling_count; + + sibling_count = atk_object_get_n_accessible_children (atk_obj); + for (i = 0; i < sibling_count && index == -1; ++i) + { + AtkObject *child = atk_object_ref_accessible_child (atk_obj, i); + if (accessible == child) + index = i; + g_object_unref (G_OBJECT (child)); + } + } + } + return index; +} + +static AtkRelationSet * +gtk_window_accessible_ref_relation_set (AtkObject *obj) +{ + GtkWidget *widget; + AtkRelationSet *relation_set; + AtkObject *array[1]; + AtkRelation* relation; + GtkWidget *current_widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + if (widget == NULL) + return NULL; + + relation_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_relation_set (obj); + + if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP) + { + relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR); + if (relation) + atk_relation_set_remove (relation_set, relation); + + if (0) /* FIXME need a way to go from tooltip window to widget */ + { + array[0] = gtk_widget_get_accessible (current_widget); + relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR); + atk_relation_set_add (relation_set, relation); + g_object_unref (relation); + } + } + return relation_set; +} + +static AtkStateSet * +gtk_window_accessible_ref_state_set (AtkObject *accessible) +{ + AtkStateSet *state_set; + GtkWidget *widget; + GtkWindow *window; + GdkWindow *gdk_window; + GdkWindowState state; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + if (widget == NULL) + return NULL; + + state_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_state_set (accessible); + + window = GTK_WINDOW (widget); + + if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window)) + atk_state_set_add_state (state_set, ATK_STATE_ACTIVE); + + gdk_window = gtk_widget_get_window (widget); + if (window) + { + state = gdk_window_get_state (gdk_window); + if (state & GDK_WINDOW_STATE_ICONIFIED) + atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED); + } + if (gtk_window_get_modal (window)) + atk_state_set_add_state (state_set, ATK_STATE_MODAL); + + if (gtk_window_get_resizable (window)) + atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE); + + return state_set; +} + +static void +gtk_window_accessible_class_init (GtkWindowAccessibleClass *klass) +{ + GailWidgetClass *widget_class = (GailWidgetClass*)klass; + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + widget_class->focus_gtk = gtk_window_accessible_focus_gtk; + widget_class->notify_gtk = gtk_window_accessible_notify_gtk; + + class->get_name = gtk_window_accessible_get_name; + class->get_index_in_parent = gtk_window_accessible_get_index_in_parent; + class->ref_relation_set = gtk_window_accessible_ref_relation_set; + class->ref_state_set = gtk_window_accessible_ref_state_set; + class->initialize = gtk_window_accessible_initialize; + + gtk_window_accessible_signals [ACTIVATE] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [CREATE] = + g_signal_new ("create", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [DEACTIVATE] = + g_signal_new ("deactivate", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [MAXIMIZE] = + g_signal_new ("maximize", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [MINIMIZE] = + g_signal_new ("minimize", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [MOVE] = + g_signal_new ("move", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [RESIZE] = + g_signal_new ("resize", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_window_accessible_signals [RESTORE] = + g_signal_new ("restore", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +gtk_window_accessible_init (GtkWindowAccessible *accessible) +{ +} + +static void +gtk_window_accessible_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + GtkWidget *widget; + GdkRectangle rect; + gint x_toplevel, y_toplevel; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); + if (widget == NULL) + return; + + if (!gtk_widget_is_toplevel (widget)) + { + AtkComponentIface *parent_iface; + + parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component)); + parent_iface->get_extents (component, x, y, width, height, coord_type); + return; + } + + gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect); + + *width = rect.width; + *height = rect.height; + if (!gtk_widget_is_drawable (widget)) + { + *x = G_MININT; + *y = G_MININT; + return; + } + + *x = rect.x; + *y = rect.y; + if (coord_type == ATK_XY_WINDOW) + { + gdk_window_get_origin (gtk_widget_get_window (widget), + &x_toplevel, &y_toplevel); + *x -= x_toplevel; + *y -= y_toplevel; + } +} + +static void +gtk_window_accessible_get_size (AtkComponent *component, + gint *width, + gint *height) +{ + GtkWidget *widget; + GdkRectangle rect; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component)); + if (widget == NULL) + return; + + if (!gtk_widget_is_toplevel (widget)) + { + AtkComponentIface *parent_iface; + + parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component)); + parent_iface->get_size (component, width, height); + return; + } + + gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect); + + *width = rect.width; + *height = rect.height; +} + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + iface->get_extents = gtk_window_accessible_get_extents; + iface->get_size = gtk_window_accessible_get_size; +} diff --git a/gtk/a11y/gtkwindowaccessible.h b/gtk/a11y/gtkwindowaccessible.h new file mode 100644 index 0000000000..ee9cb82cf5 --- /dev/null +++ b/gtk/a11y/gtkwindowaccessible.h @@ -0,0 +1,51 @@ +/* GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GTK_WINDOW_ACCESSIBLE_H__ +#define __GTK_WINDOW_ACCESSIBLE_H__ + +#include "gailcontainer.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_WINDOW_ACCESSIBLE (gtk_window_accessible_get_type ()) +#define GTK_WINDOW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WINDOW_ACCESSIBLE, GtkWindowAccessible)) +#define GTK_WINDOW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WINDOW_ACCESSIBLE, GtkWindowAccessibleClass)) +#define GTK_IS_WINDOW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WINDOW_ACCESSIBLE)) +#define GTK_IS_WINDOW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WINDOW_ACCESSIBLE)) +#define GTK_WINDOW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WINDOW_ACCESSIBLE, GtkWindowAccessibleClass)) + +typedef struct _GtkWindowAccessible GtkWindowAccessible; +typedef struct _GtkWindowAccessibleClass GtkWindowAccessibleClass; + +struct _GtkWindowAccessible +{ + GailContainer parent; +}; + +struct _GtkWindowAccessibleClass +{ + GailContainerClass parent_class; +}; + +GType gtk_window_accessible_get_type (void); + +G_END_DECLS + +#endif /* __GTK_WINDOW_ACCESSIBLE_H__ */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 4c65594e9d..3eb31054e7 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -50,6 +50,7 @@ #include "gtkcontainerprivate.h" #include "gtkintl.h" #include "gtktypebuiltins.h" +#include "a11y/gtkwindowaccessible.h" #ifdef GDK_WINDOWING_X11 #include "x11/gdkx.h" @@ -1060,6 +1061,8 @@ gtk_window_class_init (GtkWindowClass *klass) add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD); add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD); add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD); + + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE); } static void diff --git a/tests/a11y/assistant.txt b/tests/a11y/assistant.txt index 0a92cda657..5ac9641ed6 100644 --- a/tests/a11y/assistant.txt +++ b/tests/a11y/assistant.txt @@ -6,136 +6,355 @@ window1 <AtkComponent> layer: window alpha: 1 - button1 - "push button" - index: 0 - name: Page 1 - state: enabled focusable sensitive showing visible - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: -1 x -1 - image description: (null) - <AtkAction> - action 0 name: click - button2 - "push button" - index: 1 - name: Page 2 - state: enabled focusable sensitive visible - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: -1 x -1 - image description: (null) - <AtkAction> - action 0 name: click unnamed-GtkBoxAccessible-0 "filler" - parent: unnamed-GtkBoxAccessible-1 - index: 1 + parent: window1 + index: 0 state: enabled horizontal sensitive showing visible toolkit: gail <AtkComponent> layer: widget alpha: 1 - unnamed-GtkButtonAccessible-2 - "push button" + unnamed-GtkFrameAccessible-1 + "panel" parent: unnamed-GtkBoxAccessible-0 index: 0 - name: Close - state: enabled focusable sensitive + state: enabled sensitive showing visible toolkit: gail <AtkComponent> layer: widget alpha: 1 - <AtkImage> - image size: 20 x 20 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>c - unnamed-GtkButtonAccessible-3 - "push button" + unnamed-GtkBoxAccessible-2 + "filler" + parent: unnamed-GtkFrameAccessible-1 + index: 0 + state: enabled sensitive showing vertical visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + Page 1 + "label" + parent: unnamed-GtkBoxAccessible-2 + index: 0 + name: Page 1 + state: enabled multi-line sensitive + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkText> + text: Page 1 + character count: 6 + caret offset: 0 + default attributes: bg-color: <omitted> + bg-full-height: 0 + direction: <omitted> + editable: false + family-name: <omitted> + fg-color: <omitted> + indent: 0 + invisible: false + justification: left + language: <omitted> + left-margin: 0 + pixels-above-lines: 0 + pixels-below-lines: 0 + pixels-inside-wrap: 0 + right-margin: 0 + rise: 0 + scale: 1 + size: <omitted> + stretch: <omitted> + strikethrough: false + style: <omitted> + underline: none + variant: <omitted> + weight: <omitted> + wrap-mode: word + Page 1 + "label" + parent: unnamed-GtkBoxAccessible-2 + index: 1 + name: Page 1 + state: enabled multi-line sensitive visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkText> + text: Page 1 + character count: 6 + caret offset: 0 + default attributes: bg-color: <omitted> + bg-full-height: 0 + direction: <omitted> + editable: false + family-name: <omitted> + fg-color: <omitted> + indent: 0 + invisible: false + justification: left + language: <omitted> + left-margin: 0 + pixels-above-lines: 0 + pixels-below-lines: 0 + pixels-inside-wrap: 0 + right-margin: 0 + rise: 0 + scale: 1 + size: <omitted> + stretch: <omitted> + strikethrough: false + style: <omitted> + underline: none + variant: <omitted> + weight: <omitted> + wrap-mode: word + Page 2 + "label" + parent: unnamed-GtkBoxAccessible-2 + index: 2 + name: Page 2 + state: enabled multi-line sensitive showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkText> + text: Page 2 + character count: 6 + caret offset: 0 + default attributes: bg-color: <omitted> + bg-full-height: 0 + direction: <omitted> + editable: false + family-name: <omitted> + fg-color: <omitted> + indent: 0 + invisible: false + justification: left + language: <omitted> + left-margin: 0 + pixels-above-lines: 0 + pixels-below-lines: 0 + pixels-inside-wrap: 0 + right-margin: 0 + rise: 0 + scale: 1 + size: <omitted> + stretch: <omitted> + strikethrough: false + style: <omitted> + underline: none + variant: <omitted> + weight: <omitted> + wrap-mode: word + Page 2 + "label" + parent: unnamed-GtkBoxAccessible-2 + index: 3 + name: Page 2 + state: enabled multi-line sensitive + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkText> + text: Page 2 + character count: 6 + caret offset: 0 + default attributes: bg-color: <omitted> + bg-full-height: 0 + direction: <omitted> + editable: false + family-name: <omitted> + fg-color: <omitted> + indent: 0 + invisible: false + justification: left + language: <omitted> + left-margin: 0 + pixels-above-lines: 0 + pixels-below-lines: 0 + pixels-inside-wrap: 0 + right-margin: 0 + rise: 0 + scale: 1 + size: <omitted> + stretch: <omitted> + strikethrough: false + style: <omitted> + underline: none + variant: <omitted> + weight: <omitted> + wrap-mode: word + unnamed-GtkBoxAccessible-3 + "filler" parent: unnamed-GtkBoxAccessible-0 index: 1 - name: Cancel - state: enabled focusable sensitive showing visible - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: 20 x 20 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>c - unnamed-GtkButtonAccessible-4 - "push button" - parent: unnamed-GtkBoxAccessible-0 - index: 2 - name: Finish - state: focusable - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: -1 x -1 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>f - unnamed-GtkButtonAccessible-5 - "push button" - parent: unnamed-GtkBoxAccessible-0 - index: 3 - name: Go Back - state: enabled focusable sensitive - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: -1 x -1 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>b - unnamed-GtkButtonAccessible-6 - "push button" - parent: unnamed-GtkBoxAccessible-0 - index: 4 - name: Continue - state: focusable showing visible - toolkit: gail - <AtkComponent> - layer: widget - alpha: 1 - <AtkImage> - image size: 20 x 20 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>o - unnamed-GtkButtonAccessible-7 - "push button" - parent: unnamed-GtkBoxAccessible-0 - index: 5 - name: Apply - state: enabled focusable sensitive + state: enabled sensitive showing vertical visible toolkit: gail <AtkComponent> layer: widget alpha: 1 - <AtkImage> - image size: 20 x 20 - image description: (null) - <AtkAction> - action 0 name: click - action 0 keybinding: <Alt>a + unnamed-GtkNotebookAccessible-4 + "page tab list" + parent: unnamed-GtkBoxAccessible-3 + index: 0 + state: enabled sensitive showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkSelection> + selected children: unnamed-GtkNotebookPageAccessible-5 + unnamed-GtkNotebookPageAccessible-5 + "page tab" + parent: unnamed-GtkNotebookAccessible-4 + index: 0 + state: enabled selectable selected showing visible + <AtkComponent> + layer: widget + alpha: 1 + button1 + "push button" + index: 0 + name: Button 1 + state: enabled focusable sensitive showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: -1 x -1 + image description: (null) + <AtkAction> + action 0 name: click + unnamed-GtkNotebookPageAccessible-6 + "page tab" + parent: unnamed-GtkNotebookAccessible-4 + index: 1 + state: enabled selectable visible + <AtkComponent> + layer: widget + alpha: 1 + button2 + "push button" + index: 1 + name: Button 2 + state: enabled focusable sensitive visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: -1 x -1 + image description: (null) + <AtkAction> + action 0 name: click + unnamed-GtkBoxAccessible-7 + "filler" + parent: unnamed-GtkBoxAccessible-3 + index: 1 + state: enabled horizontal sensitive showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + unnamed-GtkButtonAccessible-8 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 0 + name: Close + state: enabled focusable sensitive + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: 20 x 20 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>c + unnamed-GtkButtonAccessible-9 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 1 + name: Cancel + state: enabled focusable sensitive showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: 20 x 20 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>c + unnamed-GtkButtonAccessible-10 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 2 + name: Finish + state: focusable + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: -1 x -1 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>f + unnamed-GtkButtonAccessible-11 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 3 + name: Go Back + state: enabled focusable sensitive + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: -1 x -1 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>b + unnamed-GtkButtonAccessible-12 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 4 + name: Continue + state: focusable showing visible + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: 20 x 20 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>o + unnamed-GtkButtonAccessible-13 + "push button" + parent: unnamed-GtkBoxAccessible-7 + index: 5 + name: Apply + state: enabled focusable sensitive + toolkit: gail + <AtkComponent> + layer: widget + alpha: 1 + <AtkImage> + image size: 20 x 20 + image description: (null) + <AtkAction> + action 0 name: click + action 0 keybinding: <Alt>a |