Re: Keynav implementation issues



Owen Taylor <otaylor redhat com> writes:

>   F8 to focus through GtkPaned splitter bars "currently in context"
>   F6 to to focus among panes "currently in context"

I have been working on this. Currently, I have f6 and shift-f6
(reverse f6) working, and I hope to have f8 working by the end of this
weekend.

>  The Swing key binding system has a concept where key bindings can:
> 
>    - Apply only when the widget has focus
>    - Apply when the widget or any child has focus
>    - Apply when any widget in the same toplevel has focus
> 
>  While something like this could be implemented in GTK+, it probably
>  is overkill. There are various possibilities:

To me it seems like it is really necessary to do something like
that. All three kinds of keybindings will eventually exist in Gtk+:

        - only when widget has focus: this is what most widgets do.

        - when widget or any child has focus: this is needed for panes
          and notebooks. If gtk doesn't support it, it will have to be
          hacked into these widgets.

        - when any widget in the same toplevel has focus: this is the
          f10 keybinding for menu bars.

>    - Hack all such keybindings into GtkWindow.

How can third party widgets work then?

>    - When focus is moved inside such a widget, set up a temporary
>      signal connection on the toplevel and handle keystrokes there.

This is what I do in GtkPaned.

>    - Make GTK+ propagate keystrokes not just to the focus widget
>      then to the toplevel but through all intermediate widgets
>      as well.
> 
>   I suspect the last one is the best solution, though there is some
>   risk of unintended side effects if you have nested widgets taking
>   key input.

Yes, and I don't see how these side effects can be avoided if third
party widgets must continue to work.  Is there any way to make sure
that such widgets won't do all kinds of weird things if they receive
keypressed without being focused?

>  You can almost keep track of what descendent of a container has focus
>  by watching calls to set_focus_child(), however this doesn't quite
>  work because toplevel->focus_widget isn't set at this point. This

In GtkPaned, I watch calls to set_focus_child(). When that function is
called with a NULL, I know that focus is moving *out* of
container->focus_child and use toplevel->focus_widget at that point as
the last focus widget for that child. This appears to work for
GtkPaned.

Two other points for people doing the same kind of thing: 

        - the pointer to last_focus must be a weak reference, so the
          container doesn't try to focus a widget that has been
          destroyed

        - before focusing into a last_focus widget, check that you are
          still an ancestor of it. Someone might have reparented it.

Søren




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