Menu and Keystroke Configurator
©1996-2013 Roedy Green, Canadian Mind Products
This essay does not describe an
existing computer program, just one that should exist. This
essay is about a suggested student project in
Java programming. This essay gives a
rough overview of how it might work. I have no source, object,
specifications, file layouts or anything else useful to implementing this
project.
This project outline is not like the artificial, tidy little problems you
are spoon-fed in school, when all the facts you need are included, nothing
extraneous is mentioned, the answer is fully specified, along with hints
to nudge you toward a single expected canonical solution. This project is
much more like the real world of messy problems where it is up to you to
fully the define the end point, or a series of ever more difficult versions
of this project, and research the information yourself to solve them.
Everything I have to say to help you with this project is written below.
I am not prepared to help you implement it; or give you any additional
materials. I have too many other projects of my own.
Though I am a programmer, I don’t do people’s homework for
them. That just robs them of an education.
You have my full permission to implement this project in any way you please
and to keep all the profits from your endeavour.
Please do not email me about this project without reading the disclaimer above.
Introduction
The big advance of Windows over DOS (Disk Operating System) was not the GUI (Graphic User Interface) or the mouse, but CUA (Common User Access), the Common User Interface. To a very large
extent, all Windows programs work the same way. This makes learning easier, and switching from app to app easier.
However, in Windows, though the mouse actions were standardised, the keystrokes were left in chaos. In Java and KDE (K Desktop Environment)
there is even greater chaos.
I propose imposing a standard on them too, and implementing it first as part of Java, or as part of Linux KDE to
leapfrog past Windows in ease of use. The beauty of my idea is it does not impose any particular menu or keystroke
assignment structure on anyone, not even the end user. I propose both greater order and greater freedom to
easily configure things just the way you want, either globablly or on a per app basis using a standard set of
tools.
I want menus globally configurable so the layout is almost the same in every program, so that FIND is on the same
position in every program, and accessible with the same accelerator keystroke. I don’t want to have to
configure every program separately. I want to configure how I like my menus and accelerators once and for all and be
done with it.
Here is how it works.
- Function key to function mapping is global. In one place, the end user can tell the system that F8 means
SAVE, and instantly all conforming apps start using F8 to mean save. I don’t have to configure each app
individually, using a zillion different configuring schemes. These configurations are saved on a per-user basis so
that different users of a machine can have different assignments.
- There are perhaps a dozen registered standard ways that Search and Search/Replace work. I can configure
globally which scheme I prefer. I can plug in yet another one from a third party if none of the standard
ones are suitable.
- I can reconfigure the Ctrl-C, Ctrl-X, and Ctrl-V keys so that they will be convenient for one-handed use on
keyboard layouts other than the standard QWERTY.
- The menu structure and accelerator keys are fully user-configurable in a completely standard way. You can
reorder the menus, or remove items from them you don’t want to use. This is handled by an intelligent merging
of global and app defaults.
- The application programmer does not hard code in particular keystrokes or menu item positions. He specifies
only standard function names. If he has some special keystroke function key needs not covered by the standard set,
he gives them configurable names, and configured by the same utility.
- Standard functions would include those on the Sun keycaps:
Help
Stop
Props
Front
Open
Find
Again
Undo
Copy
Paste
Cut
plus others commonly found in apps such as:
Help
Open
save
Save All
Close
Close All
New
Print
Search
Search Back
Replace
Replace Back
Calculate
Exit
Undo
Cut
Copy
Paste
Go To
Bookmark
Font
Upper Case
Lower Case
Book Title Case
Validate
Configure
Tile
Tile Vertical
Tile Horizontal
Cascade
Horizontal Split
Vertical Split
I would expect this list to have hundreds of items by the time you were done.
- Normally menu items would be named in a standard way to match the function names.
- Each app does the analogous thing for that command, not necessarily the exact same thing, e. g. VALIDATE might
spell check in a word processor, and check HTML (Hypertext Markup Language) syntax is a validator.
- There are perhaps a dozen different scrolling schemes registered. The end user, can globally, in one place,
configure which one he likes best and all conforming apps instantly start using it. If he does not like any of
them, he can buy a plug-in replacement from some third party and configure that.
- The help file mechanism automatically displays the current function key assignment, menu, and accelerators as
well as the function name when discussing various functions.
- The global configurator lets you print a compact cheat sheet for any app of the function keys supported, or the
fully expanded menu structure.
- Similarly, the generated menus have an automatically generated menu item under help called Keys It
displays a cheat sheet showing you all the current keystroke accelerators (less the ones discribed directly on the
menus.) and their function and hover help.
Implementation
What sorts of file would you need to manage a global keystroke and menu reconfiguring scheme? These are not
necessarily flat files. The menu management must be able to get at them easily. Perhaps they could be stored used the
Configuration api.
Global.PossibleFunctions
Global list of possible functions that may be supported in any program, either by keystroke or menu. There is only
one such file per user. It would have, at a minimum, a list of all possible functions that can be globally configured
for all applications. The list need not be complete, e. g.
Help
Open
save
Save All
Close
Close All
New
Print
Search
Search Back
Replace
Replace Back
Calculate
Exit
Undo
Cut
Copy
Paste
Go To
Bookmark
Font
Upper Case
Lower Case
Book Title Case
Validate
Configure
Tile
Tile Vertical
Tile Horizontal
Cascade
Horizontal Split
Vertical Split
This list could come from three possible sources:
- The group that writes the automenu code and who define the official common functions. This would include
functions that no currently installed app is using. You could still place these functions on your global menus in
preparation for installing apps that use them. This is the preferred source. This encourages application developers
to use common terminology for similar functionality. The compilers of this list need both names and definitions of
what are appropriate uses for that function. You can make up fine distinctions between synonyms, e.g. exec and
launch.
- A list of all functions that two or more apps just happen to be using.
- A list of all functions in all apps currently installed.
App.PossibleFunctions
List of standard functions plus additional functions actually supported by a given app. There would be one such file
per app, e. g.
Open
Save
Quiet Toggle
Duplicate
Not every function need be listed, however, if it is not listed, it can be reconfigured. Ideally you want every
function to be configurable as to possition and whether it even appears at all.
Global.KeystrokeAssociations
List of function key associations globally applicable unless overridden. There is only one such file per user.
F1=Help
F2=Open
F3=Search,Whazmotron ; Whazmotron search technique
F7=Print
Ctrl-V=Paste
Ctrl-X=Cut
Ctrl-C=Copy
App.KeystrokeAssociations
List of function key associations for a particular application. They override the global defaults if a keystroke
appears in both lists. There is only one such file per application.
F9=Validate
Alt-F9=Go To
Ctrl-Q=Quiet Toggle
Global.MenuAssociations
Your globally specified preferred default menu structure, describes menu structure, Alt-style keystroke
accelerators, and tooltip (bubble/hover) help. There is only one such file per user.
File/&Open=Open a file
File/&Save=Save the current file
File/app
File/Print=Print
app/
&Help/About
&Help/Register
app is a magic keyword that tells where you want the app specific menu commands to
squeeze in. Similarly app/ shows where you want the app specific stuff to squeeze in on the
menu bar.
This will be merged with the list of supported app functions and the MenuAssociation overrides for the apps to
create the actual menu. It is thus not an error to specify function that the app does not support.
The symbols =, & and / are permitted in the tooltip help. & has reserved meaning in the menu to specify
the accelerator key.
The app itself still has the ability to hide and reveal menu items, using only their function names. It would not
usually dynamically build a menu.
App.MenuDefaults
Provided by the writer of the application. This is the default menu layout he suggests. If you provide no global or
specific overrides, this is what you will get. Items appearing in the global menu will be moved to new places.
Non-standard columns will fit in the /app section of the menu. The suggested default may use menu headers from the
global pattern such as File and Help.
App.MenuAssociations
Your overrides for a specific app to describe the menu structure, Alt-style keystroke accelerators, and tooltip
(bubble/hover) help. It is merged with information from the global .MenuAssociations and
the apps .PossibleFunctions file to create the actual menu structure. It is thus not an
error to specify function that the app does not support. Further, you don’t have to put every function the app
supports on the menu. However, if you don’t specify a given supported function, that function won’t be
accessible, e. g.
Document/&Tabs=tab settings
Document/Margin=margins around the document
Internationalisation
This scheme I have described does not handle languages other than English. You want the application programmer to
have to deal only with English (or her native language), with the ability to add arbitrary languages simply by
manipulating these configuration files.
Let us assume we want to support French, as well. The .MenuAssociations file and
.KeystrokeAssociations files would be written entirely in French. The .PossibleFunctions files would be extended like this:
Help=Aider
Open=Ouvrer
Save=Sauver
Tools
The actual files would be case sensitive, though the tools to manipulate them might be case insensitive.
The tools to manipulate these files would be fully generic. The end user thus has only one configuring tool to
learn, not one per app. You could also manipulate them with a text editor very easily.
The tools to modify the .PossibleFunctions files would not normally be employed by end
users.
Tools would have a way of restoring you to a default factory default.
Because the file formats are so simple, it would a trivial matter to write a set of tools, with any degree of
whiz-bang you wanted.
The tools warn you of conflicts between global and local settings and help you resolve them. They also detect
accelerator conflicts. They would remove ordering errors, collecting together duplicate entries for the same menu
column. They would warn you when you had inaccessible functions, or a keystroke or menu item associated with more
than one function.
Note that the scheme can also specify 3 or even 4 level menus. These may be implemented as multiple toolbars for
very large menus. The run-time engine itself would be quite robust. It would carry on no matter what a mess the
configuration files were in.
Using the Scheme From Java
Here is how you might use the global keystroke and menu configuration files in a Java application or Applet:
This is considerably simpler than building the menus item by item programmatically, and of course much more
flexible.
Security Issues
You would want this scheme to work with Applets as well. You would want users to be able to configure Applets, just
like Applications. This means somehow getting the default definition files onto the local hard disk, ideally without
a signed Applet. They would be like cookies, an exception to the no-write rule.
There are a ton of little files to manage, one set for each user for each app. You want to be able to borrow
configuration files with read-only access from other users. I have not tackled the issue of how you would name all
these files to track them. You also need master factory default files and master default files for various languages.
A user might even want to maintain some alternates for a given app, e.g. a stripped down version where it is easier
to find stuff, and a full version.
Loose Ends
The accelerator keystrokes must be filtered out so that the KeyListeners never see them. They must be app wide, no
matter which Component currently has focus. This requires hooking into the AWT (Advanced Windowing Toolkit).
It may be difficult to remap keys like Ctrl-C, Ctrl-V and Ctrl-X which may be handled specially.
I have not described how pluggable search/replace algorithms could work that would be sufficiently general to work
in a spreadsheet, database or word processing program. It would not directly touch data. It would be more of a state
machine that did its work via methods of a delegate object passed to it.
I have not described how you would configure the pluggable scrolling algorithm, or define the various mouse and
keystroke options to control it. This might be a class with a few replacement components for some of the scrollable
AWT/Swing components, such as TextArea.
An app may regenerate the menu from scratch during its lifetime. This would allow it to have more than one menu
structure, e.g. for different phases of the app. It would also allow the app to manipulate the configuring text files
directly, usually to select from one of a set of canned configurations, e.g. Brief vs Epsilon vs CUA emulation.
Should there be so many separate files, or should they be combined into fewer? The advantage of separate files
are:
- Simpler tools (which might encourage an earlier implementation).
- Fine control of read/write access using the file system.
- More robust if people start manually editing it since the format is simpler, and damage to a file is confined
to one file.
- It is easier to add new languages, just add new files. There is no need to merge the data.
- RAM (Random Access Memory) usage is slightly more efficient since you never load data, for other languages, you don’t currently
use.
The advantages of combined files are:
- greater speed
- fewer files to manage manually.
- Less confusion trying to guess which files are the ones you manually want to configure or view.
The decision which way to go should probably go to the first implementor. Tools should optionally remove entries from
the app configs that duplicate the global settings. That way changes to the global settings will be automatically
reflected in the apps.
How should it come pre-configured out the box? I would hope there would develop some named schools of thought on
that, and you could try the entire configuration suite with a single tool menu change to get a reasonably pleasing
starting point before you did your fine tuning.
I find I cannot type without visual feedback. Secret passwords you type blind drive me nuts. As soon as the
feedback disappears I go numb and just cannot type worth a bean. So, I would like the hiddenness of passwords to be
configurable. I want them visible when I type. The CIA (Central Intelligence Agency) has no interest in me. I have heard there are ways of doing
them so that snoops have great difficultly picking up the monitor radiation, but they are still visible.
Key bindings really needs to happen globally, including non-Java apps, so perhaps it makes no sense to try for a
Java-only implementation, other than as a proof of concept. The application programmer’s interface should allow
for the possibility this scheme will later be implemented at the OS (Operating System) rather than the Java level. It should work
through methods, rather than playing with configuration files directly.
There also needs to be mechanisms for particular applications to request that they get no translation of
keystrokes (or a particular one) and to query what those translations currently are.
Whatever mechanism is used, it must live in the privileged sphere, requiring user ok. Remapping the spacebar to
Undo would drive many people round the bend!
What Is Important?
Don’t take any of the implementation details too seriously. You will soon know far more about this project than
I when you get into implementing it. The four things I consider most important are:
- The user should have an easy way to move a menu item to a consistent place on every app.
- The user should have an easy way to change the accelerators in all programs so they are consistent.
- The user should have a way to override my general menu/accelerator scheme for a particular app, including the
menu items that occur only in it and nowhere else.
- Apps should work whether the user configures all the menu items or not. The user should just have to configure
the menu items he finds irksome, not the whole thing. Individual Apps should provide a default menu structure.
There should be default general menu structure.
Summary
I have been bitching about this issue since DOS days. I have a history of building what I think are better mousetraps
then finding that almost no one is willing to even investigate them.
I think acceptance would be much greater if this if implementing this were more of a team effort.
Happily, Sun (Hans.Muller@Eng.Sun.COM and Scott.Violet@Eng.Sun.COM) has already started some
Learning More
in this direction. After an ice age, evolution can again progress.
David Alex Lamb of Queen’s Univerity in Kingston Ontario Canada
has been doing some work on the problem. he suggests a scheme of search path of files and resources to find the menu
and keystroke accelerator configuration information…
The KDE people are working on an implementation for Linux. Perhaps other OS es will follow their pattern, and
eventually Java will have a platform-independent hook for this in-future-common OS feature.
  |
available on the web at: |
http://mindprod.com/project/menuconfigurator.html |
| |
optional Replicator mirror
of mindprod.com
on local hard disk J: |
J:\mindprod\project\menuconfigurator.html |
 |
Please email your
feedback for publication,
letters to the editor, errors, omissions, typos, formatting errors, ambiguities, unclear
wording, broken/redirected link reports, suggestions to improve this page or comments to
Roedy Green :
 .
If you want your message, your name or email kept confidential,
not considered for public posting, please explicitly specify that.
Unless you state otherwise,
I will treat your message as a letter to the editor that I may or may not publish
in the
feedback section.
After that, it will be too late to retract it.
If you disagree with something I said, especially when sending an ad-hominem attack,
a rant composed mainly of obscenities or a death threat, please quote the offending passage
and cite the web page where you found it, tell me why you think it is wrong,
and, if possible, provide some supporting evidence.
I can’t very well fix erroneous or ambiguous text if I can’t find it. |
| Blog |
Canadian
Mind
Products
IP:[65.110.21.43]
Your face IP:[50.16.108.167] |
|
| Feedback |
You are visitor number
9,673. |
|