Merge lp:~apinheiro/unity/a11y-switcher into lp:unity
- a11y-switcher
- Merge into trunk
Proposed by
Alejandro Piñeiro
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Alex Launi | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 1811 | ||||
Proposed branch: | lp:~apinheiro/unity/a11y-switcher | ||||
Merge into: | lp:unity | ||||
Prerequisite: | lp:~apinheiro/unity/a11y-improve-window-event-emission | ||||
Diff against target: |
855 lines (+567/-80) 9 files modified
plugins/unityshell/src/nux-area-accessible.cpp (+4/-3) plugins/unityshell/src/nux-area-accessible.h (+4/-1) plugins/unityshell/src/nux-view-accessible.cpp (+4/-4) plugins/unityshell/src/unity-launcher-accessible.cpp (+5/-1) plugins/unityshell/src/unity-launcher-icon-accessible.cpp (+66/-71) plugins/unityshell/src/unity-root-accessible.cpp (+5/-0) plugins/unityshell/src/unity-switcher-accessible.cpp (+417/-0) plugins/unityshell/src/unity-switcher-accessible.h (+57/-0) plugins/unityshell/src/unitya11y.cpp (+5/-0) |
||||
To merge this branch: | bzr merge lp:~apinheiro/unity/a11y-switcher | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alex Launi (community) | Approve | ||
Neil J. Patel | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alejandro Piñeiro (apinheiro) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alex Launi (alexlauni) wrote : | # |
Again, sorry for the large delay. This looks great.
review:
Approve
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Unity Merger (unity-merger) wrote : | # |
No proposals found for merge of lp:~apinheiro/unity/a11y-improve-window-event-emission into lp:unity.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugins/unityshell/src/nux-area-accessible.cpp' |
2 | --- plugins/unityshell/src/nux-area-accessible.cpp 2011-11-07 22:37:27 +0000 |
3 | +++ plugins/unityshell/src/nux-area-accessible.cpp 2011-11-07 22:37:27 +0000 |
4 | @@ -177,9 +177,10 @@ |
5 | atk_component_add_focus_handler(ATK_COMPONENT(accessible), |
6 | nux_area_accessible_focus_handler); |
7 | |
8 | - /* NOTE: we can't search for the parent window on initilization, or |
9 | - we could enter on a infinite loop, as this is called on the |
10 | - initalization */ |
11 | + /* NOTE: we can't search for the parent window on initilization as a |
12 | + general rule, or we could enter on a infinite loop. At area this |
13 | + is done on the focus event. On the Switcher this is done on their |
14 | + initialize itself */ |
15 | } |
16 | |
17 | static AtkObject* |
18 | |
19 | === modified file 'plugins/unityshell/src/nux-area-accessible.h' |
20 | --- plugins/unityshell/src/nux-area-accessible.h 2011-08-01 17:53:14 +0000 |
21 | +++ plugins/unityshell/src/nux-area-accessible.h 2011-11-07 22:37:27 +0000 |
22 | @@ -49,7 +49,10 @@ |
23 | NuxObjectAccessibleClass parent_class; |
24 | |
25 | /* |
26 | - * Virtual method to check if there is any pending state change notification |
27 | + * Usually objects shouldn emit events like focus or selection |
28 | + * changes until the toplevel window is active. This method is |
29 | + * called when the toplevel window became active. Redefine it if you |
30 | + * need to check any pending state change notification. |
31 | */ |
32 | gboolean(*check_pending_notification)(NuxAreaAccessible* self); |
33 | |
34 | |
35 | === modified file 'plugins/unityshell/src/nux-view-accessible.cpp' |
36 | --- plugins/unityshell/src/nux-view-accessible.cpp 2011-11-07 22:37:27 +0000 |
37 | +++ plugins/unityshell/src/nux-view-accessible.cpp 2011-11-07 22:37:27 +0000 |
38 | @@ -45,13 +45,13 @@ |
39 | static gint nux_view_accessible_get_n_children(AtkObject* obj); |
40 | static AtkObject* nux_view_accessible_ref_child(AtkObject* obj, |
41 | gint i); |
42 | +static AtkStateSet* nux_view_accessible_ref_state_set(AtkObject* obj); |
43 | +static gint nux_view_accessible_get_n_children(AtkObject* obj); |
44 | +static AtkObject* nux_view_accessible_ref_child(AtkObject* obj, |
45 | + gint i); |
46 | /* NuxAreaAccessible */ |
47 | static gboolean nux_view_accessible_check_pending_notification(NuxAreaAccessible* self); |
48 | |
49 | -static AtkStateSet* nux_view_accessible_ref_state_set(AtkObject* obj); |
50 | -static gint nux_view_accessible_get_n_children(AtkObject* obj); |
51 | -static AtkObject* nux_view_accessible_ref_child(AtkObject* obj, |
52 | - gint i); |
53 | /* private methods */ |
54 | static void on_layout_changed_cb(nux::View* view, |
55 | nux::Layout* layout, |
56 | |
57 | === modified file 'plugins/unityshell/src/unity-launcher-accessible.cpp' |
58 | --- plugins/unityshell/src/unity-launcher-accessible.cpp 2011-11-07 22:37:27 +0000 |
59 | +++ plugins/unityshell/src/unity-launcher-accessible.cpp 2011-11-07 22:37:27 +0000 |
60 | @@ -36,7 +36,6 @@ |
61 | #include "unitya11y.h" |
62 | #include "Launcher.h" |
63 | #include "LauncherModel.h" |
64 | -#include "QuicklistView.h" |
65 | |
66 | using unity::launcher::Launcher; |
67 | using unity::launcher::LauncherIcon; |
68 | @@ -211,6 +210,7 @@ |
69 | LauncherModel::iterator it; |
70 | nux::Object* child = NULL; |
71 | AtkObject* child_accessible = NULL; |
72 | + AtkObject* parent = NULL; |
73 | |
74 | g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(obj), NULL); |
75 | num = atk_object_get_n_accessible_children(obj); |
76 | @@ -230,6 +230,10 @@ |
77 | child = dynamic_cast<nux::Object*>(*it); |
78 | child_accessible = unity_a11y_get_accessible(child); |
79 | |
80 | + parent = atk_object_get_parent(child_accessible); |
81 | + if (parent != obj) |
82 | + atk_object_set_parent(child_accessible, obj); |
83 | + |
84 | g_object_ref(child_accessible); |
85 | |
86 | return child_accessible; |
87 | |
88 | === modified file 'plugins/unityshell/src/unity-launcher-icon-accessible.cpp' |
89 | --- plugins/unityshell/src/unity-launcher-icon-accessible.cpp 2011-11-07 22:37:27 +0000 |
90 | +++ plugins/unityshell/src/unity-launcher-icon-accessible.cpp 2011-11-07 22:37:27 +0000 |
91 | @@ -26,6 +26,19 @@ |
92 | * nux::LauncherIcon, exposing the common elements on each basic individual |
93 | * element (position, extents, etc) |
94 | * |
95 | + * Implementation notes: on previous implementations we implemented |
96 | + * _get_parent using the LauncherIcon method GetLauncher. But this is |
97 | + * not the case in all the situations. When the user is interacting |
98 | + * with the Switcher, we consider that the parent of that LauncherIcon |
99 | + * is the Switcher. |
100 | + * |
101 | + * The parent is set with atk_object_set_parent as usual. |
102 | + * |
103 | + * As this object is used both on UnityLauncherAccessible and |
104 | + * UnitySwitcherAccessible, we have removed as much as possible any |
105 | + * reference to the Launcher, LauncherModel, SwitcherView or |
106 | + * SwitcherModel. |
107 | + * |
108 | */ |
109 | |
110 | #include "unity-launcher-icon-accessible.h" |
111 | @@ -49,7 +62,7 @@ |
112 | gpointer data); |
113 | static AtkStateSet* unity_launcher_icon_accessible_ref_state_set(AtkObject* obj); |
114 | static const gchar* unity_launcher_icon_accessible_get_name(AtkObject* obj); |
115 | -static AtkObject* unity_launcher_icon_accessible_get_parent(AtkObject* obj); |
116 | +// static AtkObject* unity_launcher_icon_accessible_get_parent(AtkObject* obj); |
117 | static gint unity_launcher_icon_accessible_get_index_in_parent(AtkObject* obj); |
118 | |
119 | /* AtkComponent.h */ |
120 | @@ -86,6 +99,7 @@ |
121 | gboolean parent_focused; |
122 | gboolean index_in_parent; |
123 | |
124 | + guint on_parent_change_id; |
125 | guint on_parent_selection_change_id; |
126 | guint on_parent_focus_event_id; |
127 | }; |
128 | @@ -102,7 +116,7 @@ |
129 | atk_class->initialize = unity_launcher_icon_accessible_initialize; |
130 | atk_class->get_name = unity_launcher_icon_accessible_get_name; |
131 | atk_class->ref_state_set = unity_launcher_icon_accessible_ref_state_set; |
132 | - atk_class->get_parent = unity_launcher_icon_accessible_get_parent; |
133 | + // atk_class->get_parent = unity_launcher_icon_accessible_get_parent; |
134 | atk_class->get_index_in_parent = unity_launcher_icon_accessible_get_index_in_parent; |
135 | |
136 | g_type_class_add_private(gobject_class, sizeof(UnityLauncherIconAccessiblePrivate)); |
137 | @@ -125,7 +139,7 @@ |
138 | |
139 | parent = atk_object_get_parent(ATK_OBJECT(object)); |
140 | |
141 | - if (UNITY_IS_LAUNCHER_ACCESSIBLE(parent)) |
142 | + if (parent != NULL) |
143 | { |
144 | if (self->priv->on_parent_selection_change_id != 0) |
145 | g_signal_handler_disconnect(parent, self->priv->on_parent_selection_change_id); |
146 | @@ -134,6 +148,9 @@ |
147 | g_signal_handler_disconnect(parent, self->priv->on_parent_focus_event_id); |
148 | } |
149 | |
150 | + if (self->priv->on_parent_change_id != 0) |
151 | + g_signal_handler_disconnect(object, self->priv->on_parent_change_id); |
152 | + |
153 | G_OBJECT_CLASS(unity_launcher_icon_accessible_parent_class)->dispose(object); |
154 | } |
155 | |
156 | @@ -154,41 +171,56 @@ |
157 | |
158 | /* AtkObject.h */ |
159 | static void |
160 | +on_parent_change_cb(gchar* property, |
161 | + GValue* value, |
162 | + gpointer data) |
163 | +{ |
164 | + AtkObject* parent = NULL; |
165 | + UnityLauncherIconAccessible* self = NULL; |
166 | + AtkStateSet* state_set = NULL; |
167 | + |
168 | + g_return_if_fail(UNITY_IS_LAUNCHER_ICON_ACCESSIBLE(data)); |
169 | + |
170 | + self = UNITY_LAUNCHER_ICON_ACCESSIBLE(data); |
171 | + parent = atk_object_get_parent(ATK_OBJECT(data)); |
172 | + |
173 | + if (parent == NULL) |
174 | + return; |
175 | + |
176 | + self->priv->on_parent_selection_change_id = |
177 | + g_signal_connect(parent, "selection-changed", |
178 | + G_CALLBACK(on_parent_selection_change_cb), self); |
179 | + |
180 | + self->priv->on_parent_focus_event_id = |
181 | + g_signal_connect(parent, "focus-event", |
182 | + G_CALLBACK(on_parent_focus_event_cb), self); |
183 | + |
184 | + state_set = atk_object_ref_state_set(parent); |
185 | + if (atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED)) |
186 | + { |
187 | + self->priv->parent_focused = TRUE; |
188 | + } |
189 | + g_object_unref(state_set); |
190 | +} |
191 | + |
192 | +static void |
193 | unity_launcher_icon_accessible_initialize(AtkObject* accessible, |
194 | gpointer data) |
195 | { |
196 | - LauncherIcon* icon = NULL; |
197 | - Launcher* launcher = NULL; |
198 | - UnityLauncherAccessible* launcher_accessible = NULL; |
199 | UnityLauncherIconAccessible* self = NULL; |
200 | - nux::Object* nux_object = NULL; |
201 | |
202 | ATK_OBJECT_CLASS(unity_launcher_icon_accessible_parent_class)->initialize(accessible, data); |
203 | self = UNITY_LAUNCHER_ICON_ACCESSIBLE(accessible); |
204 | |
205 | accessible->role = ATK_ROLE_PUSH_BUTTON; |
206 | |
207 | - nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible)); |
208 | - icon = dynamic_cast<LauncherIcon*>(nux_object); |
209 | - launcher = icon->GetLauncher(); |
210 | - |
211 | - if (launcher == NULL) |
212 | - return; |
213 | - |
214 | - /* NOTE: we could also get the launcher_accessible by just calling |
215 | - atk_object_get_parent */ |
216 | - launcher_accessible = UNITY_LAUNCHER_ACCESSIBLE(unity_a11y_get_accessible(launcher)); |
217 | - |
218 | - self->priv->on_parent_selection_change_id = |
219 | - g_signal_connect(launcher_accessible, "selection-changed", |
220 | - G_CALLBACK(on_parent_selection_change_cb), self); |
221 | - |
222 | - self->priv->on_parent_focus_event_id = |
223 | - g_signal_connect(launcher_accessible, "focus-event", |
224 | - G_CALLBACK(on_parent_focus_event_cb), self); |
225 | - |
226 | atk_component_add_focus_handler(ATK_COMPONENT(accessible), |
227 | unity_launcher_icon_accessible_focus_handler); |
228 | + |
229 | + /* we could do that by redefining ->set_parent */ |
230 | + self->priv->on_parent_change_id = |
231 | + g_signal_connect(accessible, "notify::accessible-parent", |
232 | + G_CALLBACK(on_parent_change_cb), self); |
233 | } |
234 | |
235 | |
236 | @@ -256,31 +288,6 @@ |
237 | return state_set; |
238 | } |
239 | |
240 | -static AtkObject* |
241 | -unity_launcher_icon_accessible_get_parent(AtkObject* obj) |
242 | -{ |
243 | - nux::Object* nux_object = NULL; |
244 | - LauncherIcon* icon = NULL; |
245 | - Launcher* launcher = NULL; |
246 | - |
247 | - g_return_val_if_fail(UNITY_IS_LAUNCHER_ICON_ACCESSIBLE(obj), NULL); |
248 | - |
249 | - if (obj->accessible_parent) |
250 | - return obj->accessible_parent; |
251 | - |
252 | - nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)); |
253 | - |
254 | - if (nux_object == NULL) /* defunct */ |
255 | - return NULL; |
256 | - |
257 | - icon = dynamic_cast<LauncherIcon*>(nux_object); |
258 | - launcher = icon->GetLauncher(); |
259 | - |
260 | - g_return_val_if_fail(dynamic_cast<Launcher*>(launcher), NULL); |
261 | - |
262 | - return unity_a11y_get_accessible(launcher); |
263 | -} |
264 | - |
265 | /* private methods */ |
266 | |
267 | /* |
268 | @@ -290,27 +297,15 @@ |
269 | static void |
270 | check_selected(UnityLauncherIconAccessible* self) |
271 | { |
272 | - LauncherIcon* icon = NULL; |
273 | - LauncherIcon* selected_icon = NULL; |
274 | - Launcher* launcher = NULL; |
275 | - nux::Object* nux_object = NULL; |
276 | + AtkObject* parent = NULL; |
277 | gboolean found = FALSE; |
278 | |
279 | - nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(self)); |
280 | - |
281 | - if (nux_object == NULL) /* state is defunct */ |
282 | - return; |
283 | - |
284 | - icon = dynamic_cast<LauncherIcon*>(nux_object); |
285 | - launcher = icon->GetLauncher(); |
286 | - |
287 | - if (launcher == NULL) |
288 | - return; |
289 | - |
290 | - selected_icon = launcher->GetSelectedMenuIcon(); |
291 | - |
292 | - if (icon == selected_icon) |
293 | - found = TRUE; |
294 | + parent = atk_object_get_parent(ATK_OBJECT(self)); |
295 | + if (parent == NULL) |
296 | + return; |
297 | + |
298 | + found = atk_selection_is_child_selected(ATK_SELECTION(parent), |
299 | + self->priv->index_in_parent); |
300 | |
301 | if ((found) && (self->priv->parent_focused == FALSE)) |
302 | return; |
303 | @@ -326,6 +321,7 @@ |
304 | atk_object_notify_state_change(ATK_OBJECT(self), |
305 | ATK_STATE_ACTIVE, |
306 | found); |
307 | + |
308 | g_signal_emit_by_name(self, "focus-event", self->priv->selected, &return_val); |
309 | atk_focus_tracker_notify(ATK_OBJECT(self)); |
310 | } |
311 | @@ -335,7 +331,6 @@ |
312 | on_parent_selection_change_cb(AtkSelection* selection, |
313 | gpointer data) |
314 | { |
315 | - g_return_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(selection)); |
316 | g_return_if_fail(UNITY_IS_LAUNCHER_ICON_ACCESSIBLE(data)); |
317 | |
318 | check_selected(UNITY_LAUNCHER_ICON_ACCESSIBLE(data)); |
319 | |
320 | === modified file 'plugins/unityshell/src/unity-root-accessible.cpp' |
321 | --- plugins/unityshell/src/unity-root-accessible.cpp 2011-11-07 22:37:27 +0000 |
322 | +++ plugins/unityshell/src/unity-root-accessible.cpp 2011-11-07 22:37:27 +0000 |
323 | @@ -258,6 +258,9 @@ |
324 | window_accessible = |
325 | unity_a11y_get_accessible(window); |
326 | |
327 | + /* FIXME: temporal */ |
328 | + atk_object_set_name (window_accessible, window->GetWindowName().GetTCharPtr()); |
329 | + |
330 | if (g_slist_find(self->priv->window_list, window_accessible)) |
331 | return; |
332 | |
333 | @@ -293,6 +296,8 @@ |
334 | window_accessible = |
335 | unity_a11y_get_accessible(window); |
336 | |
337 | + return; |
338 | + |
339 | if (!g_slist_find(self->priv->window_list, window_accessible)) |
340 | return; |
341 | |
342 | |
343 | === added file 'plugins/unityshell/src/unity-switcher-accessible.cpp' |
344 | --- plugins/unityshell/src/unity-switcher-accessible.cpp 1970-01-01 00:00:00 +0000 |
345 | +++ plugins/unityshell/src/unity-switcher-accessible.cpp 2011-11-07 22:37:27 +0000 |
346 | @@ -0,0 +1,417 @@ |
347 | +/* |
348 | + * Copyright (C) 2011 Canonical Ltd |
349 | + * |
350 | + * This program is free software: you can redistribute it and/or modify |
351 | + * it under the terms of the GNU General Public License version 3 as |
352 | + * published by the Free Software Foundation. |
353 | + * |
354 | + * This program is distributed in the hope that it will be useful, |
355 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
356 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
357 | + * GNU General Public License for more details. |
358 | + * |
359 | + * You should have received a copy of the GNU General Public License |
360 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
361 | + * |
362 | + * Authored by: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> |
363 | + */ |
364 | + |
365 | +/** |
366 | + * SECTION:unity-switcher-accessible |
367 | + * @Title: UnitySwitcherAccessible |
368 | + * @short_description: Implementation of the ATK interfaces for #SwitcherView |
369 | + * @see_also: SwitcherView |
370 | + * |
371 | + * #UnitySwitcherAccessible implements the required ATK interfaces for |
372 | + * #SwitcherView, ie: exposing the different AbstractLauncherIcon on the |
373 | + * #model as child of the object. |
374 | + * |
375 | + */ |
376 | + |
377 | +#include <glib/gi18n.h> |
378 | + |
379 | +#include "unity-switcher-accessible.h" |
380 | +#include "unity-launcher-icon-accessible.h" |
381 | + |
382 | +#include "unitya11y.h" |
383 | +#include "SwitcherView.h" |
384 | +#include "SwitcherModel.h" |
385 | + |
386 | +using namespace unity::switcher; |
387 | +using namespace unity::launcher; |
388 | + |
389 | +/* GObject */ |
390 | +static void unity_switcher_accessible_class_init(UnitySwitcherAccessibleClass* klass); |
391 | +static void unity_switcher_accessible_init(UnitySwitcherAccessible* self); |
392 | +static void unity_switcher_accessible_finalize(GObject* object); |
393 | + |
394 | +/* AtkObject.h */ |
395 | +static void unity_switcher_accessible_initialize(AtkObject* accessible, |
396 | + gpointer data); |
397 | +static gint unity_switcher_accessible_get_n_children(AtkObject* obj); |
398 | +static AtkObject* unity_switcher_accessible_ref_child(AtkObject* obj, |
399 | + gint i); |
400 | +static AtkStateSet* unity_switcher_accessible_ref_state_set(AtkObject* obj); |
401 | + |
402 | +/* AtkSelection */ |
403 | +static void atk_selection_interface_init(AtkSelectionIface* iface); |
404 | +static AtkObject* unity_switcher_accessible_ref_selection(AtkSelection* selection, |
405 | + gint i); |
406 | +static gint unity_switcher_accessible_get_selection_count(AtkSelection* selection); |
407 | +static gboolean unity_switcher_accessible_is_child_selected(AtkSelection* selection, |
408 | + gint i); |
409 | +/* NuxAreaAccessible */ |
410 | +static gboolean unity_switcher_accessible_check_pending_notification(NuxAreaAccessible* self); |
411 | + |
412 | +/* private */ |
413 | +static void on_selection_changed_cb(AbstractLauncherIcon* icon, |
414 | + UnitySwitcherAccessible* switcher_accessible); |
415 | +static void create_children(UnitySwitcherAccessible* self); |
416 | + |
417 | + |
418 | +G_DEFINE_TYPE_WITH_CODE(UnitySwitcherAccessible, unity_switcher_accessible, NUX_TYPE_VIEW_ACCESSIBLE, |
419 | + G_IMPLEMENT_INTERFACE(ATK_TYPE_SELECTION, atk_selection_interface_init)) |
420 | + |
421 | +#define UNITY_SWITCHER_ACCESSIBLE_GET_PRIVATE(obj) \ |
422 | + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_SWITCHER_ACCESSIBLE, \ |
423 | + UnitySwitcherAccessiblePrivate)) |
424 | + |
425 | +struct _UnitySwitcherAccessiblePrivate |
426 | +{ |
427 | + /* We maintain the children. Although the LauncherIcon are shared |
428 | + * between the Switcher and Launcher, in order to keep a hierarchy |
429 | + * coherence, we create a different accessible object */ |
430 | + GSList* children; |
431 | + |
432 | + sigc::connection on_selection_changed_connection; |
433 | +}; |
434 | + |
435 | + |
436 | +static void |
437 | +unity_switcher_accessible_class_init(UnitySwitcherAccessibleClass* klass) |
438 | +{ |
439 | + GObjectClass* gobject_class = G_OBJECT_CLASS(klass); |
440 | + AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass); |
441 | + NuxAreaAccessibleClass* area_class = NUX_AREA_ACCESSIBLE_CLASS(klass); |
442 | + |
443 | + gobject_class->finalize = unity_switcher_accessible_finalize; |
444 | + |
445 | + /* AtkObject */ |
446 | + atk_class->get_n_children = unity_switcher_accessible_get_n_children; |
447 | + atk_class->ref_child = unity_switcher_accessible_ref_child; |
448 | + atk_class->initialize = unity_switcher_accessible_initialize; |
449 | + atk_class->ref_state_set = unity_switcher_accessible_ref_state_set; |
450 | + |
451 | + /* NuxAreaAccessible */ |
452 | + area_class->check_pending_notification = unity_switcher_accessible_check_pending_notification; |
453 | + |
454 | + g_type_class_add_private(gobject_class, sizeof(UnitySwitcherAccessiblePrivate)); |
455 | +} |
456 | + |
457 | +static void |
458 | +unity_switcher_accessible_init(UnitySwitcherAccessible* self) |
459 | +{ |
460 | + UnitySwitcherAccessiblePrivate* priv = |
461 | + UNITY_SWITCHER_ACCESSIBLE_GET_PRIVATE(self); |
462 | + |
463 | + self->priv = priv; |
464 | + self->priv->children = NULL; |
465 | +} |
466 | + |
467 | +static void |
468 | +unity_switcher_accessible_finalize(GObject* object) |
469 | +{ |
470 | + UnitySwitcherAccessible* self = UNITY_SWITCHER_ACCESSIBLE(object); |
471 | + |
472 | + self->priv->on_selection_changed_connection.disconnect(); |
473 | + |
474 | + if (self->priv->children) |
475 | + { |
476 | + g_slist_free_full(self->priv->children, g_object_unref); |
477 | + self->priv->children = NULL; |
478 | + } |
479 | + |
480 | + G_OBJECT_CLASS(unity_switcher_accessible_parent_class)->finalize(object); |
481 | +} |
482 | + |
483 | +AtkObject* |
484 | +unity_switcher_accessible_new(nux::Object* object) |
485 | +{ |
486 | + AtkObject* accessible = NULL; |
487 | + |
488 | + g_return_val_if_fail(dynamic_cast<SwitcherView*>(object), NULL); |
489 | + |
490 | + accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_SWITCHER_ACCESSIBLE, NULL)); |
491 | + |
492 | + atk_object_initialize(accessible, object); |
493 | + atk_object_set_name(accessible, _("Switcher")); |
494 | + |
495 | + return accessible; |
496 | +} |
497 | + |
498 | +/* AtkObject.h */ |
499 | +static void |
500 | +unity_switcher_accessible_initialize(AtkObject* accessible, |
501 | + gpointer data) |
502 | +{ |
503 | + SwitcherView* switcher = NULL; |
504 | + nux::Object* nux_object = NULL; |
505 | + UnitySwitcherAccessible* self = NULL; |
506 | + SwitcherModel::Ptr model; |
507 | + |
508 | + ATK_OBJECT_CLASS(unity_switcher_accessible_parent_class)->initialize(accessible, data); |
509 | + |
510 | + atk_object_set_role(accessible, ATK_ROLE_TOOL_BAR); |
511 | + |
512 | + self = UNITY_SWITCHER_ACCESSIBLE(accessible); |
513 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible)); |
514 | + switcher = dynamic_cast<SwitcherView*>(nux_object); |
515 | + if (switcher == NULL) |
516 | + return; |
517 | + |
518 | + model = switcher->GetModel(); |
519 | + |
520 | + if (model) |
521 | + { |
522 | + self->priv->on_selection_changed_connection = |
523 | + model->selection_changed.connect(sigc::bind(sigc::ptr_fun(on_selection_changed_cb), |
524 | + self)); |
525 | + |
526 | + create_children(self); |
527 | + } |
528 | + |
529 | + /* To force being connected to the window::activate signal */ |
530 | + nux_area_accessible_parent_window_active(NUX_AREA_ACCESSIBLE(self)); |
531 | +} |
532 | + |
533 | +static gint |
534 | +unity_switcher_accessible_get_n_children(AtkObject* obj) |
535 | +{ |
536 | + nux::Object* object = NULL; |
537 | + UnitySwitcherAccessible* self = NULL; |
538 | + |
539 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(obj), 0); |
540 | + self = UNITY_SWITCHER_ACCESSIBLE(obj); |
541 | + |
542 | + object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)); |
543 | + if (!object) /* state is defunct */ |
544 | + return 0; |
545 | + |
546 | + return g_slist_length(self->priv->children); |
547 | +} |
548 | + |
549 | +static AtkObject* |
550 | +unity_switcher_accessible_ref_child(AtkObject* obj, |
551 | + gint i) |
552 | +{ |
553 | + gint num = 0; |
554 | + nux::Object* nux_object = NULL; |
555 | + AtkObject* child_accessible = NULL; |
556 | + UnitySwitcherAccessible* self = NULL; |
557 | + |
558 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(obj), NULL); |
559 | + num = atk_object_get_n_accessible_children(obj); |
560 | + g_return_val_if_fail((i < num) && (i >= 0), NULL); |
561 | + self = UNITY_SWITCHER_ACCESSIBLE(obj); |
562 | + |
563 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)); |
564 | + if (!nux_object) /* state is defunct */ |
565 | + return 0; |
566 | + |
567 | + child_accessible = ATK_OBJECT(g_slist_nth_data(self->priv->children, i)); |
568 | + |
569 | + g_object_ref(child_accessible); |
570 | + |
571 | + return child_accessible; |
572 | +} |
573 | + |
574 | +static AtkStateSet* |
575 | +unity_switcher_accessible_ref_state_set(AtkObject* obj) |
576 | +{ |
577 | + AtkStateSet* state_set = NULL; |
578 | + nux::Object* nux_object = NULL; |
579 | + |
580 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(obj), NULL); |
581 | + |
582 | + state_set = |
583 | + ATK_OBJECT_CLASS(unity_switcher_accessible_parent_class)->ref_state_set(obj); |
584 | + |
585 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)); |
586 | + |
587 | + if (nux_object == NULL) /* defunct */ |
588 | + return state_set; |
589 | + |
590 | + /* The Switcher is always focusable */ |
591 | + atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE); |
592 | + |
593 | + /* The Switcher is always focused. Looking SwitcherController code, |
594 | + * SwitcherView is only created to be presented to the user */ |
595 | + atk_state_set_add_state(state_set, ATK_STATE_FOCUSED); |
596 | + |
597 | + return state_set; |
598 | +} |
599 | + |
600 | +/* AtkSelection */ |
601 | +static void |
602 | +atk_selection_interface_init(AtkSelectionIface* iface) |
603 | +{ |
604 | + iface->ref_selection = unity_switcher_accessible_ref_selection; |
605 | + iface->get_selection_count = unity_switcher_accessible_get_selection_count; |
606 | + iface->is_child_selected = unity_switcher_accessible_is_child_selected; |
607 | + |
608 | + /* NOTE: for the moment we don't provide the implementation for the |
609 | + "interactable" methods, it is, the methods that allow to change |
610 | + the selected icon. The Switcher doesn't provide that API, and |
611 | + right now we are focusing on a normal user input.*/ |
612 | + /* iface->add_selection = unity_switcher_accessible_add_selection; */ |
613 | + /* iface->clear_selection = unity_switcher_accessible_clear_selection; */ |
614 | + /* iface->remove_selection = unity_switcher_accessible_remove_selection; */ |
615 | + |
616 | + /* This method will never be implemented, as select all the switcher |
617 | + icons makes no sense */ |
618 | + /* iface->select_all = unity_switcher_accessible_select_all_selection; */ |
619 | +} |
620 | + |
621 | +static AtkObject* |
622 | +unity_switcher_accessible_ref_selection(AtkSelection* selection, |
623 | + gint i) |
624 | +{ |
625 | + SwitcherView* switcher = NULL; |
626 | + SwitcherModel::Ptr switcher_model; |
627 | + nux::Object* nux_object = NULL; |
628 | + gint selected_index = 0; |
629 | + AtkObject* accessible_selected = NULL; |
630 | + UnitySwitcherAccessible* self = NULL; |
631 | + |
632 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(selection), 0); |
633 | + /* there can be only just item selected */ |
634 | + g_return_val_if_fail(i == 0, NULL); |
635 | + self = UNITY_SWITCHER_ACCESSIBLE(selection); |
636 | + |
637 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection)); |
638 | + if (!nux_object) /* state is defunct */ |
639 | + return 0; |
640 | + |
641 | + switcher = dynamic_cast<SwitcherView*>(nux_object); |
642 | + |
643 | + switcher_model = switcher->GetModel(); |
644 | + selected_index = switcher_model->SelectionIndex(); |
645 | + |
646 | + accessible_selected = ATK_OBJECT(g_slist_nth_data(self->priv->children, |
647 | + selected_index)); |
648 | + |
649 | + if (accessible_selected != NULL) |
650 | + g_object_ref(accessible_selected); |
651 | + |
652 | + return accessible_selected; |
653 | +} |
654 | + |
655 | +static gint |
656 | +unity_switcher_accessible_get_selection_count(AtkSelection* selection) |
657 | +{ |
658 | + SwitcherView* switcher = NULL; |
659 | + SwitcherModel::Ptr switcher_model; |
660 | + AbstractLauncherIcon* selected_icon = NULL; |
661 | + nux::Object* nux_object = NULL; |
662 | + |
663 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(selection), 0); |
664 | + |
665 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection)); |
666 | + if (!nux_object) /* state is defunct */ |
667 | + return 0; |
668 | + |
669 | + switcher = dynamic_cast<SwitcherView*>(nux_object); |
670 | + switcher_model = switcher->GetModel(); |
671 | + |
672 | + selected_icon = switcher_model->Selection(); |
673 | + |
674 | + if (selected_icon == 0) |
675 | + return 0; |
676 | + else |
677 | + return 1; |
678 | +} |
679 | + |
680 | +static gboolean |
681 | +unity_switcher_accessible_is_child_selected(AtkSelection* selection, |
682 | + gint i) |
683 | +{ |
684 | + SwitcherView* switcher = NULL; |
685 | + SwitcherModel::Ptr switcher_model; |
686 | + SwitcherModel::iterator it; |
687 | + nux::Object* nux_object = NULL; |
688 | + gint selected_index = 0; |
689 | + |
690 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(selection), FALSE); |
691 | + |
692 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection)); |
693 | + if (!nux_object) /* state is defunct */ |
694 | + return 0; |
695 | + |
696 | + switcher = dynamic_cast<SwitcherView*>(nux_object); |
697 | + switcher_model = switcher->GetModel(); |
698 | + selected_index = switcher_model->SelectionIndex(); |
699 | + |
700 | + if (selected_index == i) |
701 | + return TRUE; |
702 | + else |
703 | + return FALSE; |
704 | +} |
705 | + |
706 | +/* NuxAreaAccessible */ |
707 | +static gboolean |
708 | +unity_switcher_accessible_check_pending_notification(NuxAreaAccessible* self) |
709 | +{ |
710 | + g_return_val_if_fail(UNITY_IS_SWITCHER_ACCESSIBLE(self), FALSE); |
711 | + |
712 | + /* Overriding the method: the switcher doesn't get the key focus of |
713 | + * focus (Focusable) */ |
714 | + /* From SwitcherController: it shows that the switcher only exists |
715 | + * to be shown to the user, so if the parent window gets actived, we |
716 | + * assume that the switcher will be automatically focused |
717 | + */ |
718 | + atk_object_notify_state_change(ATK_OBJECT(self), ATK_STATE_FOCUSED, TRUE); |
719 | + g_signal_emit_by_name(self, "focus-event", TRUE, NULL); |
720 | + |
721 | + return TRUE; |
722 | +} |
723 | + |
724 | +/* private */ |
725 | +static void |
726 | +on_selection_changed_cb(AbstractLauncherIcon* icon, |
727 | + UnitySwitcherAccessible* switcher_accessible) |
728 | +{ |
729 | + g_signal_emit_by_name(ATK_OBJECT(switcher_accessible), "selection-changed"); |
730 | +} |
731 | + |
732 | +static void |
733 | +create_children(UnitySwitcherAccessible* self) |
734 | +{ |
735 | + gint index = 0; |
736 | + nux::Object* nux_object = NULL; |
737 | + SwitcherView* switcher = NULL; |
738 | + SwitcherModel::Ptr switcher_model; |
739 | + SwitcherModel::iterator it; |
740 | + LauncherIcon* child = NULL; |
741 | + AtkObject* child_accessible = NULL; |
742 | + |
743 | + nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(self)); |
744 | + if (!nux_object) /* state is defunct */ |
745 | + return; |
746 | + |
747 | + switcher = dynamic_cast<SwitcherView*>(nux_object); |
748 | + switcher_model = switcher->GetModel(); |
749 | + |
750 | + if (switcher_model == NULL) |
751 | + return; |
752 | + |
753 | + for (it = switcher_model->begin(); it != switcher_model->end(); it++) |
754 | + { |
755 | + child = dynamic_cast<LauncherIcon*>(*it); |
756 | + child_accessible = unity_launcher_icon_accessible_new(child); |
757 | + atk_object_set_parent(child_accessible, ATK_OBJECT(self)); |
758 | + self->priv->children = g_slist_append(self->priv->children, |
759 | + child_accessible); |
760 | + unity_launcher_icon_accessible_set_index(UNITY_LAUNCHER_ICON_ACCESSIBLE(child_accessible), |
761 | + index++); |
762 | + } |
763 | +} |
764 | |
765 | === added file 'plugins/unityshell/src/unity-switcher-accessible.h' |
766 | --- plugins/unityshell/src/unity-switcher-accessible.h 1970-01-01 00:00:00 +0000 |
767 | +++ plugins/unityshell/src/unity-switcher-accessible.h 2011-11-07 22:37:27 +0000 |
768 | @@ -0,0 +1,57 @@ |
769 | +/* |
770 | + * Copyright (C) 2011 Canonical Ltd |
771 | + * |
772 | + * This program is free software: you can redistribute it and/or modify |
773 | + * it under the terms of the GNU General Public License version 3 as |
774 | + * published by the Free Software Foundation. |
775 | + * |
776 | + * This program is distributed in the hope that it will be useful, |
777 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
778 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
779 | + * GNU General Public License for more details. |
780 | + * |
781 | + * You should have received a copy of the GNU General Public License |
782 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
783 | + * |
784 | + * Authored by: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> |
785 | + */ |
786 | + |
787 | +#ifndef UNITY_SWITCHER_ACCESSIBLE_H |
788 | +#define UNITY_SWITCHER_ACCESSIBLE_H |
789 | + |
790 | +#include <atk/atk.h> |
791 | + |
792 | +#include "nux-view-accessible.h" |
793 | + |
794 | +G_BEGIN_DECLS |
795 | + |
796 | +#define UNITY_TYPE_SWITCHER_ACCESSIBLE (unity_switcher_accessible_get_type ()) |
797 | +#define UNITY_SWITCHER_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_SWITCHER_ACCESSIBLE, UnitySwitcherAccessible)) |
798 | +#define UNITY_SWITCHER_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_SWITCHER_ACCESSIBLE, UnitySwitcherAccessibleClass)) |
799 | +#define UNITY_IS_SWITCHER_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_SWITCHER_ACCESSIBLE)) |
800 | +#define UNITY_IS_SWITCHER_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_SWITCHER_ACCESSIBLE)) |
801 | +#define UNITY_SWITCHER_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_SWITCHER_ACCESSIBLE, UnitySwitcherAccessibleClass)) |
802 | + |
803 | +typedef struct _UnitySwitcherAccessible UnitySwitcherAccessible; |
804 | +typedef struct _UnitySwitcherAccessibleClass UnitySwitcherAccessibleClass; |
805 | +typedef struct _UnitySwitcherAccessiblePrivate UnitySwitcherAccessiblePrivate; |
806 | + |
807 | +struct _UnitySwitcherAccessible |
808 | +{ |
809 | + NuxViewAccessible parent; |
810 | + |
811 | + /*< private >*/ |
812 | + UnitySwitcherAccessiblePrivate* priv; |
813 | +}; |
814 | + |
815 | +struct _UnitySwitcherAccessibleClass |
816 | +{ |
817 | + NuxViewAccessibleClass parent_class; |
818 | +}; |
819 | + |
820 | +GType unity_switcher_accessible_get_type(void); |
821 | +AtkObject* unity_switcher_accessible_new(nux::Object* object); |
822 | + |
823 | +G_END_DECLS |
824 | + |
825 | +#endif /* __UNITY_SWITCHER_ACCESSIBLE_H__ */ |
826 | |
827 | === modified file 'plugins/unityshell/src/unitya11y.cpp' |
828 | --- plugins/unityshell/src/unitya11y.cpp 2011-11-07 22:37:27 +0000 |
829 | +++ plugins/unityshell/src/unitya11y.cpp 2011-11-07 22:37:27 +0000 |
830 | @@ -41,6 +41,7 @@ |
831 | #include "PlacesGroup.h" |
832 | #include "QuicklistView.h" |
833 | #include "QuicklistMenuItem.h" |
834 | +#include "SwitcherView.h" |
835 | #include "unity-launcher-accessible.h" |
836 | #include "unity-launcher-icon-accessible.h" |
837 | #include "unity-panel-view-accessible.h" |
838 | @@ -52,6 +53,7 @@ |
839 | #include "unity-places-group-accessible.h" |
840 | #include "unity-quicklist-accessible.h" |
841 | #include "unity-quicklist-menu-item-accessible.h" |
842 | +#include "unity-switcher-accessible.h" |
843 | |
844 | using namespace unity; |
845 | using namespace unity::dash; |
846 | @@ -300,6 +302,9 @@ |
847 | if (object->Type().IsDerivedFromType(unity::dash::SearchBar::StaticObjectType)) |
848 | return unity_search_bar_accessible_new(object); |
849 | |
850 | + if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType)) |
851 | + return unity_switcher_accessible_new(object); |
852 | + |
853 | /* NUX classes */ |
854 | if (object->Type().IsDerivedFromType(nux::TextEntry::StaticObjectType)) |
855 | return nux_text_entry_accessible_new(object); |
BTW, this branch is already being tested by the users, as it is included on this branch:
https:/ /launchpad. net/~apinheiro/ +archive/ unity-extra- a11y
I already received some positive feedback from ubuntu- accessibility mailing list