[g-a-devel]ATK/GAIL patch for bug #84097
- From: Bill Haneman <bill haneman sun com>
- To: gnome-accessibility-devel gnome org
- Subject: [g-a-devel]ATK/GAIL patch for bug #84097
- Date: 09 Sep 2002 14:12:07 +0100
Hi:
Attached is the patch for bug 84097, implementing window stacking
support for ATK/GAIL.
The patch does not yet expose "desktop" information, that is, stacking
information is available for toplevels but is not segregated by the
WM_DESKTOP property. Support for multiple 'virtual desktops' should
probably be the subject of another bug and patch; however the attached
patch (from Mark McLoughlin) should solve the problem in #84097.
The patch monitors _NET_CLIENT_LIST_STACKING in order to return current
values for the Z order of toplevel windows. It also reports that
toplevels are contained in ATK_LAYER_WINDOW, whereas toplevel windows
were previously (incorrectly) reported in ATK_LAYER_WIDGET.
regards,
Bill
----------
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gail/ChangeLog,v
retrieving revision 1.491
diff -u -p -r1.491 ChangeLog
--- ChangeLog 5 Sep 2002 13:29:23 -0000 1.491
+++ ChangeLog 6 Sep 2002 05:44:44 -0000
@@ -1,3 +1,16 @@
+2002-09-06 Mark McLoughlin <mark skynet ie>
+
+ * gail/gailwindow.c: (gail_window_class_init): fix warnings.
+ (gail_window_real_initialize): set layer as ATK_LAYER_WINDOW.
+ (atk_component_interface_init): set get_mdi_zorder.
+ (get_stacked_windows), (update_screen_info),
+ (root_window_event_filter), (display_closed),
+ (init_gail_screens), (init_gail_screen),
+ (get_screen_info), (get_window_zorder),
+ (gail_window_get_mdi_zorder): impl code to obtain the z-order
+ directly from _NET_CLIENT_LIST_STACKING root window property
+ and to monitor for changes on that property.
+
2002-09-05 Padraig O'Briain <padraig obriain sun com>
* docs/reference/libgail-util/gail-libgail-util-sections.txt:
Index: gail/gailwindow.c
===================================================================
RCS file: /cvs/gnome/gail/gail/gailwindow.c,v
retrieving revision 1.36
diff -u -p -r1.36 gailwindow.c
--- gail/gailwindow.c 15 Jul 2002 11:56:44 -0000 1.36
+++ gail/gailwindow.c 6 Sep 2002 05:44:46 -0000
@@ -49,6 +49,7 @@ static gboolean gail_window
static AtkStateSet* gail_window_ref_state_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);
@@ -129,7 +130,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("activate",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -137,7 +138,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("create",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -145,7 +146,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("deactivate",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -153,7 +154,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("destroy",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -161,7 +162,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("maximize",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -169,7 +170,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("minimize",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -177,7 +178,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("resize",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -185,7 +186,7 @@ gail_window_class_init (GailWindowClass
g_signal_new ("restore",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- NULL, /* default signal handler */
+ 0, /* default signal handler */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -239,6 +240,8 @@ gail_window_real_initialize (AtkObject *
"window_state_event",
G_CALLBACK (gail_window_state_event_gtk),
NULL);
+
+ obj->layer = ATK_LAYER_WINDOW;
}
static G_CONST_RETURN gchar*
@@ -407,6 +410,7 @@ atk_component_interface_init (AtkCompone
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
@@ -488,3 +492,243 @@ gail_window_get_size (AtkComponent *comp
*height = rect.height;
}
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+
+/* _NET_CLIENT_LIST_STACKING monitoring */
+
+typedef struct {
+ Window *stacked_windows;
+ int stacked_windows_len;
+ GdkWindow *root_window;
+ guint update_handler;
+
+ 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 gboolean
+get_stacked_windows (GailScreenInfo *info)
+{
+ Atom ret_type;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ Window *data;
+ int error;
+ int result;
+
+ if (_net_client_list_stacking == None)
+ _net_client_list_stacking =
+ XInternAtom (gdk_display, "_NET_CLIENT_LIST_STACKING", False);
+
+ if (info->stacked_windows)
+ XFree (info->stacked_windows);
+
+ info->stacked_windows = NULL;
+ info->stacked_windows_len = 0;
+
+ gdk_error_trap_push ();
+ ret_type = None;
+ result = XGetWindowProperty (gdk_display,
+ GDK_WINDOW_XWINDOW (info->root_window),
+ _net_client_list_stacking,
+ 0, G_MAXLONG,
+ False, XA_WINDOW, &ret_type, &format, &nitems,
+ &bytes_after, (guchar **)&data);
+ error = gdk_error_trap_pop ();
+ if (error != Success || result != Success)
+ return FALSE;
+
+ if (ret_type != XA_WINDOW)
+ {
+ XFree (data);
+ return FALSE;
+ }
+
+ info->stacked_windows = data;
+ info->stacked_windows_len = nitems;
+
+ 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 GdkFilterReturn
+root_window_event_filter (GdkXEvent *gdkxevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = gdkxevent;
+ int screen_n;
+
+ if (xevent->type != PropertyNotify ||
+ xevent->xproperty.atom != _net_client_list_stacking)
+ return GDK_FILTER_CONTINUE;
+
+ screen_n = gdk_screen_get_number (
+ gdk_drawable_get_screen (GDK_DRAWABLE (event->any.window)));
+
+ gail_screens [screen_n].update_stacked_windows = TRUE;
+ if (!gail_screens [screen_n].update_handler)
+ {
+ gail_screens [screen_n].update_handler = g_idle_add (update_screen_info,
+ GINT_TO_POINTER (screen_n));
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+display_closed (GdkDisplay *display,
+ gboolean is_error)
+{
+ int i;
+
+ for (i = 0; i < num_screens; i++)
+ {
+ gdk_window_remove_filter (gail_screens [i].root_window,
+ root_window_event_filter, NULL);
+
+ if (gail_screens [i].update_handler)
+ {
+ g_source_remove (gail_screens [i].update_handler);
+ gail_screens [i].update_handler = 0;
+ }
+
+ if (gail_screens [i].stacked_windows)
+ {
+ XFree (gail_screens [i].stacked_windows);
+ gail_screens [i].stacked_windows = NULL;
+ gail_screens [i].stacked_windows_len = 0;
+ }
+ }
+
+ 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);
+
+ 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]);
+
+ /* Probably not neccessary */
+ XGetWindowAttributes (gdk_display,
+ GDK_WINDOW_XWINDOW (gail_screens [screen_n].root_window),
+ &attrs);
+
+ XSelectInput (gdk_display,
+ GDK_WINDOW_XWINDOW (gail_screens [screen_n].root_window),
+ attrs.your_event_mask | PropertyChangeMask);
+
+ gdk_window_add_filter (gail_screens [screen_n].root_window,
+ root_window_event_filter, NULL);
+
+ gail_screens [screen_n].screen_initialized = TRUE;
+}
+
+static GailScreenInfo *
+get_screen_info (GdkScreen *screen)
+{
+ int screen_n;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ 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;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), -1);
+
+ info = get_screen_info (
+ gdk_drawable_get_screen (GDK_DRAWABLE (window)));
+
+ g_return_val_if_fail (info->stacked_windows != NULL, -1);
+
+ xid = GDK_WINDOW_XID (window);
+
+ for (i = 0; i < info->stacked_windows_len; i++)
+ {
+ g_print ("%d: Comparing %ld %ld\n", i, info->stacked_windows [i], xid);
+ if (info->stacked_windows [i] == xid)
+ {
+ g_print ("%d: Matched %ld %ld\n", i, info->stacked_windows [i], xid);
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static gint
+gail_window_get_mdi_zorder (AtkComponent *component)
+{
+ GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
+
+ return get_window_zorder (widget->window);
+}
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/atk/ChangeLog,v
retrieving revision 1.205
diff -u -p -r1.205 ChangeLog
--- ChangeLog 5 Sep 2002 13:51:08 -0000 1.205
+++ ChangeLog 6 Sep 2002 05:44:53 -0000
@@ -1,3 +1,9 @@
+2002-09-06 Mark McLoughlin <mark skynet ie>
+
+ * atk/atkobject.h: add ATK_LAYER_WINDOW.
+
+ * atk/atkcomponent.c: upd docs.
+
2002-09-05 Padraig O'Briain <padraig obriain sun com>
* docs/atk-sections.txt docs/tmpl/atkaction.sgml
Index: atk/atkcomponent.c
===================================================================
RCS file: /cvs/gnome/atk/atk/atkcomponent.c,v
retrieving revision 1.19
diff -u -p -r1.19 atkcomponent.c
--- atk/atkcomponent.c 15 Feb 2002 11:26:25 -0000 1.19
+++ atk/atkcomponent.c 6 Sep 2002 05:44:54 -0000
@@ -344,7 +344,7 @@ atk_component_get_layer (AtkComponent *c
* @component: an #AtkComponent
*
* Gets the zorder of the component. The value G_MININT will be returned
- * if the layer of the component is not ATK_LAYER_MDI.
+ * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
*
* Returns: a gint which is the zorder of the component, i.e. the depth at
* which the component is shown in relation to other components in the same
Index: atk/atkobject.h
===================================================================
RCS file: /cvs/gnome/atk/atk/atkobject.h,v
retrieving revision 1.31
diff -u -p -r1.31 atkobject.h
--- atk/atkobject.h 13 Feb 2002 14:15:05 -0000 1.31
+++ atk/atkobject.h 6 Sep 2002 05:44:55 -0000
@@ -197,6 +197,7 @@ AtkRole atk_role_regist
* ATK_LAYER_MDI: This layer is used for layered components
* ATK_LAYER_POPUP: This layer is used for popup components, such as menus
* ATK_LAYER_OVERLAY: This layer is reserved for future use.
+ * ATK_LAYER_WINDOW: This layer is used for toplevel windows.
*
* Describes the layer of a component
**/
@@ -208,7 +209,8 @@ typedef enum
ATK_LAYER_WIDGET,
ATK_LAYER_MDI,
ATK_LAYER_POPUP,
- ATK_LAYER_OVERLAY
+ ATK_LAYER_OVERLAY,
+ ATK_LAYER_WINDOW
} AtkLayer;
#define ATK_TYPE_OBJECT (atk_object_get_type ())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]