Re: uline accels, aka. mnemonic activators



On 16 Mar 2001, Owen Taylor wrote:

> 
> Hi Tim,
> 
> I would agree with you that mnemonic's and menu accelerators are
> somewhat different:
> 
>  - Mnemonics have different conflict resolution behavior
>  - The dynamic-accelerator-changing code in GtkMenu isn't necessary for mnemonic.

and most important probably is the different visibility related behaviour.

> But in essence, GtkAccelGroup is just a fancy hash from keyval/modifiers
> to action, and that's what we need for mnemonics. I don't think
> introducing a separate, unrelated mechanism for mnemonics is
> less confusing or simpler.
> 
> >From the point of view of the average programmer, GtkAccelGroup actually
> looks very simple:
> 
>  - Create an accelgroup
>  - Connect keyval/modifiers to actions within that accelgroup
>  - Attach the accelgroup to a toplevel, to add those keyvals/modifiers
>    to set of keys that are handled globally on the window.
> 
> This same high level view makes perfect sense for mnemonics as well.

it doesn't quite. mnemonics are fine to set on leaf widgets and expect
them to get automatically carried over e.g. if reparenting.

> So, all we need is a global toggle indicating whether this accel
> group holds mnemonics or menu accelerators. Sure, this internally
> complicates the accelerator group a bit, but you certainly
> arent' scared of a little implementation complexity ;-)

not just internally, internally it means that the accel group
code has to become quite clever about widgets, knowing visibility.
externally though that means means that an accel group entry
suddenly turns into a list and API such as unlock_entry is suddenly
utterly useless.

> The other possibility would be to have gtk_accel_group_add_mnemonic() 
> and make the distinction a per-entry thing. Perhaps that would
> seem a bit simpler than having separate accel groups with a
> global behavior toggle.

no, that has still the same problems.

> The point here is keeping the number of independent unrelated concepts
> that the programmer needs to know to use GTK+ to a minimum.

eh? lemme give an anonymous quote that i think you'd also agree with: ;)

 > So, I think a clean design that involves a small new concept
 > is better than what appear to be essentially a hack.

> Other reasons for using accelerator groups instead of making up
> a new concept:
> 
>  - To properly handle keyboards with multiple groups (say, a Russina
>    keyboard) need to be doing somewhat sophisticated resolution
>    of key presses. 

there's nothing you'd gain from using an accel group here.

>    It would be better not to duplicate this code more than possible,

there's really not much duplication here, as mnemonics need to be handled
way differently than accelerators, you have to figure visibility and
ancestry propagation and conflict resolution at activation time, which
is way different than accelerator overrides due to conflicts at
installation time.

>    and furthermore the resolution can be done better the more you
>    know about what accelerators are available. For instance,
>    on a US keyboard, you might want to treat <Ctrl>= as the same as   
>    <Ctrl>+ if only one was bound to an accelerator, but separate
>    them if both are bound.

that can go into our general gtk_accelerator_*() namespace, these
kind of key alias issues have to be handled differently for
mnemonics anyways as they indicate duplicate entries that still
do not conflict. btw, that's an implementation detail that's not API
visible, so i wouldn't worry too much about this.

>  - Enhancements like per-entry data are also needed for GtkAccelGroup
>    and we shouldn't have to keep changing both APIs in parallel.

i'm sorry, but data extensions for accel groups would break serialization.
accelerators are in place to "activate" a widget argumentless, we sat down
at some point to cover more sophisticated keybinding setupd, and GtkBinding
steemed out of that. if we're missing globally parameterized key bindings,
that's (which we do) to be fixed on the GtkBindings side.
accel groups are for user-changable and serializable widget activations
that are unique within a dialog, once you start adding parameters or
riddle with uniqueness of the accelerators, the concept breaks and that
shows itself in inconsistent API and also has bad effects on thngs like
serialization or negotiation.

>  - For GtkPlug, I need to keep track of _all_ globally trapped 
>    keystrokes and forward them to the parent GtkWindow.

right, and you better handle mnemonics differently from accelerators
there, since acclerators are always globally trapped, while mnemonics
depend on visibility.

> So, yes, mnemonics are somewhat different from menu accelerators, 
> but in the end, they are globally trapped keystrokes, GtkAccelGroup
> is how we handle globally trapped keystrokes, and I don't think
> it makes sense to introduce a new parallel mechanism.


well first, the API to install either of them is proposed different already,
i.e. you'd do gtk_label_new_with_mnemonic ("My _Label"); and want that
to work (e.g. as child of a menu item), while for accelerators, you
have to specify it in the item factory "Ctrl+X" or directly via
gtk_widget_add_accelerator() which wants accel flags that don't apply to
mnemonics and wants a signal_id that's also odd for mnemonics which need
their (widget, mnemonic_group, activate_data) signal.
for mnemonics the user shouldn't specify modifiers, instead we pick either
none or Alt depending on whether the mnemonic is used inside a menubar, etc.
the two things are quite different, even in existing API.

so yeah, additional API will be introduced to install mnemonics but that's
hardly too complex for the user. either people use the convenient "_Action"
way in item factory entries and labels, or they'll have to do some
gtk_mnemonic_activator_add (window, keyval, modifier, activate_data);
in ::heirarchy_changed.
while that function could even be internally and the only public API
we provide would be:

gtk_widget_add_mnemonic (widget, keyval, data);

which does automatic (re-)installation on ::heirarchy_changed and
picks a modifier on its own.

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]