|Here's revision 2, then.|
Alex: Some of my descriptions may not be as tight as yours. That is a deliberate attempt to allow the rules to apply in more general situations. I haven't folded in your assertion that controls grab all keypresses or none - but you can choose to apply that extra rule if it makes implementation easier.
Xara LX Focus Handling Rules
Revision 2, 4th May 2006 - Phil Martin
“Control”: A control such as a text edit field, action button, radio switch, combobox or anything derived from a window that behaves like a control.
“Modeless control”: A control in a modeless dialog.
“Dialog”: A dialog box, bar, gallery or other top-level window, docked or undocked.
"Focus": The window pointer maintained by the OS/wxWidgets to the window that is given first refusal of any keypress events generated. (That window is said to “own” the focus.)
"Active View": The Camelot view window in which the user has selected nodes and in which selection blobs are being shown OR the Camelot view window that last had input focus.
“Modal dialog”: A dialog which captures all keypress and click events while it is open, preventing the user from interacting with the main application.
"Non-modal dialog" A dialog which doesn’t capture all keypresses and clicks while it’s open, this allowing it to be used at the same time as the user is interacting with the main application.
"Claim an event”: To prevent an event being sent on to other windows in the command chain.
1. Modal Dialogs
Modal dialogs work like normal modal dialogs on the current operating system.
A modal dialog owning or containing focus obviously consumes all keypresses. The control in the dialog owning the focus gets the first chance to use the keypress, then parent windows recursively until the modal dialog itself. (This should be the natural behaviour assuming the modal dialog is a "Top Level Window".)
Keypresses should be interpreted as expected by the ui guidelines of the current operating system. So Ctrl-W or Alt-F4 may close the dialog, as appropriate.
2. Visual feedback
Non-modal dialogs should look different from modal ones to indicate that they behave differently. They should have thin title-bars, like galleries on Xtreme.
A control or dialog should indicate whether it owns or contains input focus in the standard way for the native operating system. For dialogs, this is usually indicated using the title bar and will usually depend upon whether a control within the dialog has focus. Unless this is the case, the non-modal dialog will have a "no focus" title-bar (normally grey).
A modeless control or dialog that shows selected items when it does not have focus must render the selected items more boldly when it does have focus. This helps the user to see that his keypresses will do something different when the dialog has focus.
A modeless control owning the focus should give a very strong visual indication that it has focus, ideally more prominently than the selection in the active view. (E.g. flashing caret, flashing border, boldly shown selected item or popped-up selector window)
3. Minimal keypresses
A modeless control or dialog owning the focus should claim only the keypresses the user expects to work in it. (It is assumed that the active view is where the user’s attention lies and so it is the more natural destination for keypresses.) It does not have to use all of the keypresses it claims. For instance, a text edit control may claim all alphanumeric chars even though it only uses digits. All unclaimed keypresses should be passed on through a command chain in this order: window, window parents (recursively), active view, active document, application.
4. Keypress meanings
The following apply whether focus is owned by a modeless dialog (unlikely) or a modeless control.
If a control owning the focus within a non-modal dialog receives a Return keypress, UNLESS IT PROCESSES THE KEYPRESS ITSELF it should commit the contents of the current field. [this handles the bar case]. If there is a default action (e.g. an apply button), it should also perform that default action, in which case the default button should be highlighted in some way so it is obvious which "apply" action will take effect. Examples of where a control processes return itself are (a) a multi-line text control where return should merely enter a return in the multi-line text field, (b) where the drop down list of a combo has been brought up, and return is used to select the item within the list.
If a control owning the focus within a non-modal dialog receives an escape keypress, it should cancel any changes to the current field (restoring it to the previous value, and then return focus to the selected document. An example of a control processing the escape keypress itself would be a combo box where the drop down is popped up, where escape should close the drop-down (in this instance, a second escape would return focus to the document).
If a control owning the focus within a non-modal dialog receives a CTRL-W or ALT-F4 keypress (or other OS 'window close' keypress), it should process it, cancelling any changes. IE the effect should be the same as pressing ESCAPE then clicking the close button.
5. Release focus when done
A modeless control or dialog should release focus when it has done its immediate job - it must not hold focus assuming the user will want to use that window again. For example, when the colour editor is dragged by its title bar, it is given input focus - if it's not going to use that focus it should hand it back to the previous owner so that focus indication correctly shows where focus really is. The control or dialog can decide what its "immediate job" is. For example, an edit control would retain focus until the user presses Return to indicate that he has finished typing.
6. The User is in charge
A control or dialog only gets focus as the result of a deliberate action by the user such as clicking or pressing Tab while the focus is in a control to move focus to another control in the same dialog.
The application should never move focus into a modeless control or dialog by itself. An example of this is when opening a new modeless dialog: the application should not automatically move focus into that dialog or any of its controls.
7. Focus only when needed
A control or dialog should not take focus if it will not claim any keypress events. Further, a control in a modeless dialog should only take focus if keypresses are essential to its operation or if the control is in a mode where keypresses are useful.
Example1: A radio switch in a modeless dialog should not take focus when clicked on and it should prevent itself from being in the tab sequence.
Example2: A combobox in a modeless dialog should not take focus in its normal state but could do so when the popup list is open to allow listitems to be selected using keypresses.
Example3: A text edit field in a modeless dialog should take focus when it’s clicked on or Tabbed to because text cannot be entered into the field without it.
8. No external focus upsets
Mouse wheel events have nothing to do with focus or active windows - they are sent to whatever control the mouse is over. Important: Neither the operating system, nor the application or any layer in between must be allowed to move focus because of wheel events or because the mouse has been idle over the window for any period!
a. All modeless dialogs should be dockable.
b. All modeless dialogs should ideally immediately affect the active drawing (e.g. the colour editor) or have “apply” action buttons with appropriate labels. It is not correct for modeless dialogs to have OK and Cancel buttons.
c. It may be determined that all controls either claim all keypresses or none, in which case “Rule 3. Minimal keypresses” becomes simpler to implement.
Alex asserts: Controls fall into two categories: keyboard-editable controls and non-keyboard editable controls. The former can take focus in non-modal dialogs (and include text controls and combo boxes). The latter cannot. A corollary of this is that the keyboard cannot be used to control non-keyboard-editable controls in non-modal dialogs (for instance check-boxes and radio buttons).
Alex asserts: When a non-modal dialog has focus, focus necessarily resides within a keyboard-editable control. Pressing TAB will cycle focus around keyboard-editable controls ONLY. A non-modal dialog with no keyboard editable controls cannot gain focus. Clicking on a title bar of a non-modal dialog does not give it focus. When a non-modal dialog is created it should not have focus until a keyboard-editable control is clicked.