Modifier keys



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]