Bug 1869092 - Fix timeouts in browser_PanelMultiView.js. r=twisniewski,test-only
[gecko.git] / accessible / atk / nsMaiInterfaceComponent.cpp
blob81e82a8f5316da17be122bb6a6a4c481f02da5fb
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 "InterfaceInitFuncs.h"
9 #include "LocalAccessible-inl.h"
10 #include "AccessibleWrap.h"
11 #include "nsAccUtils.h"
12 #include "nsMai.h"
13 #include "nsWindow.h"
14 #include "mozilla/Likely.h"
15 #include "mozilla/a11y/DocAccessibleParent.h"
16 #include "mozilla/a11y/RemoteAccessible.h"
17 #include "mozilla/dom/BrowserParent.h"
18 #include "mozilla/dom/Document.h"
19 #include "nsAccessibilityService.h"
21 using namespace mozilla;
22 using namespace mozilla::a11y;
24 extern "C" {
26 static AtkObject* refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX,
27 gint aAccY, AtkCoordType aCoordType) {
28 return refAccessibleAtPointHelper(ATK_OBJECT(aComponent), aAccX, aAccY,
29 aCoordType);
32 static void getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
33 gint* aWidth, gint* aHeight, AtkCoordType aCoordType) {
34 getExtentsHelper(ATK_OBJECT(aComponent), aX, aY, aWidth, aHeight, aCoordType);
37 static gboolean grabFocusCB(AtkComponent* aComponent) {
38 AtkObject* atkObject = ATK_OBJECT(aComponent);
39 Accessible* acc = GetInternalObj(atkObject);
40 if (acc) {
41 acc->TakeFocus();
42 return TRUE;
44 return FALSE;
47 // ScrollType is compatible
48 MOZ_CAN_RUN_SCRIPT_BOUNDARY
49 static gboolean scrollToCB(AtkComponent* aComponent, AtkScrollType type) {
50 AtkObject* atkObject = ATK_OBJECT(aComponent);
51 if (Accessible* acc = GetInternalObj(atkObject)) {
52 acc->ScrollTo(type);
53 return TRUE;
56 return FALSE;
59 // CoordType is compatible
60 static gboolean scrollToPointCB(AtkComponent* aComponent, AtkCoordType coords,
61 gint x, gint y) {
62 AtkObject* atkObject = ATK_OBJECT(aComponent);
63 AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
64 if (accWrap) {
65 accWrap->ScrollToPoint(coords, x, y);
66 return TRUE;
69 RemoteAccessible* proxy = GetProxy(atkObject);
70 if (proxy) {
71 proxy->ScrollToPoint(coords, x, y);
72 return TRUE;
75 return FALSE;
79 AtkObject* refAccessibleAtPointHelper(AtkObject* aAtkObj, gint aX, gint aY,
80 AtkCoordType aCoordType) {
81 Accessible* acc = GetInternalObj(aAtkObj);
82 if (!acc) {
83 return nullptr;
86 // Accessible::ChildAtPoint(x,y) is in screen pixels.
87 if (aCoordType == ATK_XY_WINDOW) {
88 mozilla::LayoutDeviceIntPoint winCoords =
89 nsAccUtils::GetScreenCoordsForWindow(acc);
90 aX += winCoords.x;
91 aY += winCoords.y;
94 Accessible* accAtPoint =
95 acc->ChildAtPoint(aX, aY, Accessible::EWhichChildAtPoint::DeepestChild);
96 if (!accAtPoint) {
97 return nullptr;
99 roles::Role role = accAtPoint->Role();
100 if (role == roles::TEXT_LEAF || role == roles::STATICTEXT) {
101 // We don't include text leaf nodes in the ATK tree, so return the parent.
102 accAtPoint = accAtPoint->Parent();
103 MOZ_ASSERT(accAtPoint, "Text leaf should always have a parent");
105 AtkObject* atkObj = GetWrapperFor(accAtPoint);
106 if (atkObj) {
107 g_object_ref(atkObj);
109 return atkObj;
112 static double getScaleFactor(Accessible* aAccessible) {
113 DocAccessible* docAcc = nullptr;
114 if (LocalAccessible* localAcc = aAccessible->AsLocal()) {
115 docAcc = localAcc->Document();
116 } else {
117 RemoteAccessible* remote = aAccessible->AsRemote();
118 LocalAccessible* outerDoc = remote->OuterDocOfRemoteBrowser();
119 if (outerDoc) {
120 docAcc = outerDoc->Document();
124 if (!docAcc || !docAcc->DocumentNode()) {
125 return 1.0;
128 nsCOMPtr<nsIWidget> rootWidget =
129 nsContentUtils::WidgetForDocument(docAcc->DocumentNode());
130 if (!rootWidget) {
131 return 1.0;
134 if (RefPtr<nsWindow> window =
135 static_cast<nsWindow*>(rootWidget->GetTopLevelWidget())) {
136 return window->FractionalScaleFactor();
139 return 1.0;
142 void getExtentsHelper(AtkObject* aAtkObj, gint* aX, gint* aY, gint* aWidth,
143 gint* aHeight, AtkCoordType aCoordType) {
144 *aX = *aY = *aWidth = *aHeight = -1;
146 Accessible* acc = GetInternalObj(aAtkObj);
147 if (!acc) {
148 return;
151 mozilla::LayoutDeviceIntRect screenRect = acc->Bounds();
152 if (screenRect.IsEmpty()) {
153 return;
156 if (aCoordType == ATK_XY_WINDOW) {
157 mozilla::LayoutDeviceIntPoint winCoords =
158 nsAccUtils::GetScreenCoordsForWindow(acc);
159 screenRect.x -= winCoords.x;
160 screenRect.y -= winCoords.y;
163 double scaleFactor = getScaleFactor(acc);
165 *aX = screenRect.x / scaleFactor;
166 *aY = screenRect.y / scaleFactor;
167 *aWidth = screenRect.width / scaleFactor;
168 *aHeight = screenRect.height / scaleFactor;
171 void componentInterfaceInitCB(AtkComponentIface* aIface) {
172 NS_ASSERTION(aIface, "Invalid Interface");
173 if (MOZ_UNLIKELY(!aIface)) return;
176 * Use default implementation in atk for contains, get_position,
177 * and get_size
179 aIface->ref_accessible_at_point = refAccessibleAtPointCB;
180 aIface->get_extents = getExtentsCB;
181 aIface->grab_focus = grabFocusCB;
182 if (IsAtkVersionAtLeast(2, 30)) {
183 aIface->scroll_to = scrollToCB;
184 aIface->scroll_to_point = scrollToPointCB;