mozilla-a11y.patch
changeset 358 b28670af14d5
child 369 04fc00b85b21
equal deleted inserted replaced
357:db07eb421d6b 358:b28670af14d5
       
     1 # HG changeset patch
       
     2 # User Michael Gorse <mgorse@suse.com>
       
     3 # Parent d02253d1e8217008dfa26e6e2a901b6a8b75e989
       
     4 a11y only enabled from Gnome 2's GConf setting
       
     5 https://bugzilla.novell.com/show_bug.cgi?id=732898
       
     6 https://bugzilla.mozilla.org/show_bug.cgi?id=693343
       
     7 
       
     8 diff --git a/accessible/src/atk/Makefile.in b/accessible/src/atk/Makefile.in
       
     9 --- a/accessible/src/atk/Makefile.in
       
    10 +++ b/accessible/src/atk/Makefile.in
       
    11 @@ -87,15 +87,19 @@ EXPORTS = \
       
    12  # we want to force the creation of a static lib.
       
    13  FORCE_STATIC_LIB = 1
       
    14  
       
    15  include $(topsrcdir)/config/rules.mk
       
    16  
       
    17  CFLAGS		+= $(MOZ_GTK2_CFLAGS)
       
    18  CXXFLAGS	+= $(MOZ_GTK2_CFLAGS)
       
    19  
       
    20 +ifdef MOZ_ENABLE_DBUS
       
    21 +CXXFLAGS += $(MOZ_DBUS_CFLAGS)
       
    22 +endif
       
    23 +
       
    24  LOCAL_INCLUDES += \
       
    25    -I$(srcdir) \
       
    26    -I$(srcdir)/../base \
       
    27    -I$(srcdir)/../html \
       
    28    -I$(srcdir)/../xul \
       
    29    -I$(topsrcdir)/other-licenses/atk-1.0 \
       
    30    $(NULL)
       
    31 diff --git a/accessible/src/atk/nsApplicationAccessibleWrap.cpp b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
       
    32 --- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
       
    33 +++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
       
    34 @@ -47,29 +47,27 @@
       
    35  #include "nsIPrefBranch.h"
       
    36  #include "nsIServiceManager.h"
       
    37  #include "nsAutoPtr.h"
       
    38  #include "nsAccessibilityService.h"
       
    39  #include "AtkSocketAccessible.h"
       
    40  
       
    41  #include <gtk/gtk.h>
       
    42  #include <atk/atk.h>
       
    43 +#include <dbus/dbus.h>
       
    44 +
       
    45 +using namespace mozilla::a11y;
       
    46  
       
    47  typedef GType (* AtkGetTypeType) (void);
       
    48  GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
       
    49 -static bool sATKChecked = false;
       
    50 +static PRBool sATKChecked = PR_FALSE;
       
    51  static PRLibrary *sATKLib = nsnull;
       
    52  static const char sATKLibName[] = "libatk-1.0.so.0";
       
    53  static const char sATKHyperlinkImplGetTypeSymbol[] =
       
    54      "atk_hyperlink_impl_get_type";
       
    55 -static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
       
    56 -static const char sSysPrefService [] =
       
    57 -    "@mozilla.org/system-preference-service;1";
       
    58 -static const char sAccessibilityKey [] =
       
    59 -    "config.use_system_prefs.accessibility";
       
    60  
       
    61  /* gail function pointer */
       
    62  static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
       
    63                                                   const gchar *event_type);
       
    64  static void (* gail_remove_global_event_listener) (guint remove_listener);
       
    65  static void (* gail_remove_key_event_listener) (guint remove_listener);
       
    66  static AtkObject * (*gail_get_root) (void);
       
    67  
       
    68 @@ -609,36 +607,17 @@ toplevel_event_watcher(GSignalInvocation
       
    69    }
       
    70  
       
    71    return TRUE;
       
    72  }
       
    73  
       
    74  PRBool
       
    75  nsApplicationAccessibleWrap::Init()
       
    76  {
       
    77 -    // XXX following code is copied from widget/src/gtk2/nsWindow.cpp
       
    78 -    // we should put it to somewhere that can be used from both modules
       
    79 -    // see bug 390761
       
    80 -
       
    81 -    // check if accessibility enabled/disabled by environment variable
       
    82 -    PRBool isGnomeATEnabled = PR_FALSE;
       
    83 -    const char *envValue = PR_GetEnv(sAccEnv);
       
    84 -    if (envValue) {
       
    85 -        isGnomeATEnabled = !!atoi(envValue);
       
    86 -    } else {
       
    87 -        //check gconf-2 setting
       
    88 -        nsresult rv;
       
    89 -        nsCOMPtr<nsIPrefBranch> sysPrefService =
       
    90 -            do_GetService(sSysPrefService, &rv);
       
    91 -        if (NS_SUCCEEDED(rv) && sysPrefService) {
       
    92 -            sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
       
    93 -        }
       
    94 -    }
       
    95 -
       
    96 -    if (isGnomeATEnabled) {
       
    97 +    if (ShouldA11yBeEnabled()) {
       
    98          // load and initialize gail library
       
    99          nsresult rv = LoadGtkModule(sGail);
       
   100          if (NS_SUCCEEDED(rv)) {
       
   101              (*sGail.init)();
       
   102          }
       
   103          else {
       
   104              MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
       
   105          }
       
   106 @@ -877,8 +856,129 @@ LoadGtkModule(GnomeAccessibilityModule& 
       
   107                         aModule.init ? aModule.shutdownName : aModule.initName,
       
   108                         aModule.libName));
       
   109          PR_UnloadLibrary(aModule.lib);
       
   110          aModule.lib = NULL;
       
   111          return NS_ERROR_FAILURE;
       
   112      }
       
   113      return NS_OK;
       
   114  }
       
   115 +
       
   116 +namespace mozilla {
       
   117 +namespace a11y {
       
   118 +
       
   119 +#ifdef MOZ_ENABLE_DBUS
       
   120 +static DBusPendingCall *a11yPendingCall = NULL;
       
   121 +#endif
       
   122 +
       
   123 +void
       
   124 +PreInit()
       
   125 +{
       
   126 +  static PRBool sChecked = FALSE;
       
   127 +  if (sChecked)
       
   128 +    return;
       
   129 +  sChecked = TRUE;
       
   130 +  DBusError error;
       
   131 +  dbus_error_init(&error);
       
   132 +  DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
       
   133 +  if (!bus)
       
   134 +    return;
       
   135 +  dbus_connection_set_exit_on_disconnect(bus, FALSE);
       
   136 +
       
   137 +  DBusMessage *message;
       
   138 +  message = dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus",
       
   139 +                                         "org.freedesktop.DBus.Properties",
       
   140 +                                         "Get");
       
   141 +  if (!message)
       
   142 +    goto dbus_done;
       
   143 +
       
   144 +  static const char* iface = "org.a11y.Status";
       
   145 +  static const char* member = "IsEnabled";
       
   146 +  dbus_message_append_args(message, DBUS_TYPE_STRING, &iface,
       
   147 +                           DBUS_TYPE_STRING, &member, DBUS_TYPE_INVALID);
       
   148 +  dbus_connection_send_with_reply(bus, message, &a11yPendingCall, 1000);
       
   149 +
       
   150 +dbus_done:
       
   151 +  if (message)
       
   152 +    dbus_message_unref(message);
       
   153 +  if (bus)
       
   154 +    dbus_connection_unref(bus);
       
   155 +  dbus_error_free(&error);
       
   156 +}
       
   157 +
       
   158 +PRBool
       
   159 +ShouldA11yBeEnabled()
       
   160 +{
       
   161 +  static PRBool sChecked = PR_FALSE, sShouldEnable = PR_FALSE;
       
   162 +  if (sChecked)
       
   163 +    return sShouldEnable;
       
   164 +
       
   165 +  sChecked = PR_TRUE;
       
   166 +
       
   167 +  // check if accessibility enabled/disabled by environment variable
       
   168 +  static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
       
   169 +  const char* envValue = PR_GetEnv(sAccEnv);
       
   170 +  if (envValue)
       
   171 +    return sShouldEnable = !!atoi(envValue);
       
   172 +
       
   173 +#ifdef MOZ_ENABLE_DBUS
       
   174 +  PreInit();
       
   175 +  PRBool dbusSuccess = PR_FALSE;
       
   176 +  DBusMessage *reply = nsnull;
       
   177 +  if (a11yPendingCall) {
       
   178 +    dbus_pending_call_block(a11yPendingCall);
       
   179 +    reply = dbus_pending_call_steal_reply(a11yPendingCall);
       
   180 +    dbus_pending_call_unref(a11yPendingCall);
       
   181 +    a11yPendingCall = nsnull;
       
   182 +  }
       
   183 +  if (!reply ||
       
   184 +      dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN ||
       
   185 +      strcmp(dbus_message_get_signature (reply), "v"))
       
   186 +    goto dbus_done;
       
   187 +
       
   188 +  DBusMessageIter iter, iter_variant, iter_struct;
       
   189 +  dbus_bool_t dResult;
       
   190 +  dbus_message_iter_init(reply, &iter);
       
   191 +  dbus_message_iter_recurse (&iter, &iter_variant);
       
   192 +  switch (dbus_message_iter_get_arg_type(&iter_variant)) {
       
   193 +    case DBUS_TYPE_STRUCT:
       
   194 +      // at-spi2-core 2.2.0-2.2.1 had a bug where it returned a struct
       
   195 +      dbus_message_iter_recurse(&iter_variant, &iter_struct);
       
   196 +      if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {
       
   197 +        dbus_message_iter_get_basic(&iter_struct, &dResult);
       
   198 +        sShouldEnable = dResult;
       
   199 +        dbusSuccess = true;
       
   200 +      }
       
   201 +
       
   202 +      break;
       
   203 +    case DBUS_TYPE_BOOLEAN:
       
   204 +      dbus_message_iter_get_basic(&iter_variant, &dResult);
       
   205 +      sShouldEnable = dResult;
       
   206 +      dbusSuccess = true;
       
   207 +      break;
       
   208 +    default:
       
   209 +      break;
       
   210 +  }
       
   211 +
       
   212 +  dbus_done:
       
   213 +  if (reply)
       
   214 +    dbus_message_unref(reply);
       
   215 +
       
   216 +  if (dbusSuccess)
       
   217 +    return sShouldEnable;
       
   218 +#endif
       
   219 +
       
   220 +  //check gconf-2 setting
       
   221 +  nsresult rv = NS_OK;
       
   222 +  static const char sSysPrefService [] =
       
   223 +    "@mozilla.org/system-preference-service;1";
       
   224 +  static const char sAccessibilityKey [] =
       
   225 +    "config.use_system_prefs.accessibility";
       
   226 +  nsCOMPtr<nsIPrefBranch> sysPrefService =
       
   227 +    do_GetService(sSysPrefService, &rv);
       
   228 +  if (NS_SUCCEEDED(rv) && sysPrefService)
       
   229 +    sysPrefService->GetBoolPref(sAccessibilityKey, &sShouldEnable);
       
   230 +
       
   231 +  return sShouldEnable;
       
   232 +}
       
   233 +} // namespace a11y
       
   234 +} // namespace mozilla
       
   235 +
       
   236 diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h
       
   237 --- a/accessible/src/base/nsAccessibilityService.h
       
   238 +++ b/accessible/src/base/nsAccessibilityService.h
       
   239 @@ -41,16 +41,36 @@
       
   240  
       
   241  #include "nsIAccessibilityService.h"
       
   242  
       
   243  #include "a11yGeneric.h"
       
   244  #include "nsAccDocManager.h"
       
   245  
       
   246  #include "nsIObserver.h"
       
   247  
       
   248 +namespace mozilla {
       
   249 +namespace a11y {
       
   250 +#ifdef MOZ_ACCESSIBILITY_ATK
       
   251 +/**
       
   252 + * Perform initialization that should be done as soon as possible, in order
       
   253 + * to minimize startup time.
       
   254 + * XXX: this function and the next defined in nsApplicationAccessibleWrap.cpp
       
   255 + */
       
   256 +void PreInit();
       
   257 +
       
   258 +/**
       
   259 + * Is platform accessibility enabled.
       
   260 + * Only used on linux with atk for now.
       
   261 + */
       
   262 +PRBool ShouldA11yBeEnabled();
       
   263 +#endif
       
   264 +
       
   265 +} // namespace a11y
       
   266 +} // namespace mozilla
       
   267 +
       
   268  class nsAccessibilityService : public nsAccDocManager,
       
   269                                 public nsIAccessibilityService,
       
   270                                 public nsIObserver
       
   271  {
       
   272  public:
       
   273    virtual ~nsAccessibilityService();
       
   274  
       
   275    NS_DECL_ISUPPORTS_INHERITED
       
   276 diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
       
   277 --- a/widget/src/gtk2/nsWindow.cpp
       
   278 +++ b/widget/src/gtk2/nsWindow.cpp
       
   279 @@ -103,29 +103,20 @@
       
   280  #include "nsIStringBundle.h"
       
   281  #include "nsGfxCIID.h"
       
   282  #include "nsIObserverService.h"
       
   283  
       
   284  #include "nsIdleService.h"
       
   285  #include "nsIPropertyBag2.h"
       
   286  
       
   287  #ifdef ACCESSIBILITY
       
   288 -#include "nsIAccessibilityService.h"
       
   289 +#include "nsAccessibilityService.h"
       
   290  #include "nsIAccessibleDocument.h"
       
   291 -#include "prenv.h"
       
   292 -#include "stdlib.h"
       
   293  
       
   294  using namespace mozilla;
       
   295 -
       
   296 -static PRBool sAccessibilityChecked = PR_FALSE;
       
   297 -/* static */
       
   298 -PRBool nsWindow::sAccessibilityEnabled = PR_FALSE;
       
   299 -static const char sSysPrefService [] = "@mozilla.org/system-preference-service;1";
       
   300 -static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
       
   301 -static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility";
       
   302  #endif
       
   303  
       
   304  /* For SetIcon */
       
   305  #include "nsAppDirectoryServiceDefs.h"
       
   306  #include "nsXPIDLString.h"
       
   307  #include "nsIFile.h"
       
   308  #include "nsILocalFile.h"
       
   309  
       
   310 @@ -1109,19 +1100,18 @@ nsWindow::Show(PRBool aState)
       
   311              NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
       
   312                           PR_FALSE);
       
   313          } else if (mNeedsResize) {
       
   314              NativeResize(mBounds.width, mBounds.height, PR_FALSE);
       
   315          }
       
   316      }
       
   317  
       
   318  #ifdef ACCESSIBILITY
       
   319 -    if (aState && sAccessibilityEnabled) {
       
   320 +    if (aState && a11y::ShouldA11yBeEnabled())
       
   321          CreateRootAccessible();
       
   322 -    }
       
   323  #endif
       
   324  
       
   325      NativeShow(aState);
       
   326  
       
   327      return NS_OK;
       
   328  }
       
   329  
       
   330  NS_IMETHODIMP
       
   331 @@ -3887,16 +3877,21 @@ nsWindow::Create(nsIWidget        *aPare
       
   332      nsIWidget *baseParent = aInitData &&
       
   333          (aInitData->mWindowType == eWindowType_dialog ||
       
   334           aInitData->mWindowType == eWindowType_toplevel ||
       
   335           aInitData->mWindowType == eWindowType_invisible) ?
       
   336          nsnull : aParent;
       
   337  
       
   338      NS_ASSERTION(!mWindowGroup, "already have window group (leaking it)");
       
   339  
       
   340 +#ifdef ACCESSIBILITY
       
   341 +    // Send a DBus message to check whether a11y is enabled
       
   342 +    a11y::PreInit();
       
   343 +#endif
       
   344 +
       
   345      // initialize all the common bits of this class
       
   346      BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
       
   347                 aAppShell, aToolkit, aInitData);
       
   348  
       
   349      // Do we need to listen for resizes?
       
   350      PRBool listenForResizes = PR_FALSE;;
       
   351      if (aNativeParent || (aInitData && aInitData->mListenForResizes))
       
   352          listenForResizes = PR_TRUE;
       
   353 @@ -4278,43 +4273,16 @@ nsWindow::Create(nsIWidget        *aPare
       
   354          LOG(("\tmGdkWindow %p %lx\n", (void *)mGdkWindow,
       
   355               gdk_x11_window_get_xid(mGdkWindow)));
       
   356      }
       
   357  
       
   358      // resize so that everything is set to the right dimensions
       
   359      if (!mIsTopLevel)
       
   360          Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, PR_FALSE);
       
   361  
       
   362 -#ifdef ACCESSIBILITY
       
   363 -    nsresult rv;
       
   364 -    if (!sAccessibilityChecked) {
       
   365 -        sAccessibilityChecked = PR_TRUE;
       
   366 -
       
   367 -        //check if accessibility enabled/disabled by environment variable
       
   368 -        const char *envValue = PR_GetEnv(sAccEnv);
       
   369 -        if (envValue) {
       
   370 -            sAccessibilityEnabled = atoi(envValue) != 0;
       
   371 -            LOG(("Accessibility Env %s=%s\n", sAccEnv, envValue));
       
   372 -        }
       
   373 -        //check gconf-2 setting
       
   374 -        else {
       
   375 -            nsCOMPtr<nsIPrefBranch> sysPrefService =
       
   376 -                do_GetService(sSysPrefService, &rv);
       
   377 -            if (NS_SUCCEEDED(rv) && sysPrefService) {
       
   378 -
       
   379 -                // do the work to get gconf setting.
       
   380 -                // will be done soon later.
       
   381 -                sysPrefService->GetBoolPref(sAccessibilityKey,
       
   382 -                                            &sAccessibilityEnabled);
       
   383 -            }
       
   384 -
       
   385 -        }
       
   386 -    }
       
   387 -#endif
       
   388 -
       
   389  #ifdef MOZ_DFB
       
   390      if (!mDFB) {
       
   391           DirectFBCreate( &mDFB );
       
   392  
       
   393           D_ASSUME( mDFB != NULL );
       
   394  
       
   395           if (mDFB)
       
   396                mDFB->GetDisplayLayer( mDFB, DLID_PRIMARY, &mDFBLayer );
       
   397 @@ -6504,19 +6472,18 @@ nsWindow::DispatchAccessibleEvent()
       
   398      DispatchEvent(&event, status);
       
   399  
       
   400      return event.mAccessible;
       
   401  }
       
   402  
       
   403  void
       
   404  nsWindow::DispatchEventToRootAccessible(PRUint32 aEventType)
       
   405  {
       
   406 -    if (!sAccessibilityEnabled) {
       
   407 +    if (!a11y::ShouldA11yBeEnabled())
       
   408          return;
       
   409 -    }
       
   410  
       
   411      nsCOMPtr<nsIAccessibilityService> accService =
       
   412          do_GetService("@mozilla.org/accessibilityService;1");
       
   413      if (!accService) {
       
   414          return;
       
   415      }
       
   416  
       
   417      // Get the root document accessible and fire event to it.