Merge lp:~rodrigo-moya/unity/add-panel-service-a11y into lp:unity

Proposed by Rodrigo Moya
Status: Merged
Approved by: Rodrigo Moya
Approved revision: no longer in the source branch.
Merged at revision: 812
Proposed branch: lp:~rodrigo-moya/unity/add-panel-service-a11y
Merge into: lp:unity
Diff against target: 718 lines (+633/-3)
10 files modified
services/CMakeLists.txt (+9/-1)
services/panel-a11y.c (+150/-0)
services/panel-a11y.h (+30/-0)
services/panel-indicator-accessible.c (+98/-0)
services/panel-indicator-accessible.h (+53/-0)
services/panel-main.c (+9/-2)
services/panel-root-accessible.c (+123/-0)
services/panel-root-accessible.h (+51/-0)
services/panel-util-accessible.c (+59/-0)
services/panel-util-accessible.h (+51/-0)
To merge this branch: bzr merge lp:~rodrigo-moya/unity/add-panel-service-a11y
Reviewer Review Type Date Requested Status
Alex Launi (community) Approve
Alejandro Piñeiro (community) Approve
Review via email: mp+47840@code.launchpad.net

Description of the change

Add Util, Root and (beginning of) Indicators A11Y to panel service

To post a comment you must log in.
Revision history for this message
Alejandro Piñeiro (apinheiro) wrote :

154 + if (!a11y_initialized)
155 + {

I think that it is worth to check the opposite, return if a11y_initialized. That would avoid a indentation level (IMHO, code would be clearer).

164 + /* Restore environment to load AT bridge */
165 + g_unsetenv ("NO_AT_BRIDGE");
166 + g_unsetenv ("NO_GAIL");

Take into account that there are one case (!should_enable_a11y) where you don't restore the environment, *but*, you modify the environment alway. Sorry, I was the one that suggested to move that to just before the load bridge, but probably this should be done as the first thing, to ensure that you always restore the environment (although this would only be a problem if there are a process child of this service, unlikely).

299 + atk_object_set_name (accessible, _("An indicator")); /* FIXME */

Do you really thing that worths to add this temporal names. Are useful for testing during development, but not sure if it is worth on have that on the actual code. If in the end you remove it, you will not require this include:
240 +#include <glib/gi18n.h>

294 +static void
295 +panel_indicator_accessible_initialize (AtkObject *accessible, gpointer data)
296 +{
297 + g_return_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible));
298 +
299 + atk_object_set_name (accessible, _("An indicator")); /* FIXME */
300 + atk_object_set_role (accessible, ATK_ROLE_LABEL);
301 +
302 + ATK_OBJECT_CLASS (panel_indicator_accessible_parent_class)->initialize (accessible, data);

Although cally-root also calls the parent class initialize as the last thing, by default this should be done as the first thing of the initialize. Ie: imagine that the parent class also set a role, in that case that ATK_ROLE_LABEL would be unused.

508 + accessible->role = ATK_ROLE_APPLICATION;
509 + atk_object_set_name (accessible, _("Unity Panel Service"));

As the root represents the application I think that you should use the application name. Here you can use g_get_prgname(), like in gail or cally. I couldn't use that on Unity because I didn't found a equivalent to g_get_prgname to be used there (anyway, this is FIXME).

Some extra comments:

  * The indentation is somewhat weird. It seems that in some cases you have spaces and in other you have tabs, ie:
475 + atk_class->initialize = panel_root_accessible_initialize;
476 + atk_class->get_n_children = panel_root_accessible_get_n_children;
477 + atk_class->ref_child = panel_root_accessible_ref_child;
478 + atk_class->get_parent = panel_root_accessible_get_parent;

  * The way we reuse gail here is allow gtk_init to load gail but not the bridge, and then load the bridge. I don't like too much this mixed approach, as it could be prone-error (what would happen if for any reason gtk_init doesn't load the accessibility but panel-service yes, or the opposite). Taking into account the current wisdom (firefox and so on), probably we should do all the work. That means setting both NO_GAIL and NO_AT_BRIDGE, and then load by hand both gail and the bridge. But this could be done in a posterior task, but take that into account if you want to do that while solving the other issues.

review: Needs Fixing
Revision history for this message
Alejandro Piñeiro (apinheiro) wrote :

BTW, as this also touch panel-main.c code, probably you would require to add someone else to review the code.

Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :
Download full text (3.7 KiB)

> 154 + if (!a11y_initialized)
> 155 + {
>
> I think that it is worth to check the opposite, return if a11y_initialized.
> That would avoid a indentation level (IMHO, code would be clearer).
>
fixed

> 164 + /* Restore environment to load AT bridge */
> 165 + g_unsetenv ("NO_AT_BRIDGE");
> 166 + g_unsetenv ("NO_GAIL");
>
> Take into account that there are one case (!should_enable_a11y) where you
> don't restore the environment, *but*, you modify the environment alway. Sorry,
> I was the one that suggested to move that to just before the load bridge, but
> probably this should be done as the first thing, to ensure that you always
> restore the environment (although this would only be a problem if there are a
> process child of this service, unlikely).
>
done

>
> 299 + atk_object_set_name (accessible, _("An indicator")); /* FIXME */
>
> Do you really thing that worths to add this temporal names. Are useful for
> testing during development, but not sure if it is worth on have that on the
> actual code. If in the end you remove it, you will not require this include:
> 240 +#include <glib/gi18n.h>
>
in the next branch I will remove that temporary code, with real code to return the indicators. So just added this so that it shows something in accerciser.

>
> 294 +static void
> 295 +panel_indicator_accessible_initialize (AtkObject *accessible,
> gpointer data)
> 296 +{
> 297 + g_return_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible));
> 298 +
> 299 + atk_object_set_name (accessible, _("An indicator")); /* FIXME */
> 300 + atk_object_set_role (accessible, ATK_ROLE_LABEL);
> 301 +
> 302 + ATK_OBJECT_CLASS
> (panel_indicator_accessible_parent_class)->initialize (accessible, data);
>
> Although cally-root also calls the parent class initialize as the last thing,
> by default this should be done as the first thing of the initialize. Ie:
> imagine that the parent class also set a role, in that case that
> ATK_ROLE_LABEL would be unused.
>
right, fixed

>
> 508 + accessible->role = ATK_ROLE_APPLICATION;
> 509 + atk_object_set_name (accessible, _("Unity Panel Service"));
>
> As the root represents the application I think that you should use the
> application name. Here you can use g_get_prgname(), like in gail or cally. I
> couldn't use that on Unity because I didn't found a equivalent to
> g_get_prgname to be used there (anyway, this is FIXME).
>
ok, fixed

> Some extra comments:
>
> * The indentation is somewhat weird. It seems that in some cases you have
> spaces and in other you have tabs, ie:
> 475 + atk_class->initialize = panel_root_accessible_initialize;
> 476 + atk_class->get_n_children = panel_root_accessible_get_n_children;
> 477 + atk_class->ref_child = panel_root_accessible_ref_child;
> 478 + atk_class->get_parent = panel_root_accessible_get_parent;
>
yes, seems I got the format header wrong, so I've removed it from all the files and fixed (hopefully) all TABs

>
> * The way we reuse gail here is allow gtk_init to load gail but not the
> bridge, and then load the bridge. I don't like too much this mixed approach,
> as it could be pron...

Read more...

Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

> BTW, as this also touch panel-main.c code, probably you would require to add
> someone else to review the code.

yes, as soon as you approve all the A11Y part, I'll ask for a 2nd approval, so yeah, any other unity developer can have a look at this branch, please?

Revision history for this message
Alejandro Piñeiro (apinheiro) wrote :

> > * The way we reuse gail here is allow gtk_init to load gail but not the
> > bridge, and then load the bridge. I don't like too much this mixed approach,
> > as it could be prone-error (what would happen if for any reason gtk_init
> > doesn't load the accessibility but panel-service yes, or the opposite).
> Taking
> > into account the current wisdom (firefox and so on), probably we should do
> all
> > the work. That means setting both NO_GAIL and NO_AT_BRIDGE, and then load by
> > hand both gail and the bridge. But this could be done in a posterior task,
> but
> > take that into account if you want to do that while solving the other
> issues.
> >
> ok, file a bug for that and assign it to me and I'll work on that on another
> branch

Ok, I will do that.

And as you changed the rest of the things, and I have just tested it, it seems ok for me.

Just a nitpick:

390 +#include <string.h>

Why do you require this new include?

review: Approve
Revision history for this message
Alejandro Piñeiro (apinheiro) wrote :

> > BTW, as this also touch panel-main.c code, probably you would require to add
> > someone else to review the code.
>
> yes, as soon as you approve all the A11Y part, I'll ask for a 2nd approval, so
> yeah, any other unity developer can have a look at this branch, please?

Alex Launi were reviewing my branches, although these days Loïc Molinari was also helping me with this kind of things.

You could try to ask them, or just ask David.

Revision history for this message
Alex Launi (alexlauni) wrote :

This looks pretty good to me.
But same question as Alejandro, why the added #include <string.h>. It doesn't look you add anything that uses string.h.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'services/CMakeLists.txt'
2--- services/CMakeLists.txt 2010-11-29 12:02:39 +0000
3+++ services/CMakeLists.txt 2011-01-31 21:55:43 +0000
4@@ -24,9 +24,17 @@
5 link_directories(${LIB_PATHS})
6
7 add_executable(unity-panel-service
8+ panel-a11y.c
9+ panel-a11y.h
10+ panel-indicator-accessible.c
11+ panel-indicator-accessible.h
12 panel-main.c
13+ panel-root-accessible.c
14+ panel-root-accessible.h
15 panel-service.c
16- panel-service.h
17+ panel-service.h
18+ panel-util-accessible.c
19+ panel-util-accessible.h
20 )
21 install(TARGETS unity-panel-service DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/)
22
23
24=== added file 'services/panel-a11y.c'
25--- services/panel-a11y.c 1970-01-01 00:00:00 +0000
26+++ services/panel-a11y.c 2011-01-31 21:55:43 +0000
27@@ -0,0 +1,150 @@
28+/*
29+ * Copyright (C) 2011 Canonical Ltd
30+ *
31+ * This program is free software: you can redistribute it and/or modify
32+ * it under the terms of the GNU General Public License version 3 as
33+ * published by the Free Software Foundation.
34+ *
35+ * This program is distributed in the hope that it will be useful,
36+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+ * GNU General Public License for more details.
39+ *
40+ * You should have received a copy of the GNU General Public License
41+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
42+ *
43+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
44+ */
45+
46+#include <gio/gio.h>
47+#include "panel-a11y.h"
48+#include "panel-util-accessible.h"
49+
50+static gboolean a11y_initialized = FALSE;
51+
52+#define INIT_METHOD "gnome_accessibility_module_init"
53+#define DESKTOP_SCHEMA "org.gnome.desktop.interface"
54+#define ACCESSIBILITY_ENABLED_KEY "accessibility"
55+#define AT_SPI_SCHEMA "org.a11y.atspi"
56+#define ATK_BRIDGE_LOCATION_KEY "atk-bridge-location"
57+
58+static gboolean
59+has_gsettings_schema (const gchar *schema)
60+{
61+ const char * const *list_schemas = NULL;
62+ gboolean found = FALSE;
63+ int i = 0;
64+
65+ /* we need to check if AT_SPI_SCHEMA is present as g_settings_new
66+ could abort if the schema is not here*/
67+ list_schemas = g_settings_list_schemas ();
68+ for (i = 0; list_schemas [i]; i++)
69+ {
70+ if (!g_strcmp0 (list_schemas[i], schema))
71+ {
72+ found = TRUE;
73+ break;
74+ }
75+ }
76+
77+ return found;
78+}
79+
80+static gboolean
81+should_enable_a11y (void)
82+{
83+ GSettings *desktop_settings = NULL;
84+ gboolean value = FALSE;
85+
86+ if (!has_gsettings_schema (DESKTOP_SCHEMA))
87+ return FALSE;
88+
89+ desktop_settings = g_settings_new (DESKTOP_SCHEMA);
90+ value = g_settings_get_boolean (desktop_settings, ACCESSIBILITY_ENABLED_KEY);
91+
92+ g_object_unref (desktop_settings);
93+
94+ return value;
95+}
96+
97+static gchar*
98+get_atk_bridge_path (void)
99+{
100+ GSettings *atspi_settings = NULL;
101+ char *value = NULL;
102+
103+ if (!has_gsettings_schema (AT_SPI_SCHEMA))
104+ return NULL;
105+
106+ atspi_settings = g_settings_new (AT_SPI_SCHEMA);
107+ value = g_settings_get_string (atspi_settings, ATK_BRIDGE_LOCATION_KEY);
108+
109+ g_object_unref (atspi_settings);
110+
111+ return value;
112+}
113+
114+static gboolean
115+a11y_invoke_module (const char *module_path)
116+{
117+ GModule *handle;
118+ void (*invoke_fn) (void);
119+
120+ if (!module_path)
121+ {
122+ g_warning ("Accessibility: invalid module path (NULL)");
123+
124+ return FALSE;
125+ }
126+
127+ if (!(handle = g_module_open (module_path, (GModuleFlags)0)))
128+ {
129+ g_warning ("Accessibility: failed to load module '%s': '%s'",
130+ module_path, g_module_error ());
131+
132+ return FALSE;
133+ }
134+
135+ if (!g_module_symbol (handle, INIT_METHOD, (gpointer *)&invoke_fn))
136+ {
137+ g_warning ("Accessibility: error library '%s' does not include "
138+ "method '%s' required for accessibility support",
139+ module_path, INIT_METHOD);
140+ g_module_close (handle);
141+
142+ return FALSE;
143+ }
144+
145+ invoke_fn ();
146+
147+ return TRUE;
148+}
149+
150+void
151+panel_a11y_init (void)
152+{
153+ gchar *bridge_path = NULL;
154+
155+ if (a11y_initialized)
156+ return;
157+
158+ /* Restore environment to load AT bridge */
159+ g_unsetenv ("NO_AT_BRIDGE");
160+ g_unsetenv ("NO_GAIL");
161+
162+ if (!should_enable_a11y ())
163+ return;
164+
165+ /* Load PanelUtilAccessible class */
166+ g_type_class_unref (g_type_class_ref (PANEL_TYPE_UTIL_ACCESSIBLE));
167+
168+ bridge_path = get_atk_bridge_path ();
169+ if (a11y_invoke_module (bridge_path))
170+ {
171+ g_debug ("Unity accessibility started, using bridge on %s", bridge_path);
172+ }
173+
174+ g_free (bridge_path);
175+
176+ a11y_initialized = TRUE;
177+}
178
179=== added file 'services/panel-a11y.h'
180--- services/panel-a11y.h 1970-01-01 00:00:00 +0000
181+++ services/panel-a11y.h 2011-01-31 21:55:43 +0000
182@@ -0,0 +1,30 @@
183+/*
184+ * Copyright (C) 2011 Canonical Ltd
185+ *
186+ * This program is free software: you can redistribute it and/or modify
187+ * it under the terms of the GNU General Public License version 3 as
188+ * published by the Free Software Foundation.
189+ *
190+ * This program is distributed in the hope that it will be useful,
191+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
192+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
193+ * GNU General Public License for more details.
194+ *
195+ * You should have received a copy of the GNU General Public License
196+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
197+ *
198+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
199+ */
200+
201+#ifndef _PANEL_A11Y_H_
202+#define _PANEL_A11Y_H_
203+
204+#include <glib-object.h>
205+
206+G_BEGIN_DECLS
207+
208+void panel_a11y_init (void);
209+
210+G_END_DECLS
211+
212+#endif
213
214=== added file 'services/panel-indicator-accessible.c'
215--- services/panel-indicator-accessible.c 1970-01-01 00:00:00 +0000
216+++ services/panel-indicator-accessible.c 2011-01-31 21:55:43 +0000
217@@ -0,0 +1,98 @@
218+/*
219+ * Copyright (C) 2011 Canonical Ltd
220+ *
221+ * This program is free software: you can redistribute it and/or modify
222+ * it under the terms of the GNU General Public License version 3 as
223+ * published by the Free Software Foundation.
224+ *
225+ * This program is distributed in the hope that it will be useful,
226+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
227+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
228+ * GNU General Public License for more details.
229+ *
230+ * You should have received a copy of the GNU General Public License
231+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
232+ *
233+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
234+ */
235+
236+#include <glib/gi18n.h>
237+#include "panel-indicator-accessible.h"
238+
239+G_DEFINE_TYPE(PanelIndicatorAccessible, panel_indicator_accessible, ATK_TYPE_OBJECT)
240+
241+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_INDICATOR_ACCESSIBLE, PanelIndicatorAccessiblePrivate))
242+
243+/* AtkObject methods */
244+static void panel_indicator_accessible_initialize (AtkObject *accessible, gpointer data);
245+static gint panel_indicator_accessible_get_n_children (AtkObject *accessible);
246+static AtkObject *panel_indicator_accessible_ref_child (AtkObject *accessible, gint i);
247+
248+struct _PanelIndicatorAccessiblePrivate
249+{
250+};
251+
252+static void
253+panel_indicator_accessible_class_init (PanelIndicatorAccessibleClass *klass)
254+{
255+ GObjectClass *object_class;
256+ AtkObjectClass *atk_class;
257+
258+ /* GObject */
259+ object_class = G_OBJECT_CLASS (klass);
260+
261+ /* AtkObject */
262+ atk_class = ATK_OBJECT_CLASS (klass);
263+ atk_class->initialize = panel_indicator_accessible_initialize;
264+ atk_class->get_n_children = panel_indicator_accessible_get_n_children;
265+ atk_class->ref_child = panel_indicator_accessible_ref_child;
266+
267+ g_type_class_add_private (object_class, sizeof (PanelIndicatorAccessiblePrivate));
268+}
269+
270+static void
271+panel_indicator_accessible_init (PanelIndicatorAccessible *pia)
272+{
273+ pia->priv = GET_PRIVATE (pia);
274+}
275+
276+AtkObject *
277+panel_indicator_accessible_new (void)
278+{
279+ AtkObject *accessible;
280+
281+ accessible = ATK_OBJECT (g_object_new (PANEL_TYPE_INDICATOR_ACCESSIBLE, NULL));
282+
283+ atk_object_initialize (accessible, NULL);
284+
285+ return accessible;
286+}
287+
288+/* Implementation of AtkObject methods */
289+
290+static void
291+panel_indicator_accessible_initialize (AtkObject *accessible, gpointer data)
292+{
293+ g_return_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible));
294+
295+ ATK_OBJECT_CLASS (panel_indicator_accessible_parent_class)->initialize (accessible, data);
296+
297+ atk_object_set_name (accessible, _("An indicator")); /* FIXME */
298+ atk_object_set_role (accessible, ATK_ROLE_LABEL);
299+}
300+
301+static gint
302+panel_indicator_accessible_get_n_children (AtkObject *accessible)
303+{
304+ g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible), 0);
305+
306+ return 0;
307+}
308+
309+static AtkObject *
310+panel_indicator_accessible_ref_child (AtkObject *accessible, gint i)
311+{
312+ g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible), NULL);
313+
314+ return NULL;
315+}
316
317=== added file 'services/panel-indicator-accessible.h'
318--- services/panel-indicator-accessible.h 1970-01-01 00:00:00 +0000
319+++ services/panel-indicator-accessible.h 2011-01-31 21:55:43 +0000
320@@ -0,0 +1,53 @@
321+/*
322+ * Copyright (C) 2011 Canonical Ltd
323+ *
324+ * This program is free software: you can redistribute it and/or modify
325+ * it under the terms of the GNU General Public License version 3 as
326+ * published by the Free Software Foundation.
327+ *
328+ * This program is distributed in the hope that it will be useful,
329+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
330+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
331+ * GNU General Public License for more details.
332+ *
333+ * You should have received a copy of the GNU General Public License
334+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
335+ *
336+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
337+ */
338+
339+#ifndef _PANEL_INDICATOR_ACCESSIBLE_H_
340+#define _PANEL_INDICATOR_ACCESSIBLE_H_
341+
342+#include <atk/atk.h>
343+
344+G_BEGIN_DECLS
345+
346+#define PANEL_TYPE_INDICATOR_ACCESSIBLE (panel_indicator_accessible_get_type ())
347+#define PANEL_INDICATOR_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_INDICATOR_ACCESSIBLE, PanelIndicatorAccessible))
348+#define PANEL_INDICATOR_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_INDICATOR_ACCESSIBLE, PanelIndicatorAccessibleClass))
349+#define PANEL_IS_INDICATOR_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_INDICATOR_ACCESSIBLE))
350+#define PANEL_IS_INDICATOR_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_INDICATOR_ACCESSIBLE))
351+#define PANEL_INDICATOR_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_INDICATOR_ACCESSIBLE, PanelIndicatorAccessibleClass))
352+
353+typedef struct _PanelIndicatorAccessible PanelIndicatorAccessible;
354+typedef struct _PanelIndicatorAccessibleClass PanelIndicatorAccessibleClass;
355+typedef struct _PanelIndicatorAccessiblePrivate PanelIndicatorAccessiblePrivate;
356+
357+struct _PanelIndicatorAccessible
358+{
359+ AtkObject parent;
360+ PanelIndicatorAccessiblePrivate *priv;
361+};
362+
363+struct _PanelIndicatorAccessibleClass
364+{
365+ AtkObjectClass parent_class;
366+};
367+
368+GType panel_indicator_accessible_get_type (void);
369+AtkObject *panel_indicator_accessible_new (void);
370+
371+G_END_DECLS
372+
373+#endif
374
375=== modified file 'services/panel-main.c'
376--- services/panel-main.c 2011-01-11 15:48:03 +0000
377+++ services/panel-main.c 2011-01-31 21:55:43 +0000
378@@ -1,3 +1,4 @@
379+// -*- Mode: C; tab-width:2; indent-tabs-mode: t; c-basic-offset: 2 -*-
380 /*
381 * Copyright (C) 2010 Canonical Ltd
382 *
383@@ -14,12 +15,14 @@
384 * along with this program. If not, see <http://www.gnu.org/licenses/>.
385 *
386 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
387+ * Rodrigo Moya <rodrigo.moya@canonical.com>
388 */
389
390 #include <glib.h>
391 #include <gio/gio.h>
392 #include <gtk/gtk.h>
393
394+#include "panel-a11y.h"
395 #include "panel-service.h"
396
397 static GDBusNodeInfo *introspection_data = NULL;
398@@ -299,10 +302,14 @@
399 guint owner_id;
400
401 g_unsetenv("UBUNTU_MENUPROXY");
402+ g_setenv ("NO_AT_BRIDGE", "1", TRUE);
403+ g_unsetenv ("NO_GAIL");
404
405 gtk_init (&argc, &argv);
406- gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(),
407- INDICATORICONDIR);
408+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(),
409+ INDICATORICONDIR);
410+
411+ panel_a11y_init ();
412
413 introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
414 g_assert (introspection_data != NULL);
415
416=== added file 'services/panel-root-accessible.c'
417--- services/panel-root-accessible.c 1970-01-01 00:00:00 +0000
418+++ services/panel-root-accessible.c 2011-01-31 21:55:43 +0000
419@@ -0,0 +1,123 @@
420+/*
421+ * Copyright (C) 2011 Canonical Ltd
422+ *
423+ * This program is free software: you can redistribute it and/or modify
424+ * it under the terms of the GNU General Public License version 3 as
425+ * published by the Free Software Foundation.
426+ *
427+ * This program is distributed in the hope that it will be useful,
428+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
429+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
430+ * GNU General Public License for more details.
431+ *
432+ * You should have received a copy of the GNU General Public License
433+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
434+ *
435+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
436+ */
437+
438+#include <glib/gi18n.h>
439+#include "panel-indicator-accessible.h"
440+#include "panel-root-accessible.h"
441+#include "panel-service.h"
442+
443+G_DEFINE_TYPE(PanelRootAccessible, panel_root_accessible, ATK_TYPE_OBJECT)
444+
445+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_ROOT_ACCESSIBLE, PanelRootAccessiblePrivate))
446+
447+/* AtkObject methods */
448+static void panel_root_accessible_initialize (AtkObject *accessible, gpointer data);
449+static gint panel_root_accessible_get_n_children (AtkObject *accessible);
450+static AtkObject *panel_root_accessible_ref_child (AtkObject *accessible, gint i);
451+static AtkObject *panel_root_accessible_get_parent (AtkObject *accessible);
452+
453+struct _PanelRootAccessiblePrivate
454+{
455+};
456+
457+static void
458+panel_root_accessible_class_init (PanelRootAccessibleClass *klass)
459+{
460+ GObjectClass *object_class;
461+ AtkObjectClass *atk_class;
462+
463+ /* GObject */
464+ object_class = G_OBJECT_CLASS (klass);
465+
466+ /* AtkObject */
467+ atk_class = ATK_OBJECT_CLASS (klass);
468+ atk_class->initialize = panel_root_accessible_initialize;
469+ atk_class->get_n_children = panel_root_accessible_get_n_children;
470+ atk_class->ref_child = panel_root_accessible_ref_child;
471+ atk_class->get_parent = panel_root_accessible_get_parent;
472+
473+ g_type_class_add_private (object_class, sizeof (PanelRootAccessiblePrivate));
474+}
475+
476+static void
477+panel_root_accessible_init (PanelRootAccessible *root)
478+{
479+ root->priv = GET_PRIVATE (root);
480+}
481+
482+AtkObject *
483+panel_root_accessible_new (void)
484+{
485+ AtkObject *accessible;
486+
487+ accessible = ATK_OBJECT (g_object_new (PANEL_TYPE_ROOT_ACCESSIBLE, NULL));
488+ atk_object_initialize (accessible, NULL);
489+
490+ return accessible;
491+}
492+
493+/* Implementation of AtkObject methods */
494+
495+static void
496+panel_root_accessible_initialize (AtkObject *accessible, gpointer data)
497+{
498+ g_return_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible));
499+
500+ ATK_OBJECT_CLASS (panel_root_accessible_parent_class)->initialize (accessible, data);
501+
502+ accessible->role = ATK_ROLE_APPLICATION;
503+ atk_object_set_name (accessible, g_get_prgname ());
504+ atk_object_set_parent (accessible, NULL);
505+}
506+
507+static gint
508+panel_root_accessible_get_n_children (AtkObject *accessible)
509+{
510+ guint n_children;
511+
512+ g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), 0);
513+
514+ n_children = panel_service_get_n_indicators (panel_service_get_default ());
515+
516+ g_debug ("PanelRootAccessible has %d children", n_children);
517+
518+ return n_children;
519+}
520+
521+static AtkObject *
522+panel_root_accessible_ref_child (AtkObject *accessible, gint i)
523+{
524+ AtkObject *child;
525+
526+ g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL);
527+
528+ child = panel_indicator_accessible_new (); /* FIXME */
529+ atk_object_set_parent (child, accessible);
530+
531+ g_debug ("Returning ATK child %p", child);
532+
533+ return child;
534+}
535+
536+static AtkObject *
537+panel_root_accessible_get_parent (AtkObject *accessible)
538+{
539+ g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL);
540+
541+ return NULL;
542+}
543
544=== added file 'services/panel-root-accessible.h'
545--- services/panel-root-accessible.h 1970-01-01 00:00:00 +0000
546+++ services/panel-root-accessible.h 2011-01-31 21:55:43 +0000
547@@ -0,0 +1,51 @@
548+/*
549+ * Copyright (C) 2011 Canonical Ltd
550+ *
551+ * This program is free software: you can redistribute it and/or modify
552+ * it under the terms of the GNU General Public License version 3 as
553+ * published by the Free Software Foundation.
554+ *
555+ * This program is distributed in the hope that it will be useful,
556+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
557+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
558+ * GNU General Public License for more details.
559+ *
560+ * You should have received a copy of the GNU General Public License
561+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
562+ *
563+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
564+ */
565+
566+#ifndef _PANEL_ROOT_ACCESSIBLE_H_
567+#define _PANEL_ROOT_ACCESSIBLE_H_
568+
569+#include <atk/atk.h>
570+
571+G_BEGIN_DECLS
572+
573+#define PANEL_TYPE_ROOT_ACCESSIBLE (panel_root_accessible_get_type ())
574+#define PANEL_ROOT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_ROOT_ACCESSIBLE, PanelRootAccessible))
575+#define PANEL_ROOT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_ROOT_ACCESSIBLE, PanelRootAccessibleClass))
576+#define PANEL_IS_ROOT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_ROOT_ACCESSIBLE))
577+#define PANEL_IS_ROOT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_ROOT_ACCESSIBLE))
578+#define PANEL_ROOT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_ROOT_ACCESSIBLE, PanelRootAccessibleClass))
579+
580+typedef struct _PanelRootAccessible PanelRootAccessible;
581+typedef struct _PanelRootAccessibleClass PanelRootAccessibleClass;
582+typedef struct _PanelRootAccessiblePrivate PanelRootAccessiblePrivate;
583+
584+struct _PanelRootAccessible
585+{
586+ AtkObject parent;
587+ PanelRootAccessiblePrivate *priv;
588+};
589+
590+struct _PanelRootAccessibleClass
591+{
592+ AtkObjectClass parent_class;
593+};
594+
595+GType panel_root_accessible_get_type (void);
596+AtkObject *panel_root_accessible_new (void);
597+
598+#endif
599
600=== added file 'services/panel-util-accessible.c'
601--- services/panel-util-accessible.c 1970-01-01 00:00:00 +0000
602+++ services/panel-util-accessible.c 2011-01-31 21:55:43 +0000
603@@ -0,0 +1,59 @@
604+/*
605+ * Copyright (C) 2011 Canonical Ltd
606+ *
607+ * This program is free software: you can redistribute it and/or modify
608+ * it under the terms of the GNU General Public License version 3 as
609+ * published by the Free Software Foundation.
610+ *
611+ * This program is distributed in the hope that it will be useful,
612+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
613+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
614+ * GNU General Public License for more details.
615+ *
616+ * You should have received a copy of the GNU General Public License
617+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
618+ *
619+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
620+ */
621+
622+#include "panel-root-accessible.h"
623+#include "panel-util-accessible.h"
624+
625+G_DEFINE_TYPE(PanelUtilAccessible, panel_util_accessible, ATK_TYPE_UTIL)
626+
627+/* AtkUtil methods */
628+static AtkObject *panel_util_accessible_get_root (void);
629+
630+static AtkObject *root = NULL;
631+
632+/* GObject methods implementation */
633+
634+static void
635+panel_util_accessible_class_init (PanelUtilAccessibleClass *klass)
636+{
637+ AtkUtilClass *atk_class;
638+
639+ g_debug ("Initializing PanelUtilAccessible class");
640+
641+ /* AtkUtil */
642+ atk_class = g_type_class_peek (ATK_TYPE_UTIL);
643+ atk_class->get_root = panel_util_accessible_get_root;
644+}
645+
646+static void
647+panel_util_accessible_init (PanelUtilAccessible *panel_util)
648+{
649+}
650+
651+/* AtkUtil methods implementation */
652+
653+static AtkObject *
654+panel_util_accessible_get_root (void)
655+{
656+ if (!root)
657+ root = panel_root_accessible_new ();
658+
659+ g_debug ("Returning root A11Y object at %p", root);
660+
661+ return root;
662+}
663
664=== added file 'services/panel-util-accessible.h'
665--- services/panel-util-accessible.h 1970-01-01 00:00:00 +0000
666+++ services/panel-util-accessible.h 2011-01-31 21:55:43 +0000
667@@ -0,0 +1,51 @@
668+/*
669+ * Copyright (C) 2011 Canonical Ltd
670+ *
671+ * This program is free software: you can redistribute it and/or modify
672+ * it under the terms of the GNU General Public License version 3 as
673+ * published by the Free Software Foundation.
674+ *
675+ * This program is distributed in the hope that it will be useful,
676+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
677+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
678+ * GNU General Public License for more details.
679+ *
680+ * You should have received a copy of the GNU General Public License
681+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
682+ *
683+ * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
684+ */
685+
686+#ifndef _PANEL_UTIL_ACCESSIBLE_H_
687+#define _PANEL_UTIL_ACCESSIBLE_H_
688+
689+#include <atk/atk.h>
690+
691+G_BEGIN_DECLS
692+
693+#define PANEL_TYPE_UTIL_ACCESSIBLE (panel_util_accessible_get_type ())
694+
695+#define PANEL_UTIL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_UTIL_ACCESSIBLE, PanelUtilAccessible))
696+#define PANEL_UTIL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_UTIL_ACCESSIBLE, PanelUtilAccessibleClass))
697+#define PANEL_IS_UTIL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_UTIL_ACCESSIBLE))
698+#define PANEL_IS_UTIL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_UTIL_ACCESSIBLE))
699+#define PANEL_UTIL_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_UTIL_ACCESSIBLE, PanelUtilAccessibleClass))
700+
701+typedef struct _PanelUtilAccessible PanelUtilAccessible;
702+typedef struct _PanelUtilAccessibleClass PanelUtilAccessibleClass;
703+
704+struct _PanelUtilAccessible
705+{
706+ AtkUtil parent;
707+};
708+
709+struct _PanelUtilAccessibleClass
710+{
711+ AtkUtilClass parent_class;
712+};
713+
714+GType panel_util_accessible_get_type (void);
715+
716+G_END_DECLS
717+
718+#endif