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

Re: Entry / TextBuffer that does not listen to accelerators?



Am Freitag 30 September 2005 17:04 schrieb muppet:
> Stephan Brunner said:
> > I am not able to enter any 'u' into the Entry.
> >
> >> The reason this should work is, that the active widget gets the input.
> >> If the widget does not handle it, it passes it on to it's parent. And so
> >> on up to the window, which handles the accels.
>
> Not quite; key events are delivered first to the toplevel window (an X
> quirk), and propagated from there to child widgets. 
> gtk_window_key_press_event() looks like this:

[code]

> Which means that window-wide mnemonics and accelerators take precedence
> over per-widget keystrokes.  And, if you think about it, it *has* to work
> that way, or something like a TextView would eat all of the keys that are
> supposed to be menu accelerators.
>
> > Reading this, I wonder even more why I can't get it to work the way I
> > want to. Is there some subtle mistake or usage-error in my code?
>
> No.  Your key is handled by the UI manager, which means, by the logic
> above, it takes precedence over the widget's handling of the event.  In
> fact, your Entry or TextView never even gets the key-press-event.
>
> This sort of clash is the reason for using modifiers on accelerators in the
> first place.  The problem would be easily solved by making your accel be
> "<Ctrl>U" instead of just "U"... but since that's not what you asked...
>
> In this instance you need to have the widget get the first crack at the
> unadorned key.  The guys on gtk-app-devel-list or in #gtk+ will probably
> know better than i, but here's what i would try:
>
> a) Don't put the accelerator in the UIManager descriptions, but handle it
> by hand in key_press_event on the toplevel window, connected by
> signal_connect_after().  By removing it from the UI manager, it doesn't get
> handled in the accelerator table, and by having it connected _after, your
> handler runs *after* the key has been propagated to the other widgets,
> which gives the TextView and Entry first crack at it.  The drawback is that
> you lose the helpful accelerator hint in the menu.

Hmm, since I want to provide some sort of "plug-in" mechanism for the 
application, I'm quite happy about the UI manager and its convenient way of 
extending the user interface. Not only would I lose the accelerator hint, but 
also the possibility to automatically "register" a plug-in action with its 
accelerator.

[code]

> b) Leave the accelerator in the UIManager, and add special code in your
> action handler to route the event as necessary.
>
>   sub u_action {
>       # if the key focus is currently on the toplevel window, we may
>       # need to do further key routing:
>       my $widget = Gtk2->get_event_widget (Gtk2->get_current_event);
>       if ($widget->isa ('Gtk2::Window')) {
>           # check the type of the widget that currently has focus:
>           my $focus_widget = $widget->get_focus;
>           if ($focus_widget &&
>               ($focus_widget->isa ('Gtk2::Editable') ||
>                $focus_widget->isa ('Gtk2::TextView'))) {
>               # he needs this event more than we do.
>               $focus_widget->event (Gtk2->get_current_event);
>               return;
>           }
>       }
>       $count++;
>       print "$count: This is sub u_action...\n";
>   }
>
> I don't like this approach very much because it feels fragile, and requires
> placing this behavior in all of the handlers for unadorned accels, rather
> than just connecting them in a different place.  On the other hand, you get
> your handlers through UIManager, which is nice.

Yeah, even though it's clear what happens here, it somehow doesn't feel 
"complete" enough.

Well, there doesn't seem to be a "straight forward" solution like 
$widget->set_listen_to_accels(FALSE), so I will have to think twice about 
going for <Ctrl>U... I just like the VIM-approach more than the Emacs one;-)

Thank you very much for the deep insight - at least I now understand why it's 
not working "out of the box"!

Stephan
 



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