bug 693343 - a11y disabled in Gnome 3 when GNOME_ACCESSIBILITY is unset patch=mgorse, tbsaunde r=tbsaunde, karlt

(testing a possible bustage fix)
This commit is contained in:
Trevor Saunders 2012-01-04 20:54:17 -05:00
parent 3ef0679ab6
commit 57ef4f25d9
5 changed files with 157 additions and 65 deletions

View File

@ -92,6 +92,10 @@ include $(topsrcdir)/config/rules.mk
CFLAGS += $(MOZ_GTK2_CFLAGS)
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
ifdef MOZ_ENABLE_DBUS
CXXFLAGS += $(MOZ_DBUS_CFLAGS)
endif
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \

View File

@ -52,8 +52,12 @@
#include <gtk/gtk.h>
#include <atk/atk.h>
#ifdef MOZ_ENABLE_DBUS
#include <dbus/dbus.h>
#endif
using namespace mozilla;
using namespace mozilla::a11y;
typedef GType (* AtkGetTypeType) (void);
GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
@ -61,10 +65,7 @@ static bool sATKChecked = false;
static PRLibrary *sATKLib = nsnull;
static const char sATKLibName[] = "libatk-1.0.so.0";
static const char sATKHyperlinkImplGetTypeSymbol[] =
"atk_hyperlink_impl_get_type";
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
static const char sGconfAccessibilityKey[] =
"/desktop/gnome/interface/accessibility";
"atk_hyperlink_impl_get_type";
/* gail function pointer */
static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
@ -614,27 +615,7 @@ toplevel_event_watcher(GSignalInvocationHint* ihint,
bool
nsApplicationAccessibleWrap::Init()
{
// XXX following code is copied from widget/src/gtk2/nsWindow.cpp
// we should put it to somewhere that can be used from both modules
// see bug 390761
// check if accessibility enabled/disabled by environment variable
bool isGnomeATEnabled = false;
const char *envValue = PR_GetEnv(sAccEnv);
if (envValue) {
isGnomeATEnabled = !!atoi(envValue);
} else {
//check gconf-2 setting
nsresult rv;
nsCOMPtr<nsIGConfService> gconf =
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && gconf) {
gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
&isGnomeATEnabled);
}
}
if (isGnomeATEnabled) {
if (ShouldA11yBeEnabled()) {
// load and initialize gail library
nsresult rv = LoadGtkModule(sGail);
if (NS_SUCCEEDED(rv)) {
@ -883,3 +864,127 @@ LoadGtkModule(GnomeAccessibilityModule& aModule)
}
return NS_OK;
}
namespace mozilla {
namespace a11y {
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
#ifdef MOZ_ENABLE_DBUS
static DBusPendingCall *sPendingCall = nsnull;
#endif
void
PreInit()
{
#ifdef MOZ_ENABLE_DBUS
static bool sChecked = FALSE;
if (sChecked)
return;
sChecked = TRUE;
// dbus is only checked if GNOME_ACCESSIBILITY is unset
if (PR_GetEnv(sAccEnv) || !PR_GetEnv("DBUS_SESSION_BUS_ADDRESS"))
return;
DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, nsnull);
if (!bus)
return;
dbus_connection_set_exit_on_disconnect(bus, FALSE);
DBusMessage *message;
message = dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus",
"org.freedesktop.DBus.Properties",
"Get");
if (!message)
goto dbus_done;
static const char* iface = "org.a11y.Status";
static const char* member = "IsEnabled";
dbus_message_append_args(message, DBUS_TYPE_STRING, &iface,
DBUS_TYPE_STRING, &member, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply(bus, message, &sPendingCall, 1000);
dbus_message_unref(message);
dbus_done:
dbus_connection_unref(bus);
#endif
}
bool
ShouldA11yBeEnabled()
{
static bool sChecked = false, sShouldEnable = false;
if (sChecked)
return sShouldEnable;
sChecked = true;
// check if accessibility enabled/disabled by environment variable
const char* envValue = PR_GetEnv(sAccEnv);
if (envValue)
return sShouldEnable = !!atoi(envValue);
#ifdef MOZ_ENABLE_DBUS
PreInit();
bool dbusSuccess = false;
DBusMessage *reply = nsnull;
if (!sPendingCall)
goto dbus_done;
dbus_pending_call_block(sPendingCall);
reply = dbus_pending_call_steal_reply(sPendingCall);
dbus_pending_call_unref(sPendingCall);
sPendingCall = nsnull;
if (!reply ||
dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN ||
strcmp(dbus_message_get_signature (reply), DBUS_TYPE_VARIANT_AS_STRING))
goto dbus_done;
DBusMessageIter iter, iter_variant, iter_struct;
dbus_bool_t dResult;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse (&iter, &iter_variant);
switch (dbus_message_iter_get_arg_type(&iter_variant)) {
case DBUS_TYPE_STRUCT:
// at-spi2-core 2.2.0-2.2.1 had a bug where it returned a struct
dbus_message_iter_recurse(&iter_variant, &iter_struct);
if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {
dbus_message_iter_get_basic(&iter_struct, &dResult);
sShouldEnable = dResult;
dbusSuccess = true;
}
break;
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(&iter_variant, &dResult);
sShouldEnable = dResult;
dbusSuccess = true;
break;
default:
break;
}
dbus_done:
if (reply)
dbus_message_unref(reply);
if (dbusSuccess)
return sShouldEnable;
#endif
//check gconf-2 setting
static const char sGconfAccessibilityKey[] =
"/desktop/gnome/interface/accessibility";
nsresult rv = NS_OK;
nsCOMPtr<nsIGConfService> gconf =
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && gconf)
gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey), &sShouldEnable);
return sShouldEnable;
}
} // namespace a11y
} // namespace mozilla

View File

@ -56,6 +56,21 @@ namespace a11y {
*/
FocusManager* FocusMgr();
#ifdef MOZ_ACCESSIBILITY_ATK
/**
* Perform initialization that should be done as soon as possible, in order
* to minimize startup time.
* XXX: this function and the next defined in nsApplicationAccessibleWrap.cpp
*/
void PreInit();
/**
* Is platform accessibility enabled.
* Only used on linux with atk for now.
*/
bool ShouldA11yBeEnabled();
#endif
} // namespace a11y
} // namespace mozilla

View File

@ -109,19 +109,11 @@
#include "nsIPropertyBag2.h"
#ifdef ACCESSIBILITY
#include "nsIAccessibilityService.h"
#include "nsAccessibilityService.h"
#include "nsIAccessibleDocument.h"
#include "prenv.h"
#include "stdlib.h"
using namespace mozilla;
using namespace mozilla::widget;
static bool sAccessibilityChecked = false;
/* static */
bool nsWindow::sAccessibilityEnabled = false;
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
static const char sGconfAccessibilityKey[] = "/desktop/gnome/interface/accessibility";
#endif
/* For SetIcon */
@ -1123,9 +1115,8 @@ nsWindow::Show(bool aState)
}
#ifdef ACCESSIBILITY
if (aState && sAccessibilityEnabled) {
if (aState && a11y::ShouldA11yBeEnabled())
CreateRootAccessible();
}
#endif
NativeShow(aState);
@ -3962,6 +3953,11 @@ nsWindow::Create(nsIWidget *aParent,
NS_ASSERTION(!mWindowGroup, "already have window group (leaking it)");
#ifdef ACCESSIBILITY
// Send a DBus message to check whether a11y is enabled
a11y::PreInit();
#endif
// Ensure that the toolkit is created.
nsGTKToolkit::GetToolkit();
@ -4355,31 +4351,6 @@ nsWindow::Create(nsIWidget *aParent,
if (!mIsTopLevel)
Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, false);
#ifdef ACCESSIBILITY
nsresult rv;
if (!sAccessibilityChecked) {
sAccessibilityChecked = true;
//check if accessibility enabled/disabled by environment variable
const char *envValue = PR_GetEnv(sAccEnv);
if (envValue) {
sAccessibilityEnabled = atoi(envValue) != 0;
LOG(("Accessibility Env %s=%s\n", sAccEnv, envValue));
} else {
//check gconf-2 setting
nsCOMPtr<nsIGConfService> gconf =
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && gconf) {
// do the work to get gconf setting.
// will be done soon later.
gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
&sAccessibilityEnabled);
}
}
}
#endif
#ifdef MOZ_DFB
if (!mDFB) {
DirectFBCreate( &mDFB );
@ -6559,7 +6530,7 @@ nsWindow::DispatchAccessibleEvent()
void
nsWindow::DispatchEventToRootAccessible(PRUint32 aEventType)
{
if (!sAccessibilityEnabled) {
if (!a11y::ShouldA11yBeEnabled()) {
return;
}

View File

@ -347,9 +347,6 @@ public:
#endif
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
#ifdef ACCESSIBILITY
static bool sAccessibilityEnabled;
#endif
protected:
// Helper for SetParent and ReparentNativeWidget.
void ReparentNativeWidgetInternal(nsIWidget* aNewParent,