Yes, I was thinking of the $a cmd | $a cmd shift thing.
Oh, the ugly code (the one that changes the KMDispatcher, right ?). It's
patching the relevant Morphs. The solution you use when you want to hack
Morphic without recoding it :(
Anything better than that would do, a Spec or Morphic API for the application
to be able to reset/recode shortcuts when needed :) a nice when: #keymapChange
do: aBlock.
Some of the work is to switch to hardcoded Keymappings... and to allow dynamic,
instance-based control as well.
What I tried is to remove all hardcoded shortcuts, and it works. I then merged
my menus and shortcuts, and made sure my application could control which
shortcuts were active. But, in the process, I desactivated for my instances the
global Keymaps, the one Nautilus uses for its shortcuts.
Thierry
________________________________________
De : [email protected]
[[email protected]] de la part de Camillo Bruni
[[email protected]]
Date d'envoi : mardi 11 septembre 2012 22:48
À : [email protected]
Objet : Re: [Pharo-project] RE : Keymapping KMShortcut combining
On 2012-09-11, at 22:21, GOUBIER Thierry <[email protected]> wrote:
I've seen the combination and modifiers for Keymapper already; what I would
like is the alternative :
Either
Character tab
or
Character tab ctrl
(because I've linked tab to nextFocus in a TreeModel, and ctrl + tab in a
TextModel (since tab can't be used)) Ok, not much of a gain anyway, so no need
to add this to Keymapper.
I though once about this as well, so you can do something like
$a cmd | $a cmd shift
Ben, Guillermo and Stéphane, in AltBrowser, all hard-coded shortcuts are
desactivated and only the AltBrowser defined shortcuts are active (and those
shortcuts are dependent on the selection and resetted on each selection change
: it's mostly a recreation of the existing shortcuts, like doIt, copy/paste,
navigation, etc...). It takes as code :
- A subclass of KMDispatcher with two methods (keymapObservers and
dispatchKeystroke:).
- The code to replace each necessary KMDispatcher by this subclass.
- The code to reset and add shortcuts to those KMDispatchers.
As far as I remember I once had my own image which used KM shortcuts for all
the default
shortcuts with proper Settings entries (maybe I find the image somewhere so I
can share
the settings code (cause it's really only copy pasting...)
So, apart from a bit of incompatibility (ListModel shortcuts in Spec), for Spec
it's really easy to push that once you review why I had to do that change to
KMDispatcher. For the other parts (SmalltalkEditor), it's a matter of replacing
some class configs by KMShortcuts. I believe someone with Nautilus knowledge
would be nice : it is the heaviest user of shortcuts, and I really don't use
shortcuts in the same way. A merge of both is probably necessary.
For example, I have this method, called each time the selection changes :
updateTextKeymap
"Update the text keymap. Change the key dispatcher if needed. Change all
dispatchers to force and really force default shortcuts not to be used."
| keyMorph |
keyMorph := self targetShortcutMorph.
(textModel widget kmDispatcher isKindOf: AltKMDispatcher)
ifFalse: [ textModel widget setProperty: #kmDispatcher toValue:
(AltKMDispatcher target: textModel widget) ].
(keyMorph kmDispatcher isKindOf: AltKMDispatcher)
ifFalse: [ keyMorph setProperty: #kmDispatcher toValue: (AltKMDispatcher
target: keyMorph) ]
ifTrue: [ keyMorph kmDispatcher reset ].
self selectedItem notNil
ifTrue: [ self selectedItem item buildTextShortcutsOn: keyMorph with:
self ]
And, in the select object side :
buildTextShortcutsOn: aKMDispatcher with: aRequestor
"This is an attempt at handling shortcuts... Which works, with the help of a
custom KMDispatcher."
(Pragma allNamed: #textAreaCommand from: self class to: ABAbstractNode)
do: [ :e |
(self perform: e selector)
do: [ :c |
| command |
command := c on: aRequestor textModel for: aRequestor.
command buildShortcut: aKMDispatcher ] ]
And then the shortcut itself in the Command object.
buildShortcut: aKMDispatcher
"Add a shortcut to the keymap. Conditions : must have a keystroke, must
wantsKeyboard and must be active."
(self keystroke isNil or: [ self wantsKeyboard not or: [ self isActive not ]
])
ifTrue: [ ^ self ].
aKMDispatcher
on: self keystroke
do: [ self execute ]
As you see, the use of KMDispatcher is dynamic and very simple, so I need your
comments on how that would fit with Nautilus and the global keymaps, that I
have disconnected in my case because they interfere in two ways : KMDispatch
randomly chooses which will apply, and that disallows instance based overriding
of shortcuts, and I don't want to have to mask all pre-existing shortcuts to
avoid pass-through effect (a shortcut get applied because a global map has it
and me, for my application, I don't want that to happen).
given that I am a total ignorant :P, can you explain again in different words
why you need
the "ugly" code above?
If you remove all the hardcoded shortcuts, is your dynamic KMDispatcher switch
still necessary?
I still remember a vague discussion with Guillermo about how to handle local
overrides of keyboard shortcuts, wish I had made a picture of that draft back
then :P
But I think we need a bit more general solution for that problem
(of course if yours works right now, we should definitely go for it now!)