Read a11y status from Gnome3
authorMichael Gorse <mgorse@suse.com>
Tue, 29 Nov 2011 15:56:24 +0100
changeset 358 b28670af14d5
parent 357 db07eb421d6b
child 359 85f2bc39c5c4
Read a11y status from Gnome3
MozillaFirefox/MozillaFirefox.changes
MozillaFirefox/MozillaFirefox.spec
MozillaFirefox/create-tar.sh
MozillaFirefox/mozilla-a11y.patch
mozilla-a11y.patch
series
xulrunner/mozilla-a11y.patch
--- a/MozillaFirefox/MozillaFirefox.changes	Mon Nov 21 23:46:54 2011 +0100
+++ b/MozillaFirefox/MozillaFirefox.changes	Tue Nov 29 15:56:24 2011 +0100
@@ -1,3 +1,8 @@
+-------------------------------------------------------------------
+Sun Nov 27 03:51:54 UTC 2011 - mgorse@suse.com
+
+- Fix accessibility under GNOME 3 (bnc#732898)
+
 -------------------------------------------------------------------
 Sat Nov 12 15:16:38 UTC 2011 - dvaleev@suse.com
 
--- a/MozillaFirefox/MozillaFirefox.spec	Mon Nov 21 23:46:54 2011 +0100
+++ b/MozillaFirefox/MozillaFirefox.spec	Tue Nov 29 15:56:24 2011 +0100
@@ -35,7 +35,7 @@
 License:        MPLv1.1 or GPLv2+ or LGPLv2+
 Version:        %{mainver}
 Release:        1
-%define         releasedate 2011111700
+%define         releasedate 2011112500
 Provides:       web_browser
 Provides:       firefox = %{version}-%{release}
 Provides:       firefox = %{mainver}
@@ -74,6 +74,7 @@
 Patch11:        mozilla-sle11.patch
 Patch12:        mozilla-linux3.patch
 Patch13:        mozilla-ppc64.patch
+Patch14:        mozilla-a11y.patch
 # Firefox/browser
 Patch31:        firefox-browser-css.patch
 Patch32:        firefox-cross-desktop.patch
@@ -206,6 +207,7 @@
 %endif
 %patch12 -p1
 %patch13 -p1
+%patch14 -p1
 #
 %patch31 -p1
 %patch32 -p1
--- a/MozillaFirefox/create-tar.sh	Mon Nov 21 23:46:54 2011 +0100
+++ b/MozillaFirefox/create-tar.sh	Tue Nov 29 15:56:24 2011 +0100
@@ -2,7 +2,7 @@
 
 CHANNEL="beta"
 BRANCH="releases/mozilla-$CHANNEL"
-RELEASE_TAG="FIREFOX_9_0b2_RELEASE"
+RELEASE_TAG="FIREFOX_9_0b3_RELEASE"
 VERSION="8.99"
 
 # mozilla
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-a11y.patch	Tue Nov 29 15:56:24 2011 +0100
@@ -0,0 +1,1 @@
+../mozilla-a11y.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-a11y.patch	Tue Nov 29 15:56:24 2011 +0100
@@ -0,0 +1,417 @@
+# HG changeset patch
+# User Michael Gorse <mgorse@suse.com>
+# Parent d02253d1e8217008dfa26e6e2a901b6a8b75e989
+a11y only enabled from Gnome 2's GConf setting
+https://bugzilla.novell.com/show_bug.cgi?id=732898
+https://bugzilla.mozilla.org/show_bug.cgi?id=693343
+
+diff --git a/accessible/src/atk/Makefile.in b/accessible/src/atk/Makefile.in
+--- a/accessible/src/atk/Makefile.in
++++ b/accessible/src/atk/Makefile.in
+@@ -87,15 +87,19 @@ EXPORTS = \
+ # we want to force the creation of a static lib.
+ FORCE_STATIC_LIB = 1
+ 
+ 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 \
+   -I$(srcdir)/../html \
+   -I$(srcdir)/../xul \
+   -I$(topsrcdir)/other-licenses/atk-1.0 \
+   $(NULL)
+diff --git a/accessible/src/atk/nsApplicationAccessibleWrap.cpp b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
++++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+@@ -47,29 +47,27 @@
+ #include "nsIPrefBranch.h"
+ #include "nsIServiceManager.h"
+ #include "nsAutoPtr.h"
+ #include "nsAccessibilityService.h"
+ #include "AtkSocketAccessible.h"
+ 
+ #include <gtk/gtk.h>
+ #include <atk/atk.h>
++#include <dbus/dbus.h>
++
++using namespace mozilla::a11y;
+ 
+ typedef GType (* AtkGetTypeType) (void);
+ GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
+-static bool sATKChecked = false;
++static PRBool sATKChecked = PR_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 sSysPrefService [] =
+-    "@mozilla.org/system-preference-service;1";
+-static const char sAccessibilityKey [] =
+-    "config.use_system_prefs.accessibility";
+ 
+ /* 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);
+ static void (* gail_remove_key_event_listener) (guint remove_listener);
+ static AtkObject * (*gail_get_root) (void);
+ 
+@@ -609,36 +607,17 @@ toplevel_event_watcher(GSignalInvocation
+   }
+ 
+   return TRUE;
+ }
+ 
+ PRBool
+ 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
+-    PRBool isGnomeATEnabled = PR_FALSE;
+-    const char *envValue = PR_GetEnv(sAccEnv);
+-    if (envValue) {
+-        isGnomeATEnabled = !!atoi(envValue);
+-    } else {
+-        //check gconf-2 setting
+-        nsresult rv;
+-        nsCOMPtr<nsIPrefBranch> sysPrefService =
+-            do_GetService(sSysPrefService, &rv);
+-        if (NS_SUCCEEDED(rv) && sysPrefService) {
+-            sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
+-        }
+-    }
+-
+-    if (isGnomeATEnabled) {
++    if (ShouldA11yBeEnabled()) {
+         // 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));
+         }
+@@ -877,8 +856,129 @@ LoadGtkModule(GnomeAccessibilityModule& 
+                        aModule.init ? aModule.shutdownName : aModule.initName,
+                        aModule.libName));
+         PR_UnloadLibrary(aModule.lib);
+         aModule.lib = NULL;
+         return NS_ERROR_FAILURE;
+     }
+     return NS_OK;
+ }
++
++namespace mozilla {
++namespace a11y {
++
++#ifdef MOZ_ENABLE_DBUS
++static DBusPendingCall *a11yPendingCall = NULL;
++#endif
++
++void
++PreInit()
++{
++  static PRBool sChecked = FALSE;
++  if (sChecked)
++    return;
++  sChecked = TRUE;
++  DBusError error;
++  dbus_error_init(&error);
++  DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
++  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, &a11yPendingCall, 1000);
++
++dbus_done:
++  if (message)
++    dbus_message_unref(message);
++  if (bus)
++    dbus_connection_unref(bus);
++  dbus_error_free(&error);
++}
++
++PRBool
++ShouldA11yBeEnabled()
++{
++  static PRBool sChecked = PR_FALSE, sShouldEnable = PR_FALSE;
++  if (sChecked)
++    return sShouldEnable;
++
++  sChecked = PR_TRUE;
++
++  // check if accessibility enabled/disabled by environment variable
++  static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
++  const char* envValue = PR_GetEnv(sAccEnv);
++  if (envValue)
++    return sShouldEnable = !!atoi(envValue);
++
++#ifdef MOZ_ENABLE_DBUS
++  PreInit();
++  PRBool dbusSuccess = PR_FALSE;
++  DBusMessage *reply = nsnull;
++  if (a11yPendingCall) {
++    dbus_pending_call_block(a11yPendingCall);
++    reply = dbus_pending_call_steal_reply(a11yPendingCall);
++    dbus_pending_call_unref(a11yPendingCall);
++    a11yPendingCall = nsnull;
++  }
++  if (!reply ||
++      dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN ||
++      strcmp(dbus_message_get_signature (reply), "v"))
++    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
++  nsresult rv = NS_OK;
++  static const char sSysPrefService [] =
++    "@mozilla.org/system-preference-service;1";
++  static const char sAccessibilityKey [] =
++    "config.use_system_prefs.accessibility";
++  nsCOMPtr<nsIPrefBranch> sysPrefService =
++    do_GetService(sSysPrefService, &rv);
++  if (NS_SUCCEEDED(rv) && sysPrefService)
++    sysPrefService->GetBoolPref(sAccessibilityKey, &sShouldEnable);
++
++  return sShouldEnable;
++}
++} // namespace a11y
++} // namespace mozilla
++
+diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h
+--- a/accessible/src/base/nsAccessibilityService.h
++++ b/accessible/src/base/nsAccessibilityService.h
+@@ -41,16 +41,36 @@
+ 
+ #include "nsIAccessibilityService.h"
+ 
+ #include "a11yGeneric.h"
+ #include "nsAccDocManager.h"
+ 
+ #include "nsIObserver.h"
+ 
++namespace mozilla {
++namespace a11y {
++#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.
++ */
++PRBool ShouldA11yBeEnabled();
++#endif
++
++} // namespace a11y
++} // namespace mozilla
++
+ class nsAccessibilityService : public nsAccDocManager,
+                                public nsIAccessibilityService,
+                                public nsIObserver
+ {
+ public:
+   virtual ~nsAccessibilityService();
+ 
+   NS_DECL_ISUPPORTS_INHERITED
+diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
+--- a/widget/src/gtk2/nsWindow.cpp
++++ b/widget/src/gtk2/nsWindow.cpp
+@@ -103,29 +103,20 @@
+ #include "nsIStringBundle.h"
+ #include "nsGfxCIID.h"
+ #include "nsIObserverService.h"
+ 
+ #include "nsIdleService.h"
+ #include "nsIPropertyBag2.h"
+ 
+ #ifdef ACCESSIBILITY
+-#include "nsIAccessibilityService.h"
++#include "nsAccessibilityService.h"
+ #include "nsIAccessibleDocument.h"
+-#include "prenv.h"
+-#include "stdlib.h"
+ 
+ using namespace mozilla;
+-
+-static PRBool sAccessibilityChecked = 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";
+ #endif
+ 
+ /* For SetIcon */
+ #include "nsAppDirectoryServiceDefs.h"
+ #include "nsXPIDLString.h"
+ #include "nsIFile.h"
+ #include "nsILocalFile.h"
+ 
+@@ -1109,19 +1100,18 @@ nsWindow::Show(PRBool aState)
+             NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
+                          PR_FALSE);
+         } else if (mNeedsResize) {
+             NativeResize(mBounds.width, mBounds.height, PR_FALSE);
+         }
+     }
+ 
+ #ifdef ACCESSIBILITY
+-    if (aState && sAccessibilityEnabled) {
++    if (aState && a11y::ShouldA11yBeEnabled())
+         CreateRootAccessible();
+-    }
+ #endif
+ 
+     NativeShow(aState);
+ 
+     return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+@@ -3887,16 +3877,21 @@ nsWindow::Create(nsIWidget        *aPare
+     nsIWidget *baseParent = aInitData &&
+         (aInitData->mWindowType == eWindowType_dialog ||
+          aInitData->mWindowType == eWindowType_toplevel ||
+          aInitData->mWindowType == eWindowType_invisible) ?
+         nsnull : 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
++
+     // initialize all the common bits of this class
+     BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
+                aAppShell, aToolkit, aInitData);
+ 
+     // Do we need to listen for resizes?
+     PRBool listenForResizes = PR_FALSE;;
+     if (aNativeParent || (aInitData && aInitData->mListenForResizes))
+         listenForResizes = PR_TRUE;
+@@ -4278,43 +4273,16 @@ nsWindow::Create(nsIWidget        *aPare
+         LOG(("\tmGdkWindow %p %lx\n", (void *)mGdkWindow,
+              gdk_x11_window_get_xid(mGdkWindow)));
+     }
+ 
+     // resize so that everything is set to the right dimensions
+     if (!mIsTopLevel)
+         Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, PR_FALSE);
+ 
+-#ifdef ACCESSIBILITY
+-    nsresult rv;
+-    if (!sAccessibilityChecked) {
+-        sAccessibilityChecked = PR_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));
+-        }
+-        //check gconf-2 setting
+-        else {
+-            nsCOMPtr<nsIPrefBranch> sysPrefService =
+-                do_GetService(sSysPrefService, &rv);
+-            if (NS_SUCCEEDED(rv) && sysPrefService) {
+-
+-                // do the work to get gconf setting.
+-                // will be done soon later.
+-                sysPrefService->GetBoolPref(sAccessibilityKey,
+-                                            &sAccessibilityEnabled);
+-            }
+-
+-        }
+-    }
+-#endif
+-
+ #ifdef MOZ_DFB
+     if (!mDFB) {
+          DirectFBCreate( &mDFB );
+ 
+          D_ASSUME( mDFB != NULL );
+ 
+          if (mDFB)
+               mDFB->GetDisplayLayer( mDFB, DLID_PRIMARY, &mDFBLayer );
+@@ -6504,19 +6472,18 @@ nsWindow::DispatchAccessibleEvent()
+     DispatchEvent(&event, status);
+ 
+     return event.mAccessible;
+ }
+ 
+ void
+ nsWindow::DispatchEventToRootAccessible(PRUint32 aEventType)
+ {
+-    if (!sAccessibilityEnabled) {
++    if (!a11y::ShouldA11yBeEnabled())
+         return;
+-    }
+ 
+     nsCOMPtr<nsIAccessibilityService> accService =
+         do_GetService("@mozilla.org/accessibilityService;1");
+     if (!accService) {
+         return;
+     }
+ 
+     // Get the root document accessible and fire event to it.
--- a/series	Mon Nov 21 23:46:54 2011 +0100
+++ b/series	Tue Nov 29 15:56:24 2011 +0100
@@ -17,6 +17,7 @@
 mozilla-sle11.patch
 mozilla-linux3.patch
 mozilla-ppc64.patch
+mozilla-a11y.patch
 
 # Firefox patches
 firefox-browser-css.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xulrunner/mozilla-a11y.patch	Tue Nov 29 15:56:24 2011 +0100
@@ -0,0 +1,1 @@
+../mozilla-a11y.patch
\ No newline at end of file