Merge lp:~themuso/unity/improve-shutdown-dialog-a11y into lp:unity

Proposed by Luke Yelavich
Status: Merged
Approved by: Stephen M. Webb
Approved revision: no longer in the source branch.
Merged at revision: 3698
Proposed branch: lp:~themuso/unity/improve-shutdown-dialog-a11y
Merge into: lp:unity
Diff against target: 381 lines (+324/-0)
4 files modified
plugins/unityshell/src/nux-layout-accessible.cpp (+5/-0)
plugins/unityshell/src/unity-session-button-accessible.cpp (+260/-0)
plugins/unityshell/src/unity-session-button-accessible.h (+53/-0)
plugins/unityshell/src/unitya11y.cpp (+6/-0)
To merge this branch: bzr merge lp:~themuso/unity/improve-shutdown-dialog-a11y
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+207089@code.launchpad.net

Commit message

Implement accessibility for the optino buttons in the shutdown dialog.

Also improve the parent-child relationship between objects such that the shutdown message can be read with Orca flat review.

Description of the change

Implement accessibility for the optino buttons in the shutdown dialog.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

412 + highlight_change.emit();

424 + sigc::signal<void> highlight_change;

You don't need that, I'm using a nux::Property for highlighted, and it already supports signaling.

Just connect to highlighted.changed signal ;)

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

376 + if (object->Type().IsDerivedFromType(Button::StaticObjectType))
377 + return unity_session_button_accessible_new(object);

It shuold work anyway, but I think it's better to use IsDerivedFromType(session::Button::StaticObjectType), to avoid future conflicts.

Anyway this looks good now, thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/nux-layout-accessible.cpp'
2--- plugins/unityshell/src/nux-layout-accessible.cpp 2012-08-15 14:05:18 +0000
3+++ plugins/unityshell/src/nux-layout-accessible.cpp 2014-02-25 01:48:00 +0000
4@@ -137,6 +137,7 @@
5 std::list<nux::Area*> element_list;
6 gint num = 0;
7 std::list<nux::Area*>::iterator it;
8+ AtkObject* parent = NULL;
9
10 g_return_val_if_fail(NUX_IS_LAYOUT_ACCESSIBLE(obj), 0);
11 num = atk_object_get_n_accessible_children(obj);
12@@ -156,6 +157,10 @@
13 child = dynamic_cast<nux::Object*>(*it);
14 child_accessible = unity_a11y_get_accessible(child);
15
16+ parent = atk_object_get_parent(child_accessible);
17+ if (parent != obj)
18+ atk_object_set_parent(child_accessible, obj);
19+
20 g_object_ref(child_accessible);
21
22 return child_accessible;
23
24=== added file 'plugins/unityshell/src/unity-session-button-accessible.cpp'
25--- plugins/unityshell/src/unity-session-button-accessible.cpp 1970-01-01 00:00:00 +0000
26+++ plugins/unityshell/src/unity-session-button-accessible.cpp 2014-02-25 01:48:00 +0000
27@@ -0,0 +1,260 @@
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: Luke Yelavich <luke.yelavich@canonical.com>
44+ */
45+
46+/**
47+ * SECTION:unity-session_button_accessible
48+ * @Title: UnitySessionButtonAccessible
49+ * @short_description: Implementation of the ATK interfaces for #unity::session::Button
50+ *
51+ * #UnitySessionButtonAccessible implements the required ATK interfaces of
52+ * unity::Button, exposing the common elements on each basic individual
53+ * element (position, extents, etc)
54+ *
55+ */
56+
57+#include "unity-session-button-accessible.h"
58+#include "SessionButton.h"
59+
60+#include "unitya11y.h"
61+
62+using namespace unity::session;
63+
64+/* GObject */
65+static void unity_session_button_accessible_class_init(UnitySessionButtonAccessibleClass* klass);
66+static void unity_session_button_accessible_init(UnitySessionButtonAccessible* session_button_accessible);
67+static void unity_session_button_accessible_dispose(GObject* object);
68+static void unity_session_button_accessible_finalize(GObject* object);
69+
70+
71+/* AtkObject.h */
72+static void unity_session_button_accessible_initialize(AtkObject* accessible,
73+ gpointer data);
74+static AtkStateSet* unity_session_button_accessible_ref_state_set(AtkObject* obj);
75+static const gchar* unity_session_button_accessible_get_name(AtkObject* obj);
76+
77+
78+/* AtkAction */
79+static void atk_action_interface_init(AtkActionIface *iface);
80+static gboolean unity_session_button_accessible_do_action(AtkAction *action,
81+ gint i);
82+static gint unity_session_button_accessible_get_n_actions(AtkAction *action);
83+static const gchar* unity_session_button_accessible_get_name(AtkAction *action,
84+ gint i);
85+
86+/* private/utility methods*/
87+static void on_focus_change_cb(bool const& value, UnitySessionButtonAccessible* accessible);
88+
89+G_DEFINE_TYPE_WITH_CODE(UnitySessionButtonAccessible,
90+ unity_session_button_accessible,
91+ NUX_TYPE_OBJECT_ACCESSIBLE,
92+ G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
93+ atk_action_interface_init))
94+
95+static void
96+unity_session_button_accessible_class_init(UnitySessionButtonAccessibleClass* klass)
97+{
98+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
99+ AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
100+
101+ gobject_class->dispose = unity_session_button_accessible_dispose;
102+ gobject_class->finalize = unity_session_button_accessible_finalize;
103+
104+ /* AtkObject */
105+ atk_class->initialize = unity_session_button_accessible_initialize;
106+ atk_class->get_name = unity_session_button_accessible_get_name;
107+ atk_class->ref_state_set = unity_session_button_accessible_ref_state_set;
108+}
109+
110+static void
111+unity_session_button_accessible_init(UnitySessionButtonAccessible* session_button_accessible)
112+{
113+}
114+
115+static void
116+unity_session_button_accessible_dispose(GObject* object)
117+{
118+ G_OBJECT_CLASS(unity_session_button_accessible_parent_class)->dispose(object);
119+}
120+
121+static void
122+unity_session_button_accessible_finalize(GObject* object)
123+{
124+ G_OBJECT_CLASS(unity_session_button_accessible_parent_class)->finalize(object);
125+}
126+
127+AtkObject*
128+unity_session_button_accessible_new(nux::Object* object)
129+{
130+ AtkObject* accessible = NULL;
131+
132+ g_return_val_if_fail(dynamic_cast<Button*>(object), NULL);
133+
134+ accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE, NULL));
135+
136+ atk_object_initialize(accessible, object);
137+
138+ return accessible;
139+}
140+
141+/* AtkObject.h */
142+static void
143+unity_session_button_accessible_initialize(AtkObject* accessible,
144+ gpointer data)
145+{
146+ UnitySessionButtonAccessible* self = NULL;
147+ nux::Object* nux_object = NULL;
148+ Button* button = NULL;
149+
150+ ATK_OBJECT_CLASS(unity_session_button_accessible_parent_class)->initialize(accessible, data);
151+ self = UNITY_SESSION_BUTTON_ACCESSIBLE(accessible);
152+
153+ accessible->role = ATK_ROLE_PUSH_BUTTON;
154+
155+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
156+
157+ if (nux_object == NULL) /* defunct */
158+ return;
159+
160+ button = dynamic_cast<Button*>(nux_object);
161+
162+ button->highlighted.changed.connect(sigc::bind(sigc::ptr_fun(on_focus_change_cb),
163+ UNITY_SESSION_BUTTON_ACCESSIBLE(self)));
164+}
165+
166+static const gchar*
167+unity_session_button_accessible_get_name(AtkObject* obj)
168+{
169+ const gchar* name;
170+
171+ g_return_val_if_fail(UNITY_IS_SESSION_BUTTON_ACCESSIBLE(obj), NULL);
172+
173+ name = ATK_OBJECT_CLASS(unity_session_button_accessible_parent_class)->get_name(obj);
174+ if (name == NULL)
175+ {
176+ Button* button = NULL;
177+
178+ button = dynamic_cast<Button*>(nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)));
179+
180+ if (button == NULL) /* State is defunct */
181+ name = NULL;
182+ else
183+ name = button->label().c_str();
184+ }
185+
186+ return name;
187+}
188+
189+static AtkStateSet*
190+unity_session_button_accessible_ref_state_set(AtkObject* obj)
191+{
192+ AtkStateSet* state_set = NULL;
193+ nux::Object* nux_object = NULL;
194+ Button* button = NULL;
195+
196+ g_return_val_if_fail(UNITY_IS_SESSION_BUTTON_ACCESSIBLE(obj), NULL);
197+
198+ state_set = ATK_OBJECT_CLASS(unity_session_button_accessible_parent_class)->ref_state_set(obj);
199+
200+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
201+
202+ if (nux_object == NULL) /* defunct */
203+ return state_set;
204+
205+ button = dynamic_cast<Button*>(nux_object);
206+
207+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
208+ atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
209+ atk_state_set_add_state(state_set, ATK_STATE_SENSITIVE);
210+ atk_state_set_add_state(state_set, ATK_STATE_VISIBLE);
211+ atk_state_set_add_state(state_set, ATK_STATE_SHOWING);
212+
213+ if (button->highlighted)
214+ {
215+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSED);
216+ atk_state_set_add_state(state_set, ATK_STATE_SELECTED);
217+ atk_state_set_add_state(state_set, ATK_STATE_ACTIVE);
218+ }
219+
220+ return state_set;
221+}
222+
223+/* private methods */
224+static void
225+on_focus_change_cb(bool const& value, UnitySessionButtonAccessible* accessible)
226+{
227+ nux::Object* nux_object = NULL;
228+ Button* button = NULL;
229+
230+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
231+
232+ if (nux_object == NULL) /* defunct */
233+ return;
234+
235+ button = dynamic_cast<Button*>(nux_object);
236+
237+ atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_FOCUSED, button->highlighted);
238+ atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_SELECTED, button->highlighted);
239+ atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_ACTIVE, button->highlighted);
240+}
241+
242+/* AtkAction */
243+static void
244+atk_action_interface_init(AtkActionIface *iface)
245+{
246+ iface->do_action = unity_session_button_accessible_do_action;
247+ iface->get_n_actions = unity_session_button_accessible_get_n_actions;
248+ iface->get_name = unity_session_button_accessible_get_name;
249+}
250+
251+static gboolean
252+unity_session_button_accessible_do_action(AtkAction *action,
253+ gint i)
254+{
255+ Button* button = NULL;
256+ nux::Object* nux_object = NULL;
257+
258+ g_return_val_if_fail(UNITY_IS_SESSION_BUTTON_ACCESSIBLE(action), FALSE);
259+
260+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(action));
261+ if (nux_object == NULL)
262+ return FALSE;
263+
264+ button = dynamic_cast<Button*>(nux_object);
265+
266+ button->activated.emit();
267+
268+ return TRUE;
269+}
270+
271+static gint
272+unity_session_button_accessible_get_n_actions(AtkAction *action)
273+{
274+ g_return_val_if_fail(UNITY_IS_SESSION_BUTTON_ACCESSIBLE(action), 0);
275+
276+ return 1;
277+}
278+
279+static const gchar*
280+unity_session_button_accessible_get_name(AtkAction *action,
281+ gint i)
282+{
283+ g_return_val_if_fail(UNITY_IS_SESSION_BUTTON_ACCESSIBLE(action), NULL);
284+ g_return_val_if_fail(i == 0, NULL);
285+
286+ return "activate";
287+}
288
289=== added file 'plugins/unityshell/src/unity-session-button-accessible.h'
290--- plugins/unityshell/src/unity-session-button-accessible.h 1970-01-01 00:00:00 +0000
291+++ plugins/unityshell/src/unity-session-button-accessible.h 2014-02-25 01:48:00 +0000
292@@ -0,0 +1,53 @@
293+/*
294+ * Copyright (C) 2011 Canonical Ltd
295+ *
296+ * This program is free software: you can redistribute it and/or modify
297+ * it under the terms of the GNU General Public License version 3 as
298+ * published by the Free Software Foundation.
299+ *
300+ * This program is distributed in the hope that it will be useful,
301+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
302+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303+ * GNU General Public License for more details.
304+ *
305+ * You should have received a copy of the GNU General Public License
306+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
307+ *
308+ * Authored by: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
309+ */
310+
311+#ifndef UNITY_SESSION_BUTTON_ACCESSIBLE_H
312+#define UNITY_SESSION_BUTTON_ACCESSIBLE_H
313+
314+#include <atk/atk.h>
315+
316+#include "nux-object-accessible.h"
317+
318+G_BEGIN_DECLS
319+
320+#define UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE (unity_session_button_accessible_get_type ())
321+#define UNITY_SESSION_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE, UnitySessionButtonAccessible))
322+#define UNITY_SESSION_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE, UnitySessionButtonAccessibleClass))
323+#define UNITY_IS_SESSION_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE))
324+#define UNITY_IS_SESSION_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE))
325+#define UNITY_SESSION_BUTTON_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_SESSION_BUTTON_ACCESSIBLE, UnitySessionButtonAccessibleClass))
326+
327+typedef struct _UnitySessionButtonAccessible UnitySessionButtonAccessible;
328+typedef struct _UnitySessionButtonAccessibleClass UnitySessionButtonAccessibleClass;
329+
330+struct _UnitySessionButtonAccessible
331+{
332+ NuxObjectAccessible parent;
333+};
334+
335+struct _UnitySessionButtonAccessibleClass
336+{
337+ NuxObjectAccessibleClass parent_class;
338+};
339+
340+GType unity_session_button_accessible_get_type(void);
341+AtkObject* unity_session_button_accessible_new(nux::Object* object);
342+
343+G_END_DECLS
344+
345+#endif /* __UNITY_SESSION_BUTTON_ACCESSIBLE_H__ */
346
347=== modified file 'plugins/unityshell/src/unitya11y.cpp'
348--- plugins/unityshell/src/unitya11y.cpp 2014-01-25 13:39:49 +0000
349+++ plugins/unityshell/src/unitya11y.cpp 2014-02-25 01:48:00 +0000
350@@ -42,6 +42,7 @@
351 #include "QuicklistView.h"
352 #include "QuicklistMenuItem.h"
353 #include "SwitcherView.h"
354+#include "SessionButton.h"
355 #include "unity-launcher-accessible.h"
356 #include "unity-launcher-icon-accessible.h"
357 #include "unity-panel-view-accessible.h"
358@@ -53,11 +54,13 @@
359 #include "unity-quicklist-accessible.h"
360 #include "unity-quicklist-menu-item-accessible.h"
361 #include "unity-switcher-accessible.h"
362+#include "unity-session-button-accessible.h"
363
364 using namespace unity;
365 using namespace unity::dash;
366 using namespace unity::launcher;
367 using namespace unity::panel;
368+using namespace unity::session;
369
370 static GHashTable* accessible_table = NULL;
371 /* FIXME: remove accessible objects when not required anymore */
372@@ -187,6 +190,9 @@
373 if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType))
374 return unity_switcher_accessible_new(object);
375
376+ if (object->Type().IsDerivedFromType(Button::StaticObjectType))
377+ return unity_session_button_accessible_new(object);
378+
379 /* NUX classes */
380 if (object->Type().IsDerivedFromType(nux::TextEntry::StaticObjectType))
381 return nux_text_entry_accessible_new(object);