accessible/src/atk/ApplicationAccessibleWrap.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "ApplicationAccessibleWrap.h"
michael@0 8
michael@0 9 #include "nsCOMPtr.h"
michael@0 10 #include "nsMai.h"
michael@0 11 #include "nsAutoPtr.h"
michael@0 12 #include "nsAccessibilityService.h"
michael@0 13
michael@0 14 #include <gtk/gtk.h>
michael@0 15 #include <atk/atk.h>
michael@0 16
michael@0 17 using namespace mozilla;
michael@0 18 using namespace mozilla::a11y;
michael@0 19
michael@0 20
michael@0 21 // ApplicationAccessibleWrap
michael@0 22
michael@0 23 ApplicationAccessibleWrap::ApplicationAccessibleWrap():
michael@0 24 ApplicationAccessible()
michael@0 25 {
michael@0 26 }
michael@0 27
michael@0 28 ApplicationAccessibleWrap::~ApplicationAccessibleWrap()
michael@0 29 {
michael@0 30 AccessibleWrap::ShutdownAtkObject();
michael@0 31 }
michael@0 32
michael@0 33 gboolean
michael@0 34 toplevel_event_watcher(GSignalInvocationHint* ihint,
michael@0 35 guint n_param_values,
michael@0 36 const GValue* param_values,
michael@0 37 gpointer data)
michael@0 38 {
michael@0 39 static GQuark sQuark_gecko_acc_obj = 0;
michael@0 40
michael@0 41 if (!sQuark_gecko_acc_obj)
michael@0 42 sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");
michael@0 43
michael@0 44 if (nsAccessibilityService::IsShutdown())
michael@0 45 return TRUE;
michael@0 46
michael@0 47 GObject* object = reinterpret_cast<GObject*>(g_value_get_object(param_values));
michael@0 48 if (!GTK_IS_WINDOW(object))
michael@0 49 return TRUE;
michael@0 50
michael@0 51 AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));
michael@0 52
michael@0 53 // GTK native dialog
michael@0 54 if (!IS_MAI_OBJECT(child) &&
michael@0 55 (atk_object_get_role(child) == ATK_ROLE_DIALOG)) {
michael@0 56
michael@0 57 if (data == reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW)) {
michael@0 58
michael@0 59 // Attach the dialog accessible to app accessible tree
michael@0 60 Accessible* windowAcc = GetAccService()->AddNativeRootAccessible(child);
michael@0 61 g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj,
michael@0 62 reinterpret_cast<gpointer>(windowAcc));
michael@0 63
michael@0 64 } else {
michael@0 65
michael@0 66 // Deattach the dialog accessible
michael@0 67 Accessible* windowAcc =
michael@0 68 reinterpret_cast<Accessible*>
michael@0 69 (g_object_get_qdata(G_OBJECT(child), sQuark_gecko_acc_obj));
michael@0 70 if (windowAcc) {
michael@0 71 GetAccService()->RemoveNativeRootAccessible(windowAcc);
michael@0 72 g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, nullptr);
michael@0 73 }
michael@0 74
michael@0 75 }
michael@0 76 }
michael@0 77
michael@0 78 return TRUE;
michael@0 79 }
michael@0 80
michael@0 81 ENameValueFlag
michael@0 82 ApplicationAccessibleWrap::Name(nsString& aName)
michael@0 83 {
michael@0 84 // ATK doesn't provide a way to obtain an application name (for example,
michael@0 85 // Firefox or Thunderbird) like IA2 does. Thus let's return an application
michael@0 86 // name as accessible name that was used to get a branding name (for example,
michael@0 87 // Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
michael@0 88 GetAppName(aName);
michael@0 89 return eNameOK;
michael@0 90 }
michael@0 91
michael@0 92 NS_IMETHODIMP
michael@0 93 ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
michael@0 94 {
michael@0 95 *aOutAccessible = nullptr;
michael@0 96
michael@0 97 if (!mAtkObject) {
michael@0 98 mAtkObject =
michael@0 99 reinterpret_cast<AtkObject *>
michael@0 100 (g_object_new(MAI_TYPE_ATK_OBJECT, nullptr));
michael@0 101 NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
michael@0 102
michael@0 103 atk_object_initialize(mAtkObject, this);
michael@0 104 mAtkObject->role = ATK_ROLE_INVALID;
michael@0 105 mAtkObject->layer = ATK_LAYER_INVALID;
michael@0 106 }
michael@0 107
michael@0 108 *aOutAccessible = mAtkObject;
michael@0 109 return NS_OK;
michael@0 110 }
michael@0 111
michael@0 112 struct AtkRootAccessibleAddedEvent {
michael@0 113 AtkObject *app_accessible;
michael@0 114 AtkObject *root_accessible;
michael@0 115 uint32_t index;
michael@0 116 };
michael@0 117
michael@0 118 gboolean fireRootAccessibleAddedCB(gpointer data)
michael@0 119 {
michael@0 120 AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)data;
michael@0 121 g_signal_emit_by_name(eventData->app_accessible, "children_changed::add",
michael@0 122 eventData->index, eventData->root_accessible, nullptr);
michael@0 123 g_object_unref(eventData->app_accessible);
michael@0 124 g_object_unref(eventData->root_accessible);
michael@0 125 free(data);
michael@0 126
michael@0 127 return FALSE;
michael@0 128 }
michael@0 129
michael@0 130 bool
michael@0 131 ApplicationAccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aChild)
michael@0 132 {
michael@0 133 if (!ApplicationAccessible::InsertChildAt(aIdx, aChild))
michael@0 134 return false;
michael@0 135
michael@0 136 AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
michael@0 137 atk_object_set_parent(atkAccessible, mAtkObject);
michael@0 138
michael@0 139 uint32_t count = mChildren.Length();
michael@0 140
michael@0 141 // Emit children_changed::add in a timeout
michael@0 142 // to make sure aRootAccWrap is fully initialized.
michael@0 143 AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)
michael@0 144 malloc(sizeof(AtkRootAccessibleAddedEvent));
michael@0 145 if (eventData) {
michael@0 146 eventData->app_accessible = mAtkObject;
michael@0 147 eventData->root_accessible = atkAccessible;
michael@0 148 eventData->index = count -1;
michael@0 149 g_object_ref(mAtkObject);
michael@0 150 g_object_ref(atkAccessible);
michael@0 151 g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
michael@0 152 }
michael@0 153
michael@0 154 return true;
michael@0 155 }
michael@0 156
michael@0 157 bool
michael@0 158 ApplicationAccessibleWrap::RemoveChild(Accessible* aChild)
michael@0 159 {
michael@0 160 int32_t index = aChild->IndexInParent();
michael@0 161
michael@0 162 AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
michael@0 163 atk_object_set_parent(atkAccessible, nullptr);
michael@0 164 g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
michael@0 165 atkAccessible, nullptr);
michael@0 166
michael@0 167 return ApplicationAccessible::RemoveChild(aChild);
michael@0 168 }
michael@0 169

mercurial