This slice allows for per instance shortcuts and disconnect most legacy
hardcoded shortcuts in Morphs (all ctrl and cmd shortcuts). Work in
Time: 12 September 2012, 10:22:34.004 am
- Add a perInstanceOnly flag.
- Change keymapObservers to enforce an ordering on keymaps searches and
take in account the perInstanceOnly flag.
- Change dispatchKeystroke: to mark as handled all ctrl and cmd events
(and, as a consequence, remove them from Morphic event processing).
Beware : has impact on all Morphs ! Do not integrate yet ! Please test !
Spec integrating the change. Spec doing focus change by default.
- Test example : TextShortcutExample.
Left to do: Spec cleanup (key handling, focusBlock)
Next: morphic cleanup.
Do not integrate unless you want to test.
Two levels of focus switching among morphs to clean :
- The Spec one
- The Morphic one
To replace by a single, Keymapping focus switching with two levels : the
Morphic level and the Spec level ? Hey Spec, why reinventing the Morphic
Finished removing all keyhandling code from Spec apart from Keymapping.
Moved ButtonModel and ListComposableModel shortcuts to Keymapping.
Moved Morphic navigation to Keymapping : Keymapping OK, Morphic navigation
is not (Morphic bug).
RPackage / MC is bugging and may be loosing some of my changes. MC changes
gives me incorrect results.
- The possibility to remove static targets (i.e. remove system wide
shortcuts for a given instance).
- The possibility to have search among targets in a non-random order.
- Simpler code when dealing with some patterns (i.e. FinderNode : shortcuts
depends on the type of item selected)
- Avoiding creating subclasses of KMDispatcher.
Ok. As I said to Sean, I need your suggestions and wisdom for some changes
I'll set some vocabulary first, and you will be able to check if I have
understood Keymapping in the first place:
Shortcuts in Keymapping are grouped in keymaps. Keymaps may have sub
categories, to cope with platform differences : #Unix, #Windows, #MacOS,
#all (it looks nice and forward thinking!).
KMDispatcher is in charge of trying to match a key event (received by the
Morph which has the focus(remember that, it has consequences)) to a
shortcut. It cycles through targets to do so, each target having one or
more keymap associated. KMDispatcher is one of the first matcher seen by a
Morph (which is very good, thanks for the guy who did that!). If a shortcut
is not matched by KMDispatcher, it falls through in Morphic other key
handling code (Important point). Morphic may move key events between
morphs, giving a chance (chance ? more like bad luck when that happens) for
another morph and KMDispatcher to match the event.
KMDispatcher targets belong to three categories :
- static targets : global keymaps linked to the morph class. The use of
static targets is #deprecated in the KMDispatcher code.
- targets : named keymaps (from the global KMRepository) that are
associated with a KMDispatcher instance with a call to attachCategory:
- per instance target : keymaps setup by calling on:do: on the KMDispatcher
Initially, KMDispatcher would randomly iterate over all those targets to
match a shortcut. I changed that to force the following order: per instance
target, targets, static targets (but since targets is a set, if you load
multiple targets in a KMDispatcher with overlapping shortcuts, it's random
Now, there is a need for some applications to have fine control over which
shortcuts are active, and static targets gets in the way of that, since
they are allways checked. On the contrary, targets and per instance target
may be resetted by doing KMDispatcher reset.
So my choice is :
1) Add a flag to KMDispatcher to disallow, if true, static targets
2) Remove the static targets and make reset erase both targets and per
1) works, but is a bit of a kludge (and is visible to applications since
they have to learn to use it). Compatibility with code that rely on static
targets is perfect. This is the one I implemented for now in the slices.
Total control by an application is:
aKMDispatcher perInstanceOnly: true. "Switching to vim mode"
aKMDispatcher reset. "Yep, but targets are not resetted."
aKMDispatcher on: $d, $d do: [self eraseLine].
2) Break compatibility with code relying on static targets : is there any
such code ? Nautilus doesn't I believe, TextEditor and SmalltalkEditor (the
two non-Nautilus global keymaps) are targets (non-static) for
PluggableTextMorph. Once done, total control by an application is simply :
aKMDispatcher on: $d , $d do: [self eraseLine]
Ok, for fun to you guys ! TextEditor and SmalltalkEditor global keymaps are
broken... Try ctrl+end in any editor and you will see. There is a trap for
the unwary in the global keymap system : the target may not be what you
expect when you write the keymap.
Luckily, the passthrough code let TextEditor and SmalltalkEditor do their
work the old way.
There is quite some changes to Keymapping with the removal of staticTargets.
If you think it's the right path, moving everything to Keymapping should
only be a matter of adding the right shortcuts. Please look at
Morph>>kmDispatcher if you have a better idea for setting this up (default
and per-Morph shortcuts).
- Changed KMDispatcher to not use static targets (per class keymap)
-- Added TextMorph keymap to TextEditor users with the right target.
-- Removed perInstanceKeymapOnly everywhere (Spec and KMDispatcher)
-- Added two low-level shortcuts to SmalltalkEditor to replace Morphic
shortcuts : ctrl+t and ctrl+shift+f (ifTrue: and ifFalse:) to experiment
two ways of accessing low level functions of TextEditor and SmalltalkEditor.
- Left to do: scan all Morphic code to replace keystroke processing by
shortcuts, look at cursor keys and friends. Can be done step by step from