зеркало из https://github.com/mozilla/pjs.git
Bug 332660 GTK file picker as used in Firefox is not accessibile for GOK
r=aaronleventhal sr=roc
This commit is contained in:
Родитель
b6fabb2e9e
Коммит
c09b1a0dd3
|
@ -83,6 +83,10 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
|
|||
in nsIWeakReference aWeakShell,
|
||||
inout nsIFrame frameHint, out boolean aIsHidden);
|
||||
|
||||
// For gtk+ native window accessible
|
||||
[noscript] nsIAccessible addNativeRootAccessible(in voidPtr aAtkAccessible);
|
||||
[noscript] void removeNativeRootAccessible(in nsIAccessible aRootAccessible);
|
||||
|
||||
/**
|
||||
* Invalidate the accessibility cache associated with aPresShell, for accessibles
|
||||
* that were generated for aContainerContent and it's subtree.
|
||||
|
|
|
@ -242,7 +242,7 @@ PRInt32 nsAccessibleWrap::mAccWrapDeleted = 0;
|
|||
nsAccessibleWrap::nsAccessibleWrap(nsIDOMNode* aNode,
|
||||
nsIWeakReference *aShell)
|
||||
: nsAccessible(aNode, aShell),
|
||||
mMaiAtkObject(nsnull)
|
||||
mAtkObject(nsnull)
|
||||
{
|
||||
#ifdef MAI_LOGGING
|
||||
++mAccWrapCreated;
|
||||
|
@ -262,9 +262,11 @@ nsAccessibleWrap::~nsAccessibleWrap()
|
|||
(void*)this, mAccWrapDeleted,
|
||||
(mAccWrapCreated-mAccWrapDeleted)));
|
||||
|
||||
if (mMaiAtkObject) {
|
||||
MAI_ATK_OBJECT(mMaiAtkObject)->accWrap = nsnull;
|
||||
g_object_unref(mMaiAtkObject);
|
||||
if (mAtkObject) {
|
||||
if (IS_MAI_OBJECT(mAtkObject)) {
|
||||
MAI_ATK_OBJECT(mAtkObject)->accWrap = nsnull;
|
||||
}
|
||||
g_object_unref(mAtkObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,20 +278,20 @@ NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
|
|||
// We don't create ATK objects for nsIAccessible plain text leaves
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!mMaiAtkObject) {
|
||||
if (!mAtkObject) {
|
||||
GType type = GetMaiAtkType(CreateMaiInterfaces());
|
||||
NS_ENSURE_TRUE(type, NS_ERROR_FAILURE);
|
||||
mMaiAtkObject =
|
||||
mAtkObject =
|
||||
NS_REINTERPRET_CAST(AtkObject *,
|
||||
g_object_new(type, NULL));
|
||||
NS_ENSURE_TRUE(mMaiAtkObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
atk_object_initialize(mMaiAtkObject, this);
|
||||
mMaiAtkObject->role = ATK_ROLE_INVALID;
|
||||
mMaiAtkObject->layer = ATK_LAYER_INVALID;
|
||||
atk_object_initialize(mAtkObject, this);
|
||||
mAtkObject->role = ATK_ROLE_INVALID;
|
||||
mAtkObject->layer = ATK_LAYER_INVALID;
|
||||
}
|
||||
|
||||
*aOutAccessible = mMaiAtkObject;
|
||||
*aOutAccessible = mAtkObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -689,7 +691,7 @@ classInitCB(AtkObjectClass *aClass)
|
|||
void
|
||||
initializeCB(AtkObject *aAtkObj, gpointer aData)
|
||||
{
|
||||
NS_ASSERTION((MAI_IS_ATK_OBJECT(aAtkObj)), "Invalid AtkObject");
|
||||
NS_ASSERTION((IS_MAI_OBJECT(aAtkObj)), "Invalid AtkObject");
|
||||
NS_ASSERTION(aData, "Invalid Data to init AtkObject");
|
||||
if (!aAtkObj || !aData)
|
||||
return;
|
||||
|
@ -717,7 +719,7 @@ initializeCB(AtkObject *aAtkObj, gpointer aData)
|
|||
void
|
||||
finalizeCB(GObject *aObj)
|
||||
{
|
||||
if (!MAI_IS_ATK_OBJECT(aObj))
|
||||
if (!IS_MAI_OBJECT(aObj))
|
||||
return;
|
||||
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == nsnull, "AccWrap NOT null");
|
||||
|
||||
|
@ -1012,7 +1014,7 @@ refRelationSetCB(AtkObject *aAtkObj)
|
|||
nsresult
|
||||
CheckMaiAtkObject(AtkObject *aAtkObj)
|
||||
{
|
||||
NS_ENSURE_ARG(MAI_IS_ATK_OBJECT(aAtkObj));
|
||||
NS_ENSURE_ARG(IS_MAI_OBJECT(aAtkObj));
|
||||
nsAccessibleWrap * tmpAccWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
|
||||
if (tmpAccWrap == nsnull)
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
|
@ -1027,7 +1029,7 @@ CheckMaiAtkObject(AtkObject *aAtkObj)
|
|||
// for it.
|
||||
nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
|
||||
{
|
||||
NS_ENSURE_TRUE(MAI_IS_ATK_OBJECT(aAtkObj), nsnull);
|
||||
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nsnull);
|
||||
nsAccessibleWrap * tmpAccWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
|
||||
NS_ENSURE_TRUE(tmpAccWrap != nsnull, nsnull);
|
||||
NS_ENSURE_TRUE(tmpAccWrap->GetAtkObject() == aAtkObj, nsnull);
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
AtkObject *mMaiAtkObject;
|
||||
AtkObject *mAtkObject;
|
||||
|
||||
private:
|
||||
PRUint16 CreateMaiInterfaces(void);
|
||||
|
|
|
@ -51,6 +51,11 @@
|
|||
/* app root accessible */
|
||||
static nsAppRootAccessible *sAppRoot = nsnull;
|
||||
|
||||
/* gail function pointer */
|
||||
static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
|
||||
const gchar *event_type);
|
||||
static void (* gail_remove_global_event_listener) (guint remove_listener);
|
||||
|
||||
/* maiutil */
|
||||
|
||||
static guint mai_util_add_global_event_listener(GSignalEmissionHook listener,
|
||||
|
@ -70,7 +75,8 @@ static void _listener_info_destroy(gpointer data);
|
|||
static guint add_listener (GSignalEmissionHook listener,
|
||||
const gchar *object_type,
|
||||
const gchar *signal,
|
||||
const gchar *hook_data);
|
||||
const gchar *hook_data,
|
||||
guint gail_listenerid = 0);
|
||||
static AtkKeyEventStruct *atk_key_event_from_gdk_event_key(GdkEventKey *key);
|
||||
static gboolean notify_hf(gpointer key, gpointer value, gpointer data);
|
||||
static void insert_hf(gpointer key, gpointer value, gpointer data);
|
||||
|
@ -149,6 +155,11 @@ struct _MaiUtilListenerInfo
|
|||
gint key;
|
||||
guint signal_id;
|
||||
gulong hook_id;
|
||||
// For window create/destory/minimize/maximize/restore/activate/deactivate
|
||||
// events, we'll chain gail_util's add/remove_global_event_listener.
|
||||
// So we store the listenerid returned by gail's add_global_event_listener
|
||||
// in this structure to call gail's remove_global_event_listener later.
|
||||
guint gail_listenerid;
|
||||
};
|
||||
|
||||
static GnomeAccessibilityModule sAtkBridge = {
|
||||
|
@ -158,8 +169,13 @@ static GnomeAccessibilityModule sAtkBridge = {
|
|||
"libatk-bridge.so", NULL,
|
||||
#endif
|
||||
"gnome_accessibility_module_init", NULL,
|
||||
"gnome_accessibility_module_shutdown", NULL
|
||||
};
|
||||
|
||||
"gnome_accessibility_module_shutdown", NULL,
|
||||
static GnomeAccessibilityModule sGail = {
|
||||
"libgail.so", NULL,
|
||||
"gnome_accessibility_module_init", NULL,
|
||||
"gnome_accessibility_module_shutdown", NULL
|
||||
};
|
||||
|
||||
GType
|
||||
|
@ -199,6 +215,10 @@ mai_util_class_init(MaiUtilClass *klass)
|
|||
data = g_type_class_peek(ATK_TYPE_UTIL);
|
||||
atk_class = ATK_UTIL_CLASS(data);
|
||||
|
||||
// save gail function pointer
|
||||
gail_add_global_event_listener = atk_class->add_global_event_listener;
|
||||
gail_remove_global_event_listener = atk_class->remove_global_event_listener;
|
||||
|
||||
atk_class->add_global_event_listener =
|
||||
mai_util_add_global_event_listener;
|
||||
atk_class->remove_global_event_listener =
|
||||
|
@ -224,17 +244,15 @@ mai_util_add_global_event_listener(GSignalEmissionHook listener,
|
|||
|
||||
if (split_string) {
|
||||
if (!strcmp ("window", split_string[0])) {
|
||||
/* ???
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized) {
|
||||
do_window_event_initialization ();
|
||||
initialized = TRUE;
|
||||
}
|
||||
rc = add_listener (listener, "MaiWindow",
|
||||
split_string[1], event_type);
|
||||
*/
|
||||
rc = add_listener (listener, "MaiAtkObject", split_string[1], event_type);
|
||||
guint gail_listenerid = 0;
|
||||
if (gail_add_global_event_listener) {
|
||||
// call gail's function to track gtk native window events
|
||||
gail_listenerid =
|
||||
gail_add_global_event_listener(listener, event_type);
|
||||
}
|
||||
|
||||
rc = add_listener (listener, "MaiAtkObject", split_string[1],
|
||||
event_type, gail_listenerid);
|
||||
}
|
||||
else {
|
||||
rc = add_listener (listener, split_string[1], split_string[2],
|
||||
|
@ -255,6 +273,11 @@ mai_util_remove_global_event_listener(guint remove_listener)
|
|||
g_hash_table_lookup(listener_list, &tmp_idx);
|
||||
|
||||
if (listener_info != NULL) {
|
||||
if (gail_remove_global_event_listener &&
|
||||
listener_info->gail_listenerid) {
|
||||
gail_remove_global_event_listener(listener_info->gail_listenerid);
|
||||
}
|
||||
|
||||
/* Hook id of 0 and signal id of 0 are invalid */
|
||||
if (listener_info->hook_id != 0 && listener_info->signal_id != 0) {
|
||||
/* Remove the emission hook */
|
||||
|
@ -270,7 +293,6 @@ mai_util_remove_global_event_listener(guint remove_listener)
|
|||
g_log((gchar *)0, G_LOG_LEVEL_WARNING,
|
||||
"Invalid listener hook_id %ld or signal_id %d\n",
|
||||
listener_info->hook_id, listener_info->signal_id);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -438,7 +460,8 @@ guint
|
|||
add_listener (GSignalEmissionHook listener,
|
||||
const gchar *object_type,
|
||||
const gchar *signal,
|
||||
const gchar *hook_data)
|
||||
const gchar *hook_data,
|
||||
guint gail_listenerid)
|
||||
{
|
||||
GType type;
|
||||
guint signal_id;
|
||||
|
@ -460,6 +483,7 @@ add_listener (GSignalEmissionHook listener,
|
|||
g_strdup(hook_data),
|
||||
(GDestroyNotify)g_free);
|
||||
listener_info->signal_id = signal_id;
|
||||
listener_info->gail_listenerid = gail_listenerid;
|
||||
|
||||
g_hash_table_insert(listener_list, &(listener_info->key),
|
||||
listener_info);
|
||||
|
@ -535,13 +559,22 @@ NS_IMETHODIMP nsAppRootAccessible::Init()
|
|||
if (mInitialized == PR_TRUE)
|
||||
return NS_OK;
|
||||
|
||||
// load and initialize gail library
|
||||
nsresult rv = LoadGtkModule(sGail);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
(*sGail.init)();
|
||||
}
|
||||
else {
|
||||
MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
|
||||
}
|
||||
|
||||
MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n"));
|
||||
g_type_init();
|
||||
// Initialize the MAI Utility class
|
||||
// it will overwrite gail_util
|
||||
g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL));
|
||||
|
||||
// load and initialize atk-bridge library
|
||||
nsresult rv = LoadGtkModule(sAtkBridge);
|
||||
rv = LoadGtkModule(sAtkBridge);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// init atk-bridge
|
||||
(*sAtkBridge.init)();
|
||||
|
@ -565,6 +598,13 @@ NS_IMETHODIMP nsAppRootAccessible::Init()
|
|||
sAtkBridge.init = NULL;
|
||||
sAtkBridge.shutdown = NULL;
|
||||
}
|
||||
if (sGail.lib) {
|
||||
if (sGail.shutdown)
|
||||
(*sGail.shutdown)();
|
||||
sGail.lib = NULL;
|
||||
sGail.init = NULL;
|
||||
sGail.shutdown = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppRootAccessible::GetName(nsAString& _retval)
|
||||
|
@ -693,35 +733,40 @@ NS_IMETHODIMP nsAppRootAccessible::GetNativeInterface(void **aOutAccessible)
|
|||
{
|
||||
*aOutAccessible = nsnull;
|
||||
|
||||
if (!mMaiAtkObject) {
|
||||
mMaiAtkObject =
|
||||
if (!mAtkObject) {
|
||||
mAtkObject =
|
||||
NS_REINTERPRET_CAST(AtkObject *,
|
||||
g_object_new(MAI_TYPE_ATK_OBJECT, NULL));
|
||||
NS_ENSURE_TRUE(mMaiAtkObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
atk_object_initialize(mMaiAtkObject, this);
|
||||
mMaiAtkObject->role = ATK_ROLE_INVALID;
|
||||
mMaiAtkObject->layer = ATK_LAYER_INVALID;
|
||||
atk_object_initialize(mAtkObject, this);
|
||||
mAtkObject->role = ATK_ROLE_INVALID;
|
||||
mAtkObject->layer = ATK_LAYER_INVALID;
|
||||
}
|
||||
|
||||
*aOutAccessible = mMaiAtkObject;
|
||||
*aOutAccessible = mAtkObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAppRootAccessible::AddRootAccessible(nsRootAccessibleWrap *aRootAccWrap)
|
||||
nsAppRootAccessible::AddRootAccessible(nsIAccessible *aRootAccWrap)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRootAccWrap);
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
// add by weak reference
|
||||
rv = mChildren->AppendElement(NS_STATIC_CAST(nsIAccessibleDocument*, aRootAccWrap),
|
||||
PR_TRUE);
|
||||
rv = mChildren->AppendElement(aRootAccWrap, PR_TRUE);
|
||||
|
||||
#ifdef MAI_LOGGING
|
||||
void* atkAccessible;
|
||||
aRootAccWrap->GetNativeInterface(&atkAccessible);
|
||||
atk_object_set_parent((AtkObject*)atkAccessible, mAtkObject);
|
||||
PRUint32 count = 0;
|
||||
mChildren->GetLength(&count);
|
||||
g_signal_emit_by_name(mAtkObject, "children_changed::add", count - 1,
|
||||
atkAccessible, NULL);
|
||||
|
||||
#ifdef MAI_LOGGING
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MAI_LOG_DEBUG(("\nAdd RootAcc=%p OK, count=%d\n",
|
||||
(void*)aRootAccWrap, count));
|
||||
|
@ -735,7 +780,7 @@ nsAppRootAccessible::AddRootAccessible(nsRootAccessibleWrap *aRootAccWrap)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsAppRootAccessible::RemoveRootAccessible(nsRootAccessibleWrap *aRootAccWrap)
|
||||
nsAppRootAccessible::RemoveRootAccessible(nsIAccessible *aRootAccWrap)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRootAccWrap);
|
||||
|
||||
|
@ -743,10 +788,15 @@ nsAppRootAccessible::RemoveRootAccessible(nsRootAccessibleWrap *aRootAccWrap)
|
|||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
// we must use weak ref to get the index
|
||||
nsCOMPtr<nsIWeakReference> weakPtr =
|
||||
do_GetWeakReference(NS_STATIC_CAST(nsIAccessibleDocument*, aRootAccWrap));
|
||||
nsCOMPtr<nsIWeakReference> weakPtr = do_GetWeakReference(aRootAccWrap);
|
||||
rv = mChildren->IndexOf(0, weakPtr, &index);
|
||||
|
||||
void* atkAccessible;
|
||||
aRootAccWrap->GetNativeInterface(&atkAccessible);
|
||||
atk_object_set_parent((AtkObject*)atkAccessible, NULL);
|
||||
g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
|
||||
atkAccessible, NULL);
|
||||
|
||||
#ifdef MAI_LOGGING
|
||||
PRUint32 count = 0;
|
||||
mChildren->GetLength(&count);
|
||||
|
|
|
@ -92,8 +92,8 @@ public:
|
|||
// return the atk object for app root accessible
|
||||
NS_IMETHOD GetNativeInterface(void **aOutAccessible);
|
||||
|
||||
nsresult AddRootAccessible(nsRootAccessibleWrap *aRootAccWrap);
|
||||
nsresult RemoveRootAccessible(nsRootAccessibleWrap *aRootAccWrap);
|
||||
nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
|
||||
nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
|
||||
private:
|
||||
nsCOMPtr<nsIMutableArray> mChildren;
|
||||
PRBool mInitialized;
|
||||
|
|
|
@ -73,9 +73,9 @@ PR_END_MACRO
|
|||
#define MAI_ATK_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
MAI_TYPE_ATK_OBJECT, \
|
||||
MaiAtkObjectClass))
|
||||
#define MAI_IS_ATK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
#define IS_MAI_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
MAI_TYPE_ATK_OBJECT))
|
||||
#define MAI_IS_ATK_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
#define IS_MAI_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
MAI_TYPE_ATK_OBJECT))
|
||||
#define MAI_ATK_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
MAI_TYPE_ATK_OBJECT, \
|
||||
|
|
|
@ -91,3 +91,9 @@ NS_IMETHODIMP nsRootAccessibleWrap::GetParent(nsIAccessible ** aParent)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsNativeRootAccessibleWrap::nsNativeRootAccessibleWrap(AtkObject *aAccessible):
|
||||
nsRootAccessible(nsnull, nsnull)
|
||||
{
|
||||
g_object_ref(aAccessible);
|
||||
nsAccessibleWrap::mAtkObject = aAccessible;
|
||||
}
|
||||
|
|
|
@ -61,4 +61,11 @@ public:
|
|||
NS_IMETHOD GetParent(nsIAccessible ** aParent);
|
||||
};
|
||||
|
||||
// For gtk+ native window
|
||||
class nsNativeRootAccessibleWrap: public nsRootAccessible
|
||||
{
|
||||
public:
|
||||
nsNativeRootAccessibleWrap(AtkObject *aAccessible);
|
||||
};
|
||||
|
||||
#endif /* __NS_ROOT_ACCESSIBLE_WRAP_H__ */
|
||||
|
|
|
@ -96,6 +96,10 @@
|
|||
#include "nsHTMLWin32ObjectAccessible.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
#include "nsAppRootAccessible.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_XFORMS_HOOKS
|
||||
#include "nsXFormsFormControlsAccessible.h"
|
||||
#endif
|
||||
|
@ -1452,6 +1456,39 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessibilityService::AddNativeRootAccessible(void * aAtkAccessible, nsIAccessible **aRootAccessible)
|
||||
{
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
nsNativeRootAccessibleWrap* rootAccWrap =
|
||||
new nsNativeRootAccessibleWrap((AtkObject*)aAtkAccessible);
|
||||
|
||||
*aRootAccessible = NS_STATIC_CAST(nsIAccessible*, rootAccWrap);
|
||||
NS_ADDREF(*aRootAccessible);
|
||||
|
||||
nsAppRootAccessible *appRoot = nsAppRootAccessible::Create();
|
||||
appRoot->AddRootAccessible(*aRootAccessible);
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessibilityService::RemoveNativeRootAccessible(nsIAccessible * aRootAccessible)
|
||||
{
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
void* atkAccessible;
|
||||
aRootAccessible->GetNativeInterface(&atkAccessible);
|
||||
|
||||
nsAppRootAccessible *appRoot = nsAppRootAccessible::Create();
|
||||
appRoot->RemoveRootAccessible(aRootAccessible);
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Called from layout when the frame tree owned by a node changes significantly
|
||||
NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
|
||||
nsIContent *aChangeContent,
|
||||
|
|
|
@ -82,6 +82,10 @@ nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell)
|
|||
nsHyperTextAccessible(aDOMNode, aShell), mWnd(nsnull),
|
||||
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE)
|
||||
{
|
||||
// For GTK+ native window, we do nothing here.
|
||||
if (!mDOMNode)
|
||||
return;
|
||||
|
||||
// Because of the way document loading happens, the new nsIWidget is created before
|
||||
// the old one is removed. Since it creates the nsDocAccessible, for a brief moment
|
||||
// there can be 2 nsDocAccessible's for the content area, although for 2 different
|
||||
|
|
|
@ -110,6 +110,7 @@ CPPSRCS = \
|
|||
nsDeviceContextSpecG.cpp \
|
||||
nsPrintOptionsGTK.cpp \
|
||||
nsImageToPixbuf.cpp \
|
||||
nsAccessibilityHelper.cpp \
|
||||
$(NULL)
|
||||
|
||||
# build our subdirs, too
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ginn Chen (ginn.chen@sun.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAccessibilityHelper.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsWindow.h"
|
||||
#endif
|
||||
|
||||
gint RunDialog(GtkDialog* aDialog)
|
||||
{
|
||||
#ifdef ACCESSIBILITY
|
||||
if (!nsWindow::sAccessibilityEnabled) {
|
||||
return gtk_dialog_run (aDialog);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService ("@mozilla.org/accessibilityService;1");
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
|
||||
// Attach the dialog accessible to app accessible tree
|
||||
if (accService) {
|
||||
AtkObject* gailWindow = gtk_widget_get_accessible(GTK_WIDGET(aDialog));
|
||||
accService->AddNativeRootAccessible(gailWindow, getter_AddRefs(accessible));
|
||||
}
|
||||
|
||||
gint result = gtk_dialog_run (aDialog);
|
||||
|
||||
// Deattach the dialog accessible
|
||||
if (accService && accessible) {
|
||||
accService->RemoveNativeRootAccessible(accessible);
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return gtk_dialog_run (aDialog);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ginn Chen (ginn.chen@sun.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __NS_ACCESSIBILITY_HELPER_H__
|
||||
#define __NS_ACCESSIBILITY_HELPER_H__
|
||||
|
||||
#include <gtk/gtkdialog.h>
|
||||
|
||||
// This helper function attach/deattach the AtkObject of the dialog
|
||||
// to Gecko a11y root, before/after calling gtk_dialog_run.
|
||||
// It makes Mozilla's gtk2 native dialog accessible to at-tools.
|
||||
// It should be used instead of calling gtk_dialog_run directly in Mozilla.
|
||||
gint RunDialog(GtkDialog *aDialog);
|
||||
|
||||
#endif /* __NS_ACCESSIBILITY_HELPER_H__ */
|
|
@ -57,6 +57,7 @@
|
|||
#include "prlink.h"
|
||||
|
||||
#include "nsFilePicker.h"
|
||||
#include "nsAccessibilityHelper.h"
|
||||
|
||||
#define DECL_FUNC_PTR(func) static _##func##_fn _##func
|
||||
#define GTK_FILE_CHOOSER(widget) ((GtkFileChooser*) widget)
|
||||
|
@ -486,7 +487,8 @@ confirm_overwrite_file (GtkWidget *parent, nsILocalFile* file)
|
|||
gtk_window_group_add_window(parent_window->group, GTK_WINDOW(dialog));
|
||||
}
|
||||
|
||||
PRBool result = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES);
|
||||
PRBool result = (RunDialog(GTK_DIALOG (dialog)) == GTK_RESPONSE_YES);
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
return result;
|
||||
|
@ -580,7 +582,7 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
|||
_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_chooser), PR_TRUE);
|
||||
}
|
||||
|
||||
gint response = gtk_dialog_run (GTK_DIALOG (file_chooser));
|
||||
gint response = RunDialog(GTK_DIALOG (file_chooser));
|
||||
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
|
|
|
@ -75,7 +75,8 @@
|
|||
#include "prenv.h"
|
||||
#include "stdlib.h"
|
||||
static PRBool sAccessibilityChecked = PR_FALSE;
|
||||
static PRBool sAccessibilityEnabled = PR_FALSE;
|
||||
/* static */
|
||||
PRBool nsWindow::sAccessibilityEnabled = PR_FALSE;
|
||||
static const char sSysPrefService [] = "@mozilla.org/system-preference-service;1";
|
||||
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
|
||||
static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility";
|
||||
|
|
|
@ -353,6 +353,10 @@ public:
|
|||
gfxASurface *GetThebesSurface();
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
static PRBool sAccessibilityEnabled;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void GetToplevelWidget(GtkWidget **aWidget);
|
||||
void GetContainerWindow(nsWindow **aWindow);
|
||||
|
|
Загрузка…
Ссылка в новой задаче