This recently opened issue got me thinking again about the use of the keyboard in Avogadro, in particular with the Navigation and Manipulation Tools. So by “navigation” I’m meaning in the sense of the Navigation Tool rather than navigation of the interface.
As demonstrated by the user’s question, the current state of keyboard navigation is not fantastically obvious or discoverable. The main solution to this is to add it to the documentation, which is something that is easy enough for me to do.
But while I’m doing that, and while we’re still pre-2.0, I’d like to talk about changing the way the controls are set up as there are some inconsistencies and points that could be improved IMO. I’m putting a proposal out there for feedback and discussion with the idea that we could agree on a sensible direction, which I can then turn into a tracking issue. This feels very much like something I can implement myself, so I’m happy to, I just want to have agreement on an overall design first.
State of play
So, the way things work right now (and this can serve as a useful reference until the docs are updated or for the behaviour before any changes we might decide on):
-
Arrow keys, WASD, and HJKL all function equivalently/interchangeably when using the Navigation and Manipulation Tools, mapped as:
- ↑ = W = K (what I’ll call up)
- ↓ = S = J (down)
- ← = A = H (left)
- → = D = L (right)
-
When using the Navigation Tool, without modifiers:
- left/right rotates the molecule around the y-axis
- up/down rotates the molecule around the x-axis
-
Navigation Tool with Shift:
- Shift + left/right rotates the molecule around the z-axis
- Shift + up/down pans along the z-axis i.e. it controls the zoom
-
Navigation Tool with Ctrl:
- Ctrl + left/right pans along the x-axis
- Ctrl + up/down pans along the y-axis
-
Manipulation Tool without modifiers:
- left/right pans the selection along the x-axis
- up/down pans the selection along the y-axis
-
Manipulation Tool with Shift or Ctrl:
- No difference to the behaviour without modifiers
Mouse usage
The above scheme also applies exactly to use of the mouse where:
- Moving the mouse up/down/left/right is equivalent to up/down/left/right
- Ctrl and Shift have the same effect when using the mouse as when using keyboard keys
- Holding the secondary (“right-click”) mouse button down is equivalent to holding down Ctrl
- Holding the tertiary (“middle-click”) mouse button down is equivalent to holding down Shift
It would only be fair to recognize that this consistency is a significant positive about the current scheme.
On the other hand, it does miss an opportunity to enable usage of mouse and keyboard together by giving them complementary rather than identical behaviour.
Issues
This scheme presents the following issues:
- The 1:1 duplication across three different sets of direction keys (plus the mouse axes) is good for user choice but is pretty wasteful and consumes a good chunk of our available bindings
- A mental model is difficult to develop because
- Shift has two different effects
- The effects of Shift and Ctrl are arbitrary and therefore difficult to remember
- We have 3 levels of controls (unmodified, with Shift, with Ctrl) and 2 axes of controls (left/right, up/down) when the situation we are trying to represent has 2 transformation types and 3 spatial axes
- Using Ctrl in this way is inconsistent with the general principle outlined by Geoff previously that Ctrl should be used to interact with the wider interface
- Using Ctrl in this way is particularly a problem when using WASD as Ctrl + A conflicts with Select All, Ctrl + S conflicts with Save, and it is likely that we’d want to map other things to Ctrl + letter combinations in future including the HJKL keys
- The behaviours of the Navigation and Manipulation Tools are inconsistent
Note on macOS
In Qt, pressing the Command key on macOS corresponds to Qt::Key_Control
, and Option corresponds to Qt::Key_Alt
, while macOS’ “Control” key is treated as equivalent to the Windows key i.e. as Qt::Key_Meta
.
On macOS holding down the Control key and using the mouse is also equivalent to pressing/holding the right/secondary mouse button. I assume this means that as it stands Command + click and Control + click work equivalently.
Proposal
My proposed solution is to:
- Have all translations and rotations available without requiring modifiers (and certainly not with Ctrl)
- Don’t treat z-axis as a special case, give it its own pair of keys by using 6 instead of 4 directional keys – 3 control axes for 3 Cartesian axes
- Break the equivalence of the three different sets of direction keys and split functions by left hand/right hand
- HJKL remains equivalent to the arrow keys, WASD does something different
- One hand controls panning/translation, one controls rotation
- This makes it easier to do things with both hands on the keyboard
- Give the mouse the rotating function when used with left-click and the translation function with right-click (essentially as now)
- Have scroll/the mouse wheel explicitly be the z-axis control, meaning that left-click + scroll rotates around the z-axis, right-click + scroll translates (but also have scrolling without a click to be z-axis translation i.e. as now)
- Synchronize behaviour between Navigation and Manipulation so that rotation of the current selection can also be done with the keyboard
I have two concrete suggested mappings with the key difference being swapped pan/rotate functions:
Right-hand panning
- WASD control rotation around x and y
- QE control rotation around z (Q anticlockwise, E clockwise)
- Arrows or HJKL control panning/translation
- IO used for panning/translation in the z-axis
Points about this approach
- I/O can be remembered with a mnemonic of In/Out
- Inability to control z-axis with the arrow keys less of an issue since users are likely to think of “zooming” as a separate function anyway, or would likely do it with the mouse. Could make an exception to the no-modifier principle by making Shift + ↑/↓ equivalent to I/O
Left-hand panning
- WASD control panning/translation in x/y
- RF control panning/translation along the z-azis
- Arrows or HJKL control rotation around x and y
- UI control rotation around z (U anticlockwise, I clockwise)
Points about this approach:
- Feels more natural to me
- Complements well the primary function of the mouse (rotate)
- Reminiscent of 3D game controls (move with left hand, look around with right hand using mouse (which is also possible here) or arrow keys)
- Z-axis rotation a little awkward if you use the arrow keys for x and y rotation, but I don’t think this is a big deal
Use of modifiers
As a final point, I think regardless of any other changes that are made (even if that’s none), the modifier keys should be switched:
- The current role of Ctrl is taken over by Shift
- The role of Shift is performed using Shift + Alt instead
This avoids the clashes with things like Ctrl + S.
More excitingly though it also frees us up to, in future, have Ctrl interact with the mouse in the way that is common to many programs (MS Office, ChemDraw) – locking a transformation to a single axis at a time i.e. holding Ctrl while moving the mouse up and down prevents any change in the x-axis.
So that gives a third option where we don’t change anything other than the modifiers.