Closed Bug 159306 Opened 22 years ago Closed 22 years ago

How to activate accessibility feature on linux and other unix platform

Categories

(Core :: Disability Access APIs, defect)

All
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: jay.yan, Assigned: yinbolian)

References

Details

(Whiteboard: need r=?)

Attachments

(1 file, 4 obsolete files)

Now we use this command line before start mozilla to activate accessibility feature:

export GTK_MODULE=MAI:ATK_BRIDGE     

It is not acceptable in the final release.

What will be the final way to activate the accessibility feature in Linux and
other Unix?
Blocks: 136315
->bolian
Assignee: aaronl → bolian.yin
The accepted method is to use gconf-2, via the gconf key 'accessibility'.

It can be set via gconftool; presumably we will have some other user dialog
which sets this key in later GNOME-2 releases.
I investigated gconf for a while. Here I have some questions about whether we
should use this tool to activate the accessibility feature.
As a configuration data storage mechanism, gconf has many advantages, such as: 
1. GConf offers a notification service, so applications can ask to be notified
when the value of a key changes. 
2. GConf is implemented as a per-user daemon, which makes locking a non-issue
and allows aggressive caching. 
3. GConf will ship with GNOME 2.
......
On Gnome 2, we can change some configuration parameters using gconf-editor
directly. But without gnome, we must install gconf at first. Since gconf depends
some libs, we must install gettext, popt, and so on. Is it convenient for
disabled users?
On the other hand, if we include gconf in mozilla source code just as Bill
suggested, we can activate the accessibility via gconftool-2 or gconf-editor.
But I don't think it's easier than exporting an environment variable for the end
users. :-(
Gconf can't exhibit its advantages here. Why not implement it in script? This
problem confused me. :( Looking forward to your comments. Thanks.
Jay discussed this problem with me just now. Below is the result.

Since we only provide accessibility feature on GNOME, we have no need to worry
about other desktop. Thus, we can check the "accessibility" key value in
mozilla. If it is "on" (or other value. Bill, has it been confirmed?), the
accessibility feature can be activated automatically. 

The detailed steps:
1. Set a new preference value for mozilla.
2. Since the required .so may not available on some users' system, for example
libgconf-2.so, we should not search it in during configuration. One method is
using PR_LoadLibrary dynamically. If fail to load, just give a warning message
and build a ordinary mozilla. If succeed, go to step 3.
3. Get the gnome accessibility key value via gconf. If "on" or "yes", activate
the accessibility feature. Otherwise, ignore it.

According to the above, mozilla need a new preference option and we need make
some changes in configure.in. I am not sure whether it will bother other mozilla
developers.

some supplements:

the "preference value of mozilla" which Silvia talked about does not modify
mozilla's UI, it will be added in
http://lxr.mozilla.org/mozilla/source/modules/libpref/src/unix/unix.js

such as adding:
pref("accessibility.gconf2.shared-library", "libgconf-2.so");

When mozilla starts up, it

......
1 get preference value of "accessibility.gconf2.shared-library", it will be
libgconf-2.so
2 load libgconf-2.so, if it successes, go to step 3, if failed, goto step 5
3 use gconf functions to detect "accessibility" gconf key, if it is "on", goto
step 4, if it is "off", goto step 5
4 activate accessibility feature
5 go on other initialization.
......

In this way, mozilla has runtime dependency on gconf, and can run on any desktop.

I think this modification is acceptable, Silvia, thanks for the investigation,
we can go on making the patch now. 

What are your opinion about this method? Aronl, Bill and Peter? is there any
potential risk?
sorry, a cirtical mistake in comment #5

"In this way, mozilla has runtime dependency on gconf, and can run on any desktop." 

should be

"In this way, mozilla has *no* runtime dependency on gconf, and can run on any
desktop."

==>Silvia
Assignee: bolian.yin → silvia.zhao
Status: NEW → ASSIGNED
Since GNOME 2.0 has the command-line utility gconftool-2 and it will always
be available for GNOME 2.0 dists it is not better to use this to obtain
the value of the gconf key so that there is absolutely no reliance on the 
libgconf library? Why introduce yet another dependency on a library? This is
how some other applications plan on doing it... Of course if the plan is that
Mozilla want's to store configuration in gconf too then that's another story :)

Also, the plan is to have a mechanism in GNOME2.0 to enable accessibility, is it
really necessary to also have this in Mozilla? The whole point is to have a 
central place to do this type of thing, introducing another UI element that does
this will only confuse the user ultimately.

Thanks Darren for the comments. perhaps there is some misunderstanding.

This bug is speaking about how mozilla will detect the value of accessibility
gconfkey: /desktop/gnome/interface/accessibility. it does not want to regester
new key in gnome.

comment #5 is speaking about a way which has *no dependency* with gconf
libirary, althought that way modifies native code and need compiling.

Accroding to comment #8, another way is to modify mozilla's startup script.
there we can use gconftool-2 to detect the value of
/desktop/gnome/interface/accessibility, if it is true, script will export
GTK_MODULE=MAI:ATK_BRIDGE before native paragram runs. 

Thanks Darren.
Hi Bolian, Jay, Silvio, and Darren:

In reply to comment #9, use of GTK_MODULES in the startup script 'might' be OK
but I see some problems.  In particular, accessibility should be loadable by
applications which use only gecko and not the whole Mozilla UI. 

But of course the accessibility code will not do anything useful on Linux and
Solaris unless GNOME is installed, so I agree that it's reasonable to assume
that gconf will be present.  But if there may be future cases where the
accessibility code needs to be enabled on a system that does not have gconf
running, you could export some other mozilla-specific environment variable such
as MOZILLA_ACCESSIBILITY=1, and use that to initiate loading the required
g_modules.  

I am not sure that the exact format of the string returned by gconftool-2 is
"supported API" and so I would be a little reluctant about using the commandline
tool rather than dynamically loading gconf.

The question I ask about how this will work for applications that re-use the
gecko component is important I think, what do we propose to do for these
applications?

-Bill
Whiteboard: need r=?
seek r/sr=?
I would like introduce the patch for a smooth review.

With this patch (attachment 100210 [details] [diff] [review]), we can have better a way to enable mozilla
accessibility, the way of using gconf-2.

In the system with gconf-2 installed, one can enable accessibility by
*gconftool-2 --set "/desktop/gnome/interface/accessibility" --type boolean "True"*
and get current seting of accessibility by
*gconftool-2 --get "/desktop/gnome/interface/accessibility"*

But, this only work when you have add two lines in your preference, unix.js (see
the patch):
pref("accessibility.unix.gconf2.shared-library", "libgconf-2.so");

On the system without gconf-2, no more action do than mormal case, because
Mozilla with check it and take care of it.

Another way to enable accessibility is set then environment variable
GNOME_ACCESSIBILITY to a non-zero value. This method need also need to add one
line in preference, unix.js:
pref("accessibility.unix.env", "GNOME_ACCESSIBILITY");

At the same times, the old way of setting *GTK_MODULES=mai:atk-bridge* can still
work. *gtk_init* will do that work, nothing needed to do in Mozilla to support it.

In fact, in the above patch, the first two methods use the third method indirectly.

==>Bolian
Assignee: silvia.zhao → bolian.yin
Status: ASSIGNED → NEW
Some comments here:

1.  I would like to generisize the gconf bits here if possible, if possible. 
Can we just create a new file called 'nsGConfInterface.h/cpp' and create an
easy-to-use api for getting gconf keys?  There are other keys that I would like
to be able to get down the road, and this would help a lot.  That would get all
of the library loading out of nsAppShell.cpp, which makes me feel a little funny.

How about some global functions like:

nsGConfInterface::Init()
nsGConfInterface::GetDefault();
nsGConfInterface::GetBool();

etc.

2.  The actual function pointers (*GconfClientGetBool) and
(*GconfClientGetDefault) need to have C calling conventions, so please wrap them
in an extern "C" if possible.  This probably doesn't bite us, but it might  bite
someone else.

3.  For a default gconf library name, we need to figure out what to do about
that.  For example, on my system it's going to be 'libgconf-2.so.4' and it
sounds like on your system it's just 'libgconf-2.so'.  We can do one of two things:

  a. Add a per-flatform prefs.js (solaris.js, linux.js) file to
modules/libpref/src/unix/ and modify modules/libpref/src/unix/Makefile.in to add
those .js files at install time.  There are other platforms that do this already.

  b. Hard code a default library name in the .cpp file and don't add a default
pref.  We can use a configure test to get the name of the gconf library.  Use a
pref as an override to the hard coded name.

I'm not sure what I want to do here.  There are advantages and disadvantages to
both.

4.  Modifying GTK_MODULES makes me really nervous.  Don't we have another way of
initializing all that code?  Remeber, we launch other programs from time to time
from Mozilla and they are going to try to load the mai module with that in the
environment.

5.  Calling shutdown_mai() from inside of nsAppShell::Exit() seems like a bad
idea to me.  The problem is that in embedded applications, we never actually
_run_ the appshell so Exit() is never called.  We need to add a callback from
the library shutdown.  You just need to add a callback from
nsWidgetGtk2ModuleDtor() in nsWidgetFactory.cpp to get this.  There's an easy
example in the gtk code for this.

6. Why is "GNOME_ACCESSIBILITY" even in the prefs file?  I would expect this to
be hard coded to whatever the GNOME standard is (assuming there is on, of course.)
Hi Blizzard, Thanks for your great and quick comments.   I will try to merge
them all.  :)

I'd like to give my idea about (3) and (4) points

3. In fact there is "libgconf-2.so", "libgconf-2.so.4" and "libgconf-2.so.4.1.0"
on my system, both "libgconf-2.so" and "libgconf-2.so.4" are soft link to
"libgconf-2.so.4.1.0".  I think, "libgconf-2.so" is the right default name to
use in mozilla, and the system will always link it to the right library.  So,
there is no need to split pref.js, adding "libgconf-2.so" will suffice.

4. Yes, there is other way of initializing mai/atk-bridge modules, that is to
duplicate the work that gtk does for GTK_MODULES in gtk_init. Another easy way
for us can be to restore GTK_MODULES to its old value after gtk_init.  But
before that, what you means by "we launch other programs from time to time from
Mozilla" ? the helpler applications?



Thanks
3.  I don't have a gconf library that just ends in .so on my system, so we need
to figure something out.  All these different plaforms have different naming
schemes for shared libraries.  (This is one of those rare moments when I long
for the simplicity of Windows.)

4.  Yes, I'm talking about helper applications.  How much code are we talking
about for initialization?
3. Ok, then we can use the method 3.b you suggested in comment #14. But I think,
we should not use configure test to get gconf2 lib name. Because the runing
environment maybe very different from the building environment, the name got in
configure may be unavailable when running.  So, how about hard code
"libgconf-2.so" and "libgconf-2.so.4" (and in that order), and use a pref as an
override.

4. less than 100 lines I think. But the most difficult part will be where to
find the library. Gtk can find libatk-bridge.so from its gtk-2.0/modules
directory. For example, if gtk is in /usr/local/gnome/lib, it will try to get
libatk-bridge.so from /usr/local/gnome/lib/gtk-2.0/modules. We need to fingure
out where to find it, if we load it ourself.  
   By the way, do you think restore GTK_MODULES value after calling gtk_init is
acceptable?  It will not affect other applications I think.
3.  We are in agreement on that.

4.  It suddenly occurred to me this still doesn't help with the embedding
situation where gtk_init() will already have been called and we don't get the
chance to re-load what's in GTK_MODULES.  We need to find another way to do this.
4. it seems we have to load it ourself. I will try to make it.
Attached patch patch_v2 (obsolete) — Splinter Review
need r/sr=,

In this patch, follow the discussion from comments #14 to comments #19.
In addition, I make the interface with MAI into files
(nsAccessibilityInterface.h/cpp), and this make it cleaner in other files.
Attachment #100210 - Attachment is obsolete: true
Attached patch sorry, missing the pref patch (obsolete) — Splinter Review
But, I am wondering the preference like this, without which it works, should be
added in trunk, or let users to added manunally?
Comment on attachment 100830 [details] [diff] [review]
patch_v2

>Index: Makefile.in
>===================================================================
>RCS file: /cvsroot/mozilla/widget/src/gtk2/Makefile.in,v
>retrieving revision 1.18
>diff -u -r1.18 Makefile.in
>--- Makefile.in	24 Sep 2002 01:37:14 -0000	1.18
>+++ Makefile.in	27 Sep 2002 03:14:53 -0000
>@@ -64,6 +64,8 @@
> 		nsClipboard.cpp \
> 		nsDragService.cpp \
> 		nsSound.cpp \
>+                nsAccessibilityInterface.cpp \
>+                nsGConfInterface.cpp \

I think you've got some tab/space issues here.

>Index: nsWidgetFactory.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWidgetFactory.cpp,v
>retrieving revision 1.11
>diff -u -r1.11 nsWidgetFactory.cpp
>--- nsWidgetFactory.cpp	24 Sep 2002 01:37:14 -0000	1.11
>+++ nsWidgetFactory.cpp	27 Sep 2002 03:14:54 -0000
>@@ -54,6 +54,10 @@
> #include "nsBidiKeyboard.h"
> #endif
> 
>+#ifdef ACCESSIBILITY
>+#include "nsAccessibilityInterface.h"
>+#endif
>+
> NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
> NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
> NS_GENERIC_FACTORY_CONSTRUCTOR(nsAppShell)
>@@ -192,6 +196,7 @@
> PR_STATIC_CALLBACK(void)
> nsWidgetGtk2ModuleDtor(nsIModule *aSelf)
> {
>+    nsAccessibilityInterface::ShutDown();

Does this need to be wrapped in an ACCESSIBILITY ifdef?
Attached patch patch_v3 (obsolete) — Splinter Review
Changes in this patch:
  1. correct errors pointed out in comments #22 (Thanks for blizzard :) )
  2. add pref (unix.js) changes into the patch also.
Hi blizzard, would you please review again?  Thanks.
--Bolian
Attachment #100830 - Attachment is obsolete: true
Attachment #100831 - Attachment is obsolete: true
Comment on attachment 100967 [details] [diff] [review]
patch_v3

Just a few more comments here, sorry.

>+static const char sPrefGConfKey[] = "accessibility.unix.gconf2.shared-library";
>+static const char sDefaultLibName1[] = "libgconf-2.so";
>+static const char sDefaultLibName2[] = "libgconf-2.so.4";

We should go from the most specific to least specific here.  You should reverse
the order of these two items.  Oh, and since the library is listed here you
don't need the pref at all.  In fact, if you did include the pref, given the
code below, it wouldn't work on Linux which was the entire point of listing
more than one library name. :)

>+    nsXPIDLCString gconfLibName;
>+    if (NS_FAILED(pref->GetCharPref(sPrefGConfKey,
>+                                    getter_Copies(gconfLibName)))) {
>+        LOG(("GConf library not specified in prefs, try the default: "
>+             "%s and %s\n", sDefaultLibName1, sDefaultLibName2));
>+        mGConfLib = PR_LoadLibrary(sDefaultLibName1);
>+        if (!mGConfLib)
>+            mGConfLib = PR_LoadLibrary(sDefaultLibName2);
>+    }
>+    else {
>+        //use the library name in the preference
>+        LOG(("GConf library in prefs is %s\n", gconfLibName.get()));
>+        mGConfLib = PR_LoadLibrary(gconfLibName.get());
>+    }

I'm really bothered by patterns like this.  Can you do something like:

nsresult rv;
rv = pref->GetCharName(..);
if (NS_SUCCEEDED(rv)) {
    [ load from prefs ]
}
else {
    [ load by library name ]
}

It's the fact that the failure is used in the if() block that bugs me.	That
and the test is broken away from the values created as part of the if().  Just
a style thing - I think it makes for more readable code.

Also, you could use a little more veritcal whitespace here.  Try to break your
code into logical paragraphs if possible.

Other than that, it's looking good!
Attached patch patch_v4Splinter Review
Hi, blizzard. You are right, it looks cleaner this time.  Thanks.
The preference patch is removed also.
Bother you to review again.
Attachment #100967 - Attachment is obsolete: true
Comment on attachment 101033 [details] [diff] [review]
patch_v4

r=blizzard
Attachment #101033 - Flags: review+
checked in Trunk. Thanks for everyone.
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: