After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 354970 - Support customization of key and braille bindings
Support customization of key and braille bindings
Status: RESOLVED FIXED
Product: orca
Classification: Applications
Component: general
1.0.x
Other All
: Normal enhancement
: 2.18.0
Assigned To: Willie Walker
Orca Maintainers
Depends on:
Blocks:
 
 
Reported: 2006-09-08 14:20 UTC by Willie Walker
Modified: 2008-07-22 19:20 UTC
See Also:
GNOME target: ---
GNOME version: 2.15/2.16


Attachments
Patch to apply part one of the proposal (45.68 KB, patch)
2006-09-09 23:54 UTC, Willie Walker
committed Details | Review
New method for keybindings.KeyBindings (1.05 KB, patch)
2006-09-19 15:49 UTC, Jorge Sandín
none Details | Review
Method for getting BrlTTY command code (in script.py Script) (853 bytes, patch)
2006-09-25 12:19 UTC, Jorge Sandín
none Details | Review
Patch to combine the two previous patches (2.13 KB, patch)
2006-09-26 08:21 UTC, Willie Walker
committed Details | Review
Common human-readable i18n names for used BrlTTY commands (1.02 KB, patch)
2006-09-27 10:03 UTC, Jorge Sandín
committed Details | Review
Patch to show Orca default keybindings in a new tab (3.73 KB, patch)
2006-10-31 13:03 UTC, Jorge Sandín
none Details | Review
Patch to show Orca default keybindings in a new tab (20.00 KB, patch)
2006-11-02 09:20 UTC, Jorge Sandín
none Details | Review
Revised keybinding list patch (30.00 KB, patch)
2006-11-16 17:28 UTC, Jorge Sandín
none Details | Review
Slightly modified patch (31.04 KB, patch)
2006-11-17 02:31 UTC, Willie Walker
committed Details | Review
Patch to enable key binding editing by the user (in the GUI) (29.02 KB, patch)
2006-12-07 12:40 UTC, Jorge Sandín
none Details | Review
User Key Bindings Editing Feature (29.56 KB, patch)
2006-12-12 13:00 UTC, Jorge Sandín
none Details | Review
Jorge's patch with a few minor edits (33.78 KB, patch)
2006-12-13 01:25 UTC, Willie Walker
committed Details | Review

Description Willie Walker 2006-09-08 14:20:33 UTC
PRIMARY GOALS:

1) Provide infrastructure to more easily allow key and braille
   bindings to be specified/configured via a GUI.

2) Support the notion of "drop in" key and braille bindings files to
   allow people to share bindings for different keyboard layouts
   (e.g., laptops) and locales.


BACKGROUND:

Each script can have its own set of key and braille bindings.
Currently, default.py provides the bulk of them, but sub-scripts such
as the one for StarOffice provide new key bindings for things such as
getting the formula for a spread sheet cell.

The key and braille bindings bind a user action (a keystroke or a
braille input device event) to an input event handler.  The input
handlers are set up in the script's setupInputEventHandlers method,
and the bindings are set up in the script's getKeyBindings and
getBrailleBindings methods.

Examples from default.py include:

    def setupInputEventHandlers(self):
        ...
        self.reviewAboveHandler = input_event.InputEventHandler(
            Script.reviewAbove,
            _("Moves flat review to the word above the current word."))
	...

    def getKeyBindings(self):
	...
        keyBindings = script.Script.getKeyBindings(self)
	...
        keyBindings.add(
            keybindings.KeyBinding(
                "KP_4",
                1 << settings.MODIFIER_ORCA,
                1 << settings.MODIFIER_ORCA,
                self.reviewAboveHandler))
	...
	return keyBindings

    def getBrailleBindings(self):
	...
        brailleBindings = script.Script.getBrailleBindings(self)
	...
        brailleBindings[braille.CMD_LNUP]     = self.reviewAboveHandler
	...
        return brailleBindings

    
PROPOSAL PART ONE:

To make things nicer on folks providing configuration GUIs, we might
want to consider using a dictionary to hold the input event handlers.
This will allow for the easy enumeration of all possible input event
handlers supported by a script (and also allows for the addition of
custom input event handlers, if so desired).  For example, instead of
the following in setupInputEventHandlers:

        self.reviewAboveHandler = input_event.InputEventHandler(
            Script.reviewAbove,
            _("Moves flat review to the word above the current word."))

We'd have:

        self.inputHandlers["reviewAboveHandler"] = \
	    input_event.InputEventHandler(
                Script.reviewAbove,
                _("Moves flat review to the word above the current word."))

Then in getKeyBindings and getBrailleBindings, we'd have:

        keyBindings.add(
            keybindings.KeyBinding(
                "KP_4",
                1 << settings.MODIFIER_ORCA,
                1 << settings.MODIFIER_ORCA,
                self.inputHandlers["reviewAboveHandler"]))

        brailleBindings[braille.CMD_LNUP] = \
            self.inputHandlers["reviewAboveHandler"]

For helping with internationalization, we might want to add a name field
to the input event handler.  This name field would be a localized human
consumable form (e.g., _("Left Click Review Item")).


PROPOSAL PART TWO:

The next step in the proposal is to allow the default keybindings to
be extended/modified/overridden.  A possible way to do this would be
to have ~/.orca/user-customizations.py set a getKeyBindings method in
orca.settings (assume the same for getBrailleBindings in the rest of
this document).  This method and its use would live in
user-customizations.py and would look something like the following:

def getKeyBindings(script):
    keyBindings = orca.keybindings.KeyBindings()
    keyBindings.add(orca.keybindings.KeyBinding(
        "Some X_Keysym",
        modifier_mask,
        modifiers,
        script.inputHandlers["inputHandlerName"]))
    ...
    return keyBindings

orca.settings.getKeyBindings = getKeyBindings 

This method could also provide some logic to know what script it was
dealing with if need be (e.g., to provide different custom bindings for
StarOffice).

default.py:getKeyBindings would then have some logic along the following
lines at the very top:

    def getKeyBindings(self):
        # Defer to the settings module to override keybindings if so 
        # desired.
        #
        try:
            return settings.getKeyBindings(self)
        except:
            pass

        (rest of code here)

The drawback of this approach is that it requires *all* the
keybindings to be set up in the customizations file.  It might be more
desirable to move the customization stuff to the end, renaming the
settings.getKeyBindings method to settings.overrideKeyBindings or
something like that:

    def getKeyBindings(self):
	...
        keyBindings = script.Script.getKeyBindings(self)
	...

        (default bindings set here)

        try:
            settings.overrideKeyBindings(self, keyBindings)
        except:
            pass

	return keyBindings

To allow the overrideKeyBindings method to be more effective, however,
we'd need to provide some mechanism to obtain a keyBinding given an
InputEventHandler (or InputEventHandler name).  A
not-well-though-out-idea of how this could be done is via a brute
force search to start with, and could be handled via new methods such
as 'getKeyBinding(keyBindings, InputEventHandler)' and
'getBrailleBinding(brailleBindings, InputEventHandler)'.  These
methods would merely search for the given InputEventHandler in the
given bindings and return the one that matched.  One could then delete
the existing InputEventHandler from the given bindings and replace it
with a new one (if so desired).
Comment 1 Willie Walker 2006-09-09 23:54:38 UTC
Created attachment 72472 [details] [review]
Patch to apply part one of the proposal

This patch applies part one of the proposal.  Since this is a rather substantial change, assuming people agree with this patch, I think we may need to do it earlier than later in the GNOME 2.17 cycle.
Comment 2 Willie Walker 2006-09-12 12:50:30 UTC
Patch to refactor the way key and braille bindings are created and managed committed.  Still need to work on th second part of the proposal, which is to allow customizations to determine the key and braille bindings given an input event handler.
Comment 3 Jorge Sandín 2006-09-19 15:49:47 UTC
Created attachment 73039 [details] [review]
New method for keybindings.KeyBindings

As various KeyBinding can have the same InputEventHandler associated, this new method of KeyBindings returs a KeyBindings object, that contains all the KeyBinding that matches the same handler function than the one in the InputEventHandler passed as argument.

This could be needed from the (soon-coming) key redefinition GUI section.
Comment 4 Jorge Sandín 2006-09-25 12:19:34 UTC
Created attachment 73358 [details] [review]
Method for getting BrlTTY command code (in script.py Script)

New script.py Script method for getting a BrlTTY command code from a brailleBinding dictionary entry (in a specific app script instance).
Comment 5 Willie Walker 2006-09-26 08:21:25 UTC
Created attachment 73416 [details] [review]
Patch to combine the two previous patches

This patch combines the two previous patches and keeps the logic for both in script.py.  The patch renames things a little bit for consistency and also uses existing bindings (e.g., self.keyBindings) for the script rather than creating new ones (e.g., self.getKeyBindings()).  The new methods added are:

getKeyBindingsForInputHandler
getBrailleCommandsForInputHandler
Comment 6 Willie Walker 2006-09-26 16:52:41 UTC
Comment on attachment 73416 [details] [review]
Patch to combine the two previous patches

Submitted this patch with one fix suggested by Jorge (thanks Jorge): 

for binding in self.keyBindings.keyBindings:
Comment 7 Jorge Sandín 2006-09-27 10:03:34 UTC
Created attachment 73483 [details] [review]
Common human-readable i18n names for used BrlTTY commands

Dictionary in braille.py to provide a human-readable name (i18n) to used BrlTTY codes in default.py script. To be shown in the GUI for Braille redefinition.
Comment 8 Willie Walker 2006-10-15 00:25:54 UTC
Add accessibility keyword.  Apologies for spam.
Comment 9 Jorge Sandín 2006-10-31 13:03:41 UTC
Created attachment 75721 [details] [review]
Patch to show Orca default keybindings in a new tab

Preliminary patch to show in a new tab of the GUI all the Orca default keybindings as a list. The handler description with their associated keybindings.

ATM it's not possible to modify them.
Only Orca default keybindings are shown (as a list), in the future also apps specific keybindings will be shown (as a treeview).
Comment 10 Willie Walker 2006-10-31 14:08:25 UTC
Hi Jorge:  Thanks for the patch!  What kind of file is this?  It's coming through as some sort of binary file whose content Firefox displays in a new window versus asking me if I want to save it.
Comment 11 Jorge Sandín 2006-11-02 09:20:21 UTC
Created attachment 75825 [details] [review]
Patch to show Orca default keybindings in a new tab

The previous patch, but uploaded in a plain .tar file, instead of a .tar.bz2 file that messed it up, sorry for that, let's hope this time it's ok :)
-------------
Preliminary patch to show in a new tab of the GUI all the Orca default
keybindings as a list. The handler description with their associated
keybindings.

ATM it's not possible to modify them.
Only Orca default keybindings are shown (as a list), in the future also apps
specific keybindings will be shown (as a treeview).
-------------
Comment 12 Willie Walker 2006-11-15 18:28:25 UTC
Jorge: I finally had a chance to take a look at this.  With one minor fix (I needed to comment out a line that referred to "editinKey" the patched orca_gui_prefs.py), I got it working.

I think this is a good patch:  even if it doesn't let you change the key bindings and even if it doesn't show app-specific bindings, it serves a very good purpose.  That purpose is to provide a very convenient mechanism for people to discover what the Orca keybindings are.

Rich, Mike, Lynn: should we shoot for getting this functionality in for 2.17.3?  The things that would need to be addressed are:

1) A code review
2) A little cleanup (i.e., removing empty whitespace here and there)
3) Moving the keybindings tab to the last position?
Comment 13 Willie Walker 2006-11-15 19:43:02 UTC
I think you should continue moving forward with the patch, with the following suggestions:

0) Make the "KeyBindings" tab say something like "Key Bindings" (i.e., add a space) and put it at the end of the tab order.

1) Don't force the the Orca modifier to "Ins+".  Instead, in keybindings.py, check for "mods & 256" and then use the first list item from settings.orcaModifiers.  If you want to get tricky, you could compose a nerdy style string using all the modifiers in the list, such as "{Insert,KP_Insert}+", but this may be too tricky and actually kind of cumbersome when it comes to speech output.  Maybe listing the Orca modifier list separate from the table might be a better thing to do.

2) If it's possible to order the bindings, it would be great to put the Function keys (e.g., F10, etc.) at the bottom and the keypad keys (i.e., KP_*) and arrow keys at the top.

3) When one hits the "Apply" button now after changing the bindings from laptop to desktop and vice versa, the bindings table should be recalculated accordingly.
 
This is actually a very exciting patch to me.  I see it helping answer one of our top FAQs, which is "what are the Orca key bindings?"
Comment 14 Mike Pedersen 2006-11-15 20:42:38 UTC
I agree with Will here.  I think we should include this functionality as soon as possible.  It is also the beginning to a tool that will be very powerful for creating custom key bindings in the future.  Thanks much for the contribution.  
Comment 15 Rich Burridge 2006-11-15 22:29:59 UTC
I too agree that this should go in as soon as possible to work 
out any remaining kinks. Thanks for the patch.
Comment 16 Jorge Sandín 2006-11-16 17:28:28 UTC
Created attachment 76709 [details] [review]
Revised keybinding list patch

Patch to show Orca default keybindings in a new tab, with Willie suggestions fixed:

* Keybindings tab as "Key Bindings", in the last position.
* Real Orca modifier key list used.
* Keybindings ordered by default.
* Apply button updates keybinding list and orca modifier keys list.

Also a small fix in magnifier GUI to display it correctly with the new dialog size.

Anything else that you want to be changed just tell me :)
Comment 17 Willie Walker 2006-11-17 02:31:23 UTC
Created attachment 76741 [details] [review]
Slightly modified patch

The previous patch looked great.  I modified the patch slightly to format the Python code within 80 character limits, use constants where possible, change "OrcaMod." string to "Orca", and eliminate the extra space prior to the keystring.  It's checked in.  Thanks!
Comment 18 Mike Pedersen 2006-11-17 16:05:29 UTC
This is going to be a really useful feature.  A couple things I've noticed so far.  
1. Do we really need to hear both states of the Keypad ie for Keypad 3 we hear both KP3 and KP end"  I think just hearing what the key would be if numlock was off would be enough.  
2.  It would be nice if the ordering of keys could be a little more logical.  For example, it would be good to have the keys that increase or decrease the speech rate grouped together. 
thanks much 
Comment 19 Jorge Sandín 2006-12-07 12:40:13 UTC
Created attachment 77884 [details] [review]
Patch to enable key binding editing by the user (in the GUI)

Patch to enable editing of the list of key bindings by the user.

* Change the List model to a Treeview.
* The changes are persistent (when apply/acept button is clicked, the modified key bindings are saved in the ~/.orca/user-settings.py file)
* Include a list of braille bindings (not editable)

The patch should be revised before getting it into the CVS... And there are still some things to be improved (to delete an already modified keybinding you have to access the file directly, which is not a good idea for the final user)
Comment 20 Willie Walker 2006-12-08 18:38:27 UTC
Jorge:

> Patch to enable editing of the list of key bindings by the user.

I finally had a chance to look at this patch.  It looks like you're almost there and I'm tempted to check it in with very minor modifications (i.e., removing an 'import sys' that doesn't need to be there).   Invoking/cancelling the keystroke recording seems pretty intuitive to me and I think it's cool that you got it working.

I'm curious about why you removed the "Meta" and "Caps_Lock" strings from keybindings.py:getModifierNames?

> The patch should be revised before getting it into the CVS... 

What things would you like further review on or to make revisions to?

> And there are
> still some things to be improved (to delete an already modified keybinding you
> have to access the file directly, which is not a good idea for the final user)

I'm not sure if it is possible, but would you be able to compare the binding and function to the default one and not write it out to user-settings.py if they are the same?

In addition, it might be nice to have a button somewhere that allows the user to revert a binding to the default value.  

In any case, I think this looks pretty good.  If you'd like, I'm happy to check it in.  I can also wait a little longer if you'd like to refine it some more.  The big deadlines to get this in are Dec 18 and Jan 22.  After that, it'll become harder to get them in and we'll probably need to wait until GNOME 2.20.
Comment 21 Jorge Sandín 2006-12-12 13:00:00 UTC
Created attachment 78201 [details] [review]
User Key Bindings Editing Feature

Updated patch for the edition of Key Bindings:

> I finally had a chance to look at this patch.  It looks like you're almost
> there and I'm tempted to check it in with very minor modifications (i.e.,
> removing an 'import sys' that doesn't need to be there).   Invoking/cancelling
> the keystroke recording seems pretty intuitive to me and I think it's cool that
> you got it working.

Great! I've moved that "import sys" to the begining of the file (it was a test), and clean few other things.

New improvements:

* Now it's possible to unmark a key binding modification in the GUI as a check box, now they work! :), so the default Orca key binding can be restored easily from the GUI.


> I'm curious about why you removed the "Meta" and "Caps_Lock" strings from
> keybindings.py:getModifierNames?

Well, in my spanish keyboard layout at least, I always get the META modifier when Num_Lock is enabled, it's strange, I removed that to avoid seeing it in the list in every keybinding, as it's not relevant... I'm not sure why happens that here. Other thing I've notice is that I cannot get 'KP_5' (I get just '5' instead).


> What things would you like further review on or to make revisions to?

Nothing in particular, if you think it's good/useful enough to be checked in, for me it's great :)


> I'm not sure if it is possible, but would you be able to compare the binding
> and function to the default one and not write it out to user-settings.py if
> they are the same?

Yes, that's already done at capturing time, it needs to have a different key or  modifiers to be captured.


> In addition, it might be nice to have a button somewhere that allows the user
> to revert a binding to the default value.

That's done now, perhaps it's not the most intuitive way of doing it, but it's simple (almost no extra code) and it works fine, if you have any better idea about how to do that just tell me and I'll try to do it.


> The big deadlines to get this in are Dec 18 and Jan 22.  After that, it'll
> become harder to get them in and we'll probably need to wait until GNOME 2.20.

Ok, it's ready I think, and we've got still some days to try it, I'm only worried about the gtk warnings it shows in the console when dealing with the treeview.

Anything, just tell me :)

Jorge.
Comment 22 Willie Walker 2006-12-13 01:25:40 UTC
Created attachment 78252 [details] [review]
Jorge's patch with a few minor edits

I made a few 'pythonic' changes (at least as much as I understand what it means to be 'pythonic', which may not be a lot) and fixed a few stack traces here and there.  I also modified the code to use debug.printException instead of calling sys directly.  It's now in for Orca v2.17.4.  Great stuff, Jorge!  We now have a few release cycles to let people test this before GNOME 2.18.
Comment 23 Juan Ramon Jimenez 2007-02-15 10:49:38 UTC
There is a little problem with this funcionalitty in Orca preferences GUI.

  Some keybindings doesn't work. If two keybindings are only diferent in the modifiers that they use, the combination with more modifiers doesn't work (well, it works only if is defined _before_ that the combination with less modifiers)

    The problem is with the second and third parameters in the keybinding function (now, always filled with the same value). When a new keybindings is defined, not only have to write a new entry for it in the user customization file, but also must check if exists another keybinding with the same letter and different modifiers. In this case, the previous keybinding definition must be changed too.

I have reported a new bug (#408174) because default.py also has the same problem. In this bug everything is better explained.
Comment 24 Willie Walker 2007-03-27 13:27:39 UTC
Closing this as FIXED.  Specific problems with customization should be opened as new bugs.  Thanks for all the hard work on this!