Bug 1841050 - Disable webgl.gl_khr_no_error on Windows. r=gfx-reviewers,bradwerth
[gecko.git] / accessible / atk / ApplicationAccessibleWrap.cpp
blob4c3e615387dabf5884beea6c73d5a50a9c262321
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ApplicationAccessibleWrap.h"
9 #include "nsMai.h"
10 #include "nsAccessibilityService.h"
12 #include <gtk/gtk.h>
13 #include "atk/atkobject.h"
15 using namespace mozilla;
16 using namespace mozilla::a11y;
18 // ApplicationAccessibleWrap
20 ApplicationAccessibleWrap::ApplicationAccessibleWrap() = default;
22 ApplicationAccessibleWrap::~ApplicationAccessibleWrap() {
23 AccessibleWrap::ShutdownAtkObject();
26 gboolean toplevel_event_watcher(GSignalInvocationHint* ihint,
27 guint n_param_values,
28 const GValue* param_values, gpointer data) {
29 static GQuark sQuark_gecko_acc_obj = 0;
31 if (!sQuark_gecko_acc_obj) {
32 sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");
35 if (nsAccessibilityService::IsShutdown()) return TRUE;
37 GObject* object =
38 reinterpret_cast<GObject*>(g_value_get_object(param_values));
39 if (!GTK_IS_WINDOW(object)) return TRUE;
41 AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));
42 AtkRole role = atk_object_get_role(child);
44 // GTK native dialog
45 if (!IS_MAI_OBJECT(child) &&
46 (role == ATK_ROLE_DIALOG || role == ATK_ROLE_FILE_CHOOSER ||
47 role == ATK_ROLE_COLOR_CHOOSER || role == ATK_ROLE_FONT_CHOOSER)) {
48 if (data == reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW)) {
49 // Attach the dialog accessible to app accessible tree
50 LocalAccessible* windowAcc =
51 GetAccService()->AddNativeRootAccessible(child);
52 g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj,
53 reinterpret_cast<gpointer>(windowAcc));
55 } else {
56 // Deattach the dialog accessible
57 LocalAccessible* windowAcc = reinterpret_cast<LocalAccessible*>(
58 g_object_get_qdata(G_OBJECT(child), sQuark_gecko_acc_obj));
59 if (windowAcc) {
60 GetAccService()->RemoveNativeRootAccessible(windowAcc);
61 g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, nullptr);
66 return TRUE;
69 ENameValueFlag ApplicationAccessibleWrap::Name(nsString& aName) const {
70 // ATK doesn't provide a way to obtain an application name (for example,
71 // Firefox or Thunderbird) like IA2 does. Thus let's return an application
72 // name as accessible name that was used to get a branding name (for example,
73 // Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
74 AppName(aName);
75 return eNameOK;
78 void ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible) {
79 *aOutAccessible = nullptr;
81 if (!mAtkObject) {
82 mAtkObject = reinterpret_cast<AtkObject*>(
83 g_object_new(MAI_TYPE_ATK_OBJECT, nullptr));
84 if (!mAtkObject) return;
86 atk_object_initialize(mAtkObject, static_cast<Accessible*>(this));
87 mAtkObject->role = ATK_ROLE_INVALID;
88 mAtkObject->layer = ATK_LAYER_INVALID;
91 *aOutAccessible = mAtkObject;
94 struct AtkRootAccessibleAddedEvent {
95 AtkObject* app_accessible;
96 AtkObject* root_accessible;
97 uint32_t index;
100 gboolean fireRootAccessibleAddedCB(gpointer data) {
101 AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)data;
102 g_signal_emit_by_name(eventData->app_accessible, "children_changed::add",
103 eventData->index, eventData->root_accessible, nullptr);
104 g_object_unref(eventData->app_accessible);
105 g_object_unref(eventData->root_accessible);
106 free(data);
108 return FALSE;
111 bool ApplicationAccessibleWrap::InsertChildAt(uint32_t aIdx,
112 LocalAccessible* aChild) {
113 if (!ApplicationAccessible::InsertChildAt(aIdx, aChild)) return false;
115 AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
116 atk_object_set_parent(atkAccessible, mAtkObject);
118 uint32_t count = mChildren.Length();
120 // Emit children_changed::add in a timeout
121 // to make sure aRootAccWrap is fully initialized.
122 AtkRootAccessibleAddedEvent* eventData =
123 (AtkRootAccessibleAddedEvent*)malloc(sizeof(AtkRootAccessibleAddedEvent));
124 if (eventData) {
125 eventData->app_accessible = mAtkObject;
126 eventData->root_accessible = atkAccessible;
127 eventData->index = count - 1;
128 g_object_ref(mAtkObject);
129 g_object_ref(atkAccessible);
130 g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
133 return true;
136 bool ApplicationAccessibleWrap::RemoveChild(LocalAccessible* aChild) {
137 int32_t index = aChild->IndexInParent();
139 AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
140 atk_object_set_parent(atkAccessible, nullptr);
141 g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
142 atkAccessible, nullptr);
144 return ApplicationAccessible::RemoveChild(aChild);