Modifier keys
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Cc: timj gtk org
- Subject: Modifier keys
- Date: Wed, 13 Feb 2002 15:28:17 -0500 (EST)
Detailed plan for:
50300 Make keybindings handle modifiers properly
Background:
The GDK keyboard mapping is in essence a list of entries>.
keysym <=> { keycode1, group1, level1 }, { keycode2, group2, level2 }
The keycode corresponds to a physical key on the keyboard. The group
is the mode of a keyboard with multiple modes (Roman and Cyrillic, say).
The level is the shift state of the key (shifted or non shifted.)
Given an event, for which a keycode, group and level can be determined,
we want to find the matching binding.
Work items:
* Add a new internal data type, _GtkKeyHash with the operations
void _gtk_key_hash_insert (GtkKeyHash *keyhash,
guint keyval,
GdkModifierType mods,
gpointer data);
void _gtk_key_hash_remove (GtkKeyHash *keyhash,
gpointer data);
gpointer _gtk_key_hash_lookup (GtkKeyHash *keyhash,
GdkEventKey *event,
gboolean (*predicate) (gpointer data, gpointer user_data),
gpointer data);
GList *_gtk_key_hash_lookup_all (GtkKeyHash *keyhash,
GdkEventKey *event,
gboolean (*predicate) (gpointer data, gpointer user_data),
gpointer data);
The algorithm here is that a entry in the hash matches an event
1) The keysym matches and the unconsumed modifiers match.
2) No other entries match, the keycode and level and unconsumed modifiers
match, but the group doesn't.
Fuzzy-group matching is useful because it allows accelerators to be
activated without forcing the user to switch a multiple group keyboard
into the right group first.
If we actually had all key bindings at once, we could go on and do
fuzzy-level matching, unfortunately, each key press is handled in
multiple stages:
Accelerators
Input method key presses on focus widget
Bindings on focus widget
Bindings on ancestors of focus widget
Bindings on GtkWidow
So we don't want to be too aggressive about matching. If <ctrl>a is bound
as an accelerator, and the user presses <ctrl>A, we can't go ahead and
make a fuzzy match, since the widget itself might bind <ctrl>a itself.
There is some danger in fuzzy group matching, because groups are also used
to implement AltGR, so if, say, with a French Keyboard, you have
an accelerator for '<Alt>{' and a widget binding for '<Alt>(' then
the accelerator will always fire, and the binding never, ignoring the
AltGR key. But I think this is acceptable ... it shouldn't be that common
to get accelerator/binding mixes for punctuation and this only would
ever effect hard-to-press combinations like '<AltGR><Alt>('.
* Make GtkAccelGroup use GdkKeyHash to do it's lookups. This will involve
removing the ::accel_activate signal trick and handle the closures
ourself.
* Make GtkBindingSet use GdkKeyHash to do it's lookups. This is the reason
for _gtk_key_hash_lookup_all() and the predicate argument to lookup()
and lookup() all. As currently GtkBindingSet would put all key bindings
in a global hash, and then when a key is pressed, do the pattern matching,
find the matching bindings and sort by priority and order of addition.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]