Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/accessibility/browser_accessibility_gtk.h" | 5 #include "content/browser/accessibility/browser_accessibility_gtk.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "content/browser/accessibility/browser_accessibility_manager_gtk.h" | 10 #include "content/browser/accessibility/browser_accessibility_manager_gtk.h" |
| 11 #include "content/common/accessibility_messages.h" | 11 #include "content/common/accessibility_messages.h" |
| 12 | 12 |
| 13 namespace content { | 13 namespace content { |
| 14 | 14 |
| 15 // The maximum length of an autogenerated unique type name string, | |
| 16 // generated from the 16-bit interface mask from an AtkObject. | |
| 17 // 30 is enough for the prefix "WAIType" + 5 hex chars (max) */ | |
| 18 static const int kWAITypeNameLen = 30; | |
| 19 | |
| 20 static gpointer browser_accessibility_parent_class = NULL; | 15 static gpointer browser_accessibility_parent_class = NULL; |
| 21 | 16 |
| 22 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( | 17 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( |
| 23 BrowserAccessibilityAtk* atk_object) { | 18 BrowserAccessibilityAtk* atk_object) { |
| 24 if (!atk_object) | 19 if (!atk_object) |
| 25 return NULL; | 20 return NULL; |
| 26 | 21 |
| 27 return atk_object->m_object; | 22 return atk_object->m_object; |
| 28 } | 23 } |
| 29 | 24 |
| 25 // | |
| 26 // AtkComponent interface. | |
| 27 // | |
| 28 | |
| 29 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( | |
| 30 AtkComponent* atk_object) { | |
| 31 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) | |
| 32 return NULL; | |
| 33 | |
| 34 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); | |
| 35 } | |
| 36 | |
| 37 static AtkObject* browser_accessibility_accessible_at_point( | |
| 38 AtkComponent* component, gint x, gint y, AtkCoordType coord_type) { | |
| 39 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component); | |
| 40 if (!obj) | |
| 41 return 0; | |
|
aboxhall
2013/07/29 22:23:09
Why return 0 instead of NULL here?
dmazzoni
2013/07/29 22:34:28
Done.
| |
| 42 | |
| 43 gfx::Point point(x, y); | |
| 44 if (!obj->GetGlobalBoundsRect().Contains(point)) | |
| 45 return NULL; | |
| 46 | |
| 47 BrowserAccessibility* result = obj->BrowserAccessibilityForPoint(point); | |
| 48 if (!result) | |
| 49 return NULL; | |
| 50 | |
| 51 AtkObject* atk_result = result->ToBrowserAccessibilityGtk()->GetAtkObject(); | |
| 52 g_object_ref(atk_result); | |
| 53 return atk_result; | |
| 54 } | |
| 55 | |
| 56 static void browser_accessibility_get_extents( | |
| 57 AtkComponent* component, gint* x, gint* y, gint* width, gint* height, | |
| 58 AtkCoordType coord_type) { | |
| 59 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component); | |
| 60 if (!obj) | |
| 61 return; | |
| 62 | |
| 63 gfx::Rect bounds = obj->GetGlobalBoundsRect(); | |
|
aboxhall
2013/07/29 22:23:09
Does bounds need any sanity (null) checking?
dmazzoni
2013/07/29 22:34:28
Not needed, it's just a struct.
| |
| 64 *x = bounds.x(); | |
| 65 *y = bounds.y(); | |
| 66 *width = bounds.width(); | |
| 67 *height = bounds.height(); | |
| 68 } | |
| 69 | |
| 70 static gboolean browser_accessibility_grab_focus(AtkComponent* component) { | |
| 71 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component); | |
| 72 if (!obj) | |
| 73 return false; | |
| 74 | |
| 75 obj->manager()->SetFocus(obj, true); | |
| 76 return true; | |
| 77 } | |
| 78 | |
| 79 static void ComponentInterfaceInit(AtkComponentIface* iface) { | |
| 80 iface->ref_accessible_at_point = browser_accessibility_accessible_at_point; | |
| 81 iface->get_extents = browser_accessibility_get_extents; | |
| 82 iface->grab_focus = browser_accessibility_grab_focus; | |
| 83 } | |
| 84 | |
| 85 static const GInterfaceInfo ComponentInfo = { | |
| 86 reinterpret_cast<GInterfaceInitFunc>(ComponentInterfaceInit), 0, 0 | |
| 87 }; | |
| 88 | |
| 89 // | |
| 90 // AtkValue interface. | |
| 91 // | |
| 92 | |
| 93 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( | |
| 94 AtkValue* atk_object) { | |
| 95 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) | |
| 96 return NULL; | |
| 97 | |
| 98 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); | |
| 99 } | |
| 100 | |
| 101 static void browser_accessibility_get_current_value( | |
| 102 AtkValue* atk_object, GValue* value) { | |
| 103 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); | |
| 104 if (!obj) | |
| 105 return; | |
| 106 | |
| 107 float float_val; | |
| 108 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_VALUE_FOR_RANGE, | |
| 109 &float_val)) { | |
| 110 memset(value, 0, sizeof(value)); | |
| 111 g_value_init(value, G_TYPE_FLOAT); | |
| 112 g_value_set_float(value, float_val); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 static void browser_accessibility_get_minimum_value( | |
| 117 AtkValue* atk_object, GValue* value) { | |
| 118 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); | |
| 119 if (!obj) | |
| 120 return; | |
| 121 | |
| 122 float float_val; | |
| 123 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MIN_VALUE_FOR_RANGE, | |
| 124 &float_val)) { | |
| 125 memset(value, 0, sizeof(value)); | |
| 126 g_value_init(value, G_TYPE_FLOAT); | |
| 127 g_value_set_float(value, float_val); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 static void browser_accessibility_get_maximum_value( | |
| 132 AtkValue* atk_object, GValue* value) { | |
| 133 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); | |
| 134 if (!obj) | |
| 135 return; | |
| 136 | |
| 137 float float_val; | |
| 138 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MAX_VALUE_FOR_RANGE, | |
| 139 &float_val)) { | |
| 140 memset(value, 0, sizeof(value)); | |
| 141 g_value_init(value, G_TYPE_FLOAT); | |
| 142 g_value_set_float(value, float_val); | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 static void browser_accessibility_get_minimum_increment( | |
| 147 AtkValue* atk_object, GValue* value) { | |
| 148 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); | |
|
aboxhall
2013/07/29 22:23:09
obj isn't used below; do we still need this check?
dmazzoni
2013/07/29 22:34:28
Done.
| |
| 149 if (!obj) | |
| 150 return; | |
| 151 | |
| 152 memset(value, 0, sizeof(value)); | |
| 153 g_value_init(value, G_TYPE_FLOAT); | |
| 154 g_value_set_float(value, 1.0); | |
|
aboxhall
2013/07/29 22:23:09
Is this always correct?
dmazzoni
2013/07/29 22:34:28
No. I added a TODO; I believe the other platforms
| |
| 155 } | |
| 156 | |
| 157 static void ValueInterfaceInit(AtkValueIface* iface) { | |
| 158 iface->get_current_value = browser_accessibility_get_current_value; | |
| 159 iface->get_minimum_value = browser_accessibility_get_minimum_value; | |
| 160 iface->get_maximum_value = browser_accessibility_get_maximum_value; | |
| 161 iface->get_minimum_increment = browser_accessibility_get_minimum_increment; | |
| 162 } | |
| 163 | |
| 164 static const GInterfaceInfo ValueInfo = { | |
| 165 reinterpret_cast<GInterfaceInitFunc>(ValueInterfaceInit), 0, 0 | |
| 166 }; | |
| 167 | |
| 168 // | |
| 169 // AtkObject interface | |
| 170 // | |
| 171 | |
| 30 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( | 172 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( |
| 31 AtkObject* atk_object) { | 173 AtkObject* atk_object) { |
| 32 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) | 174 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) |
| 33 return NULL; | 175 return NULL; |
| 34 | 176 |
| 35 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); | 177 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); |
| 36 } | 178 } |
| 37 | 179 |
| 38 static const gchar* browser_accessibility_get_name(AtkObject* atk_object) { | 180 static const gchar* browser_accessibility_get_name(AtkObject* atk_object) { |
| 39 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); | 181 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 } | 261 } |
| 120 | 262 |
| 121 static AtkRelationSet* browser_accessibility_ref_relation_set( | 263 static AtkRelationSet* browser_accessibility_ref_relation_set( |
| 122 AtkObject* atk_object) { | 264 AtkObject* atk_object) { |
| 123 AtkRelationSet* relation_set = | 265 AtkRelationSet* relation_set = |
| 124 ATK_OBJECT_CLASS(browser_accessibility_parent_class) | 266 ATK_OBJECT_CLASS(browser_accessibility_parent_class) |
| 125 ->ref_relation_set(atk_object); | 267 ->ref_relation_set(atk_object); |
| 126 return relation_set; | 268 return relation_set; |
| 127 } | 269 } |
| 128 | 270 |
| 271 // | |
| 272 // The rest of the BrowserAccessibilityGtk code, not specific to one | |
| 273 // of the Atk* interfaces. | |
| 274 // | |
| 275 | |
| 129 static void browser_accessibility_init(AtkObject* atk_object, gpointer data) { | 276 static void browser_accessibility_init(AtkObject* atk_object, gpointer data) { |
| 130 if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) { | 277 if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) { |
| 131 ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize( | 278 ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize( |
| 132 atk_object, data); | 279 atk_object, data); |
| 133 } | 280 } |
| 134 | 281 |
| 135 BROWSER_ACCESSIBILITY(atk_object)->m_object = | 282 BROWSER_ACCESSIBILITY(atk_object)->m_object = |
| 136 reinterpret_cast<BrowserAccessibilityGtk*>(data); | 283 reinterpret_cast<BrowserAccessibilityGtk*>(data); |
| 137 } | 284 } |
| 138 | 285 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 }; | 323 }; |
| 177 | 324 |
| 178 GType type = g_type_register_static( | 325 GType type = g_type_register_static( |
| 179 ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0)); | 326 ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0)); |
| 180 g_once_init_leave(&type_volatile, type); | 327 g_once_init_leave(&type_volatile, type); |
| 181 } | 328 } |
| 182 | 329 |
| 183 return type_volatile; | 330 return type_volatile; |
| 184 } | 331 } |
| 185 | 332 |
| 186 static guint16 GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) { | 333 static const char* GetUniqueAccessibilityTypeName(int interface_mask) |
| 187 return 0; | |
| 188 } | |
| 189 | |
| 190 static const char* GetUniqueAccessibilityTypeName(guint16 interface_mask) | |
| 191 { | 334 { |
| 192 static char name[kWAITypeNameLen + 1]; | 335 // 20 characters is enough for "Chrome%x" with any conceivable integer. |
|
aboxhall
2013/07/29 22:23:09
What does 'conceivable' mean here?
dmazzoni
2013/07/29 22:34:28
Done.
| |
| 193 | 336 static char name[20]; |
| 194 sprintf(name, "WAIType%x", interface_mask); | 337 snprintf(name, sizeof(name), "Chrome%x", interface_mask); |
| 195 name[kWAITypeNameLen] = '\0'; | |
| 196 | |
| 197 return name; | 338 return name; |
| 198 } | 339 } |
| 199 | 340 |
| 200 static const GInterfaceInfo AtkInterfacesInitFunctions[] = { | 341 enum AtkInterfaces { |
| 342 ATK_ACTION_INTERFACE, | |
| 343 ATK_COMPONENT_INTERFACE, | |
| 344 ATK_DOCUMENT_INTERFACE, | |
| 345 ATK_EDITABLE_TEXT_INTERFACE, | |
| 346 ATK_HYPERLINK_INTERFACE, | |
| 347 ATK_HYPERTEXT_INTERFACE, | |
| 348 ATK_IMAGE_INTERFACE, | |
| 349 ATK_SELECTION_INTERFACE, | |
| 350 ATK_TABLE_INTERFACE, | |
| 351 ATK_TEXT_INTERFACE, | |
| 352 ATK_VALUE_INTERFACE, | |
| 201 }; | 353 }; |
| 202 | 354 |
| 203 enum WAIType { | 355 static int GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) { |
| 204 WAI_ACTION, | 356 int interface_mask = 0; |
| 205 WAI_SELECTION, | |
| 206 WAI_EDITABLE_TEXT, | |
| 207 WAI_TEXT, | |
| 208 WAI_COMPONENT, | |
| 209 WAI_IMAGE, | |
| 210 WAI_TABLE, | |
| 211 WAI_HYPERTEXT, | |
| 212 WAI_HYPERLINK, | |
| 213 WAI_DOCUMENT, | |
| 214 WAI_VALUE, | |
| 215 }; | |
| 216 | 357 |
| 217 static GType GetAtkInterfaceTypeFromWAIType(WAIType type) { | 358 // Component interface is always supported. |
| 218 switch (type) { | 359 interface_mask |= 1 << ATK_COMPONENT_INTERFACE; |
| 219 case WAI_ACTION: | 360 |
| 220 return ATK_TYPE_ACTION; | 361 int role = obj->role(); |
| 221 case WAI_SELECTION: | 362 if (role == AccessibilityNodeData::ROLE_PROGRESS_INDICATOR || |
|
aboxhall
2013/07/29 22:23:09
So we'll need to go through each of the roles and
dmazzoni
2013/07/29 22:34:28
Yes. Usually it's pretty easy; for example the TAB
| |
| 222 return ATK_TYPE_SELECTION; | 363 role == AccessibilityNodeData::ROLE_SCROLLBAR || |
| 223 case WAI_EDITABLE_TEXT: | 364 role == AccessibilityNodeData::ROLE_SLIDER) { |
| 224 return ATK_TYPE_EDITABLE_TEXT; | 365 interface_mask |= 1 << ATK_VALUE_INTERFACE; |
| 225 case WAI_TEXT: | |
| 226 return ATK_TYPE_TEXT; | |
| 227 case WAI_COMPONENT: | |
| 228 return ATK_TYPE_COMPONENT; | |
| 229 case WAI_IMAGE: | |
| 230 return ATK_TYPE_IMAGE; | |
| 231 case WAI_TABLE: | |
| 232 return ATK_TYPE_TABLE; | |
| 233 case WAI_HYPERTEXT: | |
| 234 return ATK_TYPE_HYPERTEXT; | |
| 235 case WAI_HYPERLINK: | |
| 236 return ATK_TYPE_HYPERLINK_IMPL; | |
| 237 case WAI_DOCUMENT: | |
| 238 return ATK_TYPE_DOCUMENT; | |
| 239 case WAI_VALUE: | |
| 240 return ATK_TYPE_VALUE; | |
| 241 } | 366 } |
| 242 | 367 |
| 243 return G_TYPE_INVALID; | 368 return interface_mask; |
| 244 } | 369 } |
| 245 | 370 |
| 246 static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) { | 371 static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) { |
| 247 static const GTypeInfo type_info = { | 372 static const GTypeInfo type_info = { |
| 248 sizeof(BrowserAccessibilityAtkClass), | 373 sizeof(BrowserAccessibilityAtkClass), |
| 249 (GBaseInitFunc) 0, | 374 (GBaseInitFunc) 0, |
| 250 (GBaseFinalizeFunc) 0, | 375 (GBaseFinalizeFunc) 0, |
| 251 (GClassInitFunc) 0, | 376 (GClassInitFunc) 0, |
| 252 (GClassFinalizeFunc) 0, | 377 (GClassFinalizeFunc) 0, |
| 253 0, /* class data */ | 378 0, /* class data */ |
| 254 sizeof(BrowserAccessibilityAtk), /* instance size */ | 379 sizeof(BrowserAccessibilityAtk), /* instance size */ |
| 255 0, /* nb preallocs */ | 380 0, /* nb preallocs */ |
| 256 (GInstanceInitFunc) 0, | 381 (GInstanceInitFunc) 0, |
| 257 0 /* value table */ | 382 0 /* value table */ |
| 258 }; | 383 }; |
| 259 | 384 |
| 260 guint16 interface_mask = GetInterfaceMaskFromObject(obj); | 385 int interface_mask = GetInterfaceMaskFromObject(obj); |
| 261 const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask); | 386 const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask); |
| 262 GType type = g_type_from_name(atk_type_name); | 387 GType type = g_type_from_name(atk_type_name); |
| 263 if (type) | 388 if (type) |
| 264 return type; | 389 return type; |
| 265 | 390 |
| 266 type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, | 391 type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, |
| 267 atk_type_name, | 392 atk_type_name, |
| 268 &type_info, | 393 &type_info, |
| 269 GTypeFlags(0)); | 394 GTypeFlags(0)); |
| 270 for (guint i = 0; i < G_N_ELEMENTS(AtkInterfacesInitFunctions); i++) { | 395 if (interface_mask & (1 << ATK_COMPONENT_INTERFACE)) |
| 271 if (interface_mask & (1 << i)) { | 396 g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo); |
| 272 g_type_add_interface_static( | 397 if (interface_mask & (1 << ATK_VALUE_INTERFACE)) |
| 273 type, | 398 g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo); |
| 274 GetAtkInterfaceTypeFromWAIType(static_cast<WAIType>(i)), | |
| 275 &AtkInterfacesInitFunctions[i]); | |
| 276 } | |
| 277 } | |
| 278 | 399 |
| 279 return type; | 400 return type; |
| 280 } | 401 } |
| 281 | 402 |
| 282 BrowserAccessibilityAtk* browser_accessibility_new( | 403 BrowserAccessibilityAtk* browser_accessibility_new( |
| 283 BrowserAccessibilityGtk* obj) { | 404 BrowserAccessibilityGtk* obj) { |
| 284 GType type = GetAccessibilityTypeFromObject(obj); | 405 GType type = GetAccessibilityTypeFromObject(obj); |
| 285 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0)); | 406 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0)); |
| 286 | 407 |
| 287 atk_object_initialize(atk_object, obj); | 408 atk_object_initialize(atk_object, obj); |
| 288 | 409 |
| 289 return BROWSER_ACCESSIBILITY(atk_object); | 410 return BROWSER_ACCESSIBILITY(atk_object); |
| 290 } | 411 } |
| 291 | 412 |
| 292 void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) { | 413 void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) { |
| 293 atk_object->m_object = NULL; | 414 atk_object->m_object = NULL; |
| 294 } | 415 } |
| 295 | 416 |
| 296 // static | 417 // static |
| 297 BrowserAccessibility* BrowserAccessibility::Create() { | 418 BrowserAccessibility* BrowserAccessibility::Create() { |
| 298 return new BrowserAccessibilityGtk(); | 419 return new BrowserAccessibilityGtk(); |
| 299 } | 420 } |
| 300 | 421 |
| 301 BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() { | 422 BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() { |
| 302 return static_cast<BrowserAccessibilityGtk*>(this); | 423 return static_cast<BrowserAccessibilityGtk*>(this); |
| 303 } | 424 } |
| 304 | 425 |
| 305 BrowserAccessibilityGtk::BrowserAccessibilityGtk() { | 426 BrowserAccessibilityGtk::BrowserAccessibilityGtk() |
| 306 atk_object_ = ATK_OBJECT(browser_accessibility_new(this)); | 427 : atk_object_(NULL) { |
| 307 } | 428 } |
| 308 | 429 |
| 309 BrowserAccessibilityGtk::~BrowserAccessibilityGtk() { | 430 BrowserAccessibilityGtk::~BrowserAccessibilityGtk() { |
| 310 browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_)); | 431 browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_)); |
| 311 g_object_unref(atk_object_); | 432 if (atk_object_) |
| 433 g_object_unref(atk_object_); | |
| 312 } | 434 } |
| 313 | 435 |
| 314 AtkObject* BrowserAccessibilityGtk::GetAtkObject() const { | 436 AtkObject* BrowserAccessibilityGtk::GetAtkObject() const { |
| 315 if (!G_IS_OBJECT(atk_object_)) | 437 if (!G_IS_OBJECT(atk_object_)) |
| 316 return NULL; | 438 return NULL; |
| 317 return atk_object_; | 439 return atk_object_; |
| 318 } | 440 } |
| 319 | 441 |
| 320 void BrowserAccessibilityGtk::PreInitialize() { | 442 void BrowserAccessibilityGtk::PreInitialize() { |
| 321 BrowserAccessibility::PreInitialize(); | 443 BrowserAccessibility::PreInitialize(); |
| 322 InitRoleAndState(); | 444 InitRoleAndState(); |
| 323 | 445 |
| 324 if (this->parent()) { | 446 if (atk_object_) { |
| 325 atk_object_set_parent( | 447 // If the object's role changes and that causes its |
| 326 atk_object_, | 448 // interface mask to change, we need to create a new |
| 327 this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject()); | 449 // AtkObject for it. |
| 450 int interface_mask = GetInterfaceMaskFromObject(this); | |
| 451 if (interface_mask != interface_mask_) { | |
| 452 g_object_unref(atk_object_); | |
| 453 atk_object_ = NULL; | |
| 454 } | |
| 455 } | |
| 456 | |
| 457 if (!atk_object_) { | |
| 458 interface_mask_ = GetInterfaceMaskFromObject(this); | |
| 459 atk_object_ = ATK_OBJECT(browser_accessibility_new(this)); | |
| 460 if (this->parent()) { | |
| 461 atk_object_set_parent( | |
| 462 atk_object_, | |
| 463 this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject()); | |
| 464 } | |
| 328 } | 465 } |
| 329 } | 466 } |
| 330 | 467 |
| 331 bool BrowserAccessibilityGtk::IsNative() const { | 468 bool BrowserAccessibilityGtk::IsNative() const { |
| 332 return true; | 469 return true; |
| 333 } | 470 } |
| 334 | 471 |
| 335 void BrowserAccessibilityGtk::InitRoleAndState() { | 472 void BrowserAccessibilityGtk::InitRoleAndState() { |
| 336 atk_acc_name_ = UTF16ToUTF8(name()); | 473 atk_acc_name_ = UTF16ToUTF8(name()); |
| 337 | 474 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 case AccessibilityNodeData::ROLE_WEBCORE_LINK: | 513 case AccessibilityNodeData::ROLE_WEBCORE_LINK: |
| 377 atk_role_ = ATK_ROLE_LINK; | 514 atk_role_ = ATK_ROLE_LINK; |
| 378 break; | 515 break; |
| 379 default: | 516 default: |
| 380 atk_role_ = ATK_ROLE_UNKNOWN; | 517 atk_role_ = ATK_ROLE_UNKNOWN; |
| 381 break; | 518 break; |
| 382 } | 519 } |
| 383 } | 520 } |
| 384 | 521 |
| 385 } // namespace content | 522 } // namespace content |
| OLD | NEW |