accessible/atk/ApplicationAccessibleWrap.cpp
author Nathan Froyd <froydnj@mozilla.com>
Wed, 07 Oct 2015 16:50:25 -0400
changeset 287061 91d4539e00cecb658604e021675a923c60ef3235
parent 223892 ef5d07a500fdb98ce847a637bc50f65174a599cc
child 328780 232a786cf87fb0f68f9bda6e9316515524d2ac8a
permissions -rw-r--r--
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "ApplicationAccessibleWrap.h"

#include "nsCOMPtr.h"
#include "nsMai.h"
#include "nsAutoPtr.h"
#include "nsAccessibilityService.h"

#include <gtk/gtk.h>
#include <atk/atk.h>

using namespace mozilla;
using namespace mozilla::a11y;


// ApplicationAccessibleWrap

ApplicationAccessibleWrap::ApplicationAccessibleWrap():
  ApplicationAccessible()
{
}

ApplicationAccessibleWrap::~ApplicationAccessibleWrap()
{
  AccessibleWrap::ShutdownAtkObject();
}

gboolean
toplevel_event_watcher(GSignalInvocationHint* ihint,
                       guint                  n_param_values,
                       const GValue*          param_values,
                       gpointer               data)
{
  static GQuark sQuark_gecko_acc_obj = 0;

  if (!sQuark_gecko_acc_obj)
    sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");

  if (nsAccessibilityService::IsShutdown())
    return TRUE;

  GObject* object = reinterpret_cast<GObject*>(g_value_get_object(param_values));
  if (!GTK_IS_WINDOW(object))
    return TRUE;

  AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));

  // GTK native dialog
  if (!IS_MAI_OBJECT(child) &&
      (atk_object_get_role(child) == ATK_ROLE_DIALOG)) {

    if (data == reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW)) {

      // Attach the dialog accessible to app accessible tree
      Accessible* windowAcc = GetAccService()->AddNativeRootAccessible(child);
      g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj,
                         reinterpret_cast<gpointer>(windowAcc));

    } else {

      // Deattach the dialog accessible
      Accessible* windowAcc =
        reinterpret_cast<Accessible*>
                        (g_object_get_qdata(G_OBJECT(child), sQuark_gecko_acc_obj));
      if (windowAcc) {
        GetAccService()->RemoveNativeRootAccessible(windowAcc);
        g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, nullptr);
      }

    }
  }

  return TRUE;
}

ENameValueFlag
ApplicationAccessibleWrap::Name(nsString& aName)
{
  // ATK doesn't provide a way to obtain an application name (for example,
  // Firefox or Thunderbird) like IA2 does. Thus let's return an application
  // name as accessible name that was used to get a branding name (for example,
  // Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
  AppName(aName);
  return eNameOK;
}

void
ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
{
  *aOutAccessible = nullptr;

  if (!mAtkObject) {
    mAtkObject =
      reinterpret_cast<AtkObject*>(g_object_new(MAI_TYPE_ATK_OBJECT, nullptr));
    if (!mAtkObject)
      return;

    atk_object_initialize(mAtkObject, this);
    mAtkObject->role = ATK_ROLE_INVALID;
    mAtkObject->layer = ATK_LAYER_INVALID;
  }

  *aOutAccessible = mAtkObject;
}

struct AtkRootAccessibleAddedEvent {
  AtkObject *app_accessible;
  AtkObject *root_accessible;
  uint32_t index;
};

gboolean fireRootAccessibleAddedCB(gpointer data)
{
    AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)data;
    g_signal_emit_by_name(eventData->app_accessible, "children_changed::add",
                          eventData->index, eventData->root_accessible, nullptr);
    g_object_unref(eventData->app_accessible);
    g_object_unref(eventData->root_accessible);
    free(data);

    return FALSE;
}

bool
ApplicationAccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aChild)
{
  if (!ApplicationAccessible::InsertChildAt(aIdx, aChild))
    return false;

  AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
  atk_object_set_parent(atkAccessible, mAtkObject);

    uint32_t count = mChildren.Length();

    // Emit children_changed::add in a timeout
    // to make sure aRootAccWrap is fully initialized.
    AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)
      malloc(sizeof(AtkRootAccessibleAddedEvent));
    if (eventData) {
      eventData->app_accessible = mAtkObject;
      eventData->root_accessible = atkAccessible;
      eventData->index = count -1;
      g_object_ref(mAtkObject);
      g_object_ref(atkAccessible);
      g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
    }

    return true;
}

bool
ApplicationAccessibleWrap::RemoveChild(Accessible* aChild)
{
  int32_t index = aChild->IndexInParent();

  AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
  atk_object_set_parent(atkAccessible, nullptr);
  g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
                        atkAccessible, nullptr);

  return ApplicationAccessible::RemoveChild(aChild);
}