Re: RFC: Tooltips redesign (needed e.g. for row dependent tips in treeview)



On Fri, 2004-11-05 at 19:39 +0100, Christof Petig wrote:

> Owenn Taylor schrieb:
> > Here's an alternate approach I came up with talking to Jonathan (he's
> > promised a more detailed writeup of GtkTreeView requirements) is a
> > little more of a radical change.
> > 
> >  * We ditch (deprecate) GtkTooltips; GtkTooltips objects are 90% just
> >    annoying to create and memory manage.
> 
> I'm 100% in favor of ditching GtkTooltips in favor of a widget property.
> What about tip_private? It does not show up in your proposal at all.

I don't see any reason to carry tip_private forward, there's a vague
idea that it has something to do with what-is-this help, but it was
never really anything useful. If someone passes in a non-NULL
tip_private we can store it in object data for backwards-compat,
but it should have no presence in the non-deprecated API.

If we want to actually support what-is-this help, that needs to
be thought out from scratch. I'm not sure if it belongs in the
tooltips API ... looking at the API for Windows, etc, might be
useful.

(Note that there is another vestigal appearance of what-is-this help
in the GtkWidgetHelpType parameter to the ::show-help action signal.)

> >  * We can reimplement GtkTooltips using GtkTooltipsGroup and
> >    gtk_widget_set_tooltip().
> 
> Agreed. (You are talking about backwards compatibility here, right?)

Right.

> >  * For custom tooltips, we introduce the GtkTooltipsWindow widget,
> >    There is a singleton GtkTooltipsWindow object per toplevel,
> >    which can be retrieved with:
> > 
> >     gtk_widget_get_tooltips_window()
> > 
> >    This both handles the display of the yellow rectangle, and the 
> >    logic for showing/hiding the tooltip based on keyboard and 
> >    mouse actions.
> 
> So, TooltipsWindow is manageing querying the widgets for the text and 
> the display of the tooltip?

I don't know what you mean by that. GtkTooltipsWindow *is* the window
that pops up if a tooltip is displayed. (I think, perhaps it would
be better to generate that window on the fly.) But it also is the
object that tracks the current state of the tooltips and decides
when and where to pop up the tooltips widget.

> >     void gtk_tooltips_window_begin (GtkTooltipsWindow *window,
> >                                     GtkTooltipsContext context,
> >                                     GObject           *owner);
> >     void gtk_tooltips_window_end   (GtkTooltipsWindow *window,
> >                                     GtkTooltipsContext context,
> >                                     GObject           *owner);
> 
> Who calls these? And what would be done inside these calls? [Emitting a 
> signal?]

For widget global tooltips, it's called by gtkwidget.c. But for widgets
with multiple tooltips within them, it would be called by the widget
implementation as it gives enter/leave focus-in/focus-out events.

What is done inside these calls is updating internal state variables,
setting up timeouts, etc.

> >     void gtk_tooltips_window_set_text (GtkTooltipsWindow  *window,
> >                                        GtkTooltipsContext  context,
> >                                        GObject            *owner,
> >                                        const char         *text);
> >     void gtk_tooltips_window_set_markup (GtkTooltipsWindow  *window,
> >                                          GtkTooltipsContext  context,
> >                                          GObject            *owner,
> >                                          const char         *markup);
> 
> This looks like you still manage the tip storage outside of widgets. (In 
> Tooltips Window).

The information is only stored for the duration that this "tooltipable
object" is an area of interest for mouse or keyboard tooltips.

> owner would always be a GtkWidget, wouldn't it?\

No. 'owner' is just an arbitrary GObject that is used to distinguish
this "tooltipable object" from any other tooltip-able widget that might
be active at the same time.

If I was doing row tooltips on GtkTreeView, the object I'd probably
use is the treeview's "bin window" (the GdkWindow that the rows
are drawn in.). Since GdkWindow is also a GObject. It can't be the
treeview itself, since that would cause confusion with tooltips
on the treeview.

> >     void gtk_tooltips_window_set_area   (GtkTooltipsWindow  *window,
> >                                          GtkTooltipsContext  context,
> >                                          GdkWindow          *relative_to,
> >                                          int x, int y, int width, int height);
> 
> So here you mark the active area. Managing different areas inside one 
> widget is missing?

This is just saying "if you pop up the tooltip right now use the
specified area to position the tooltip)

> >     void gtk_tooltips_window_set_group  (GtkTooltipsWindow  *window,
> >                                          GtkTooltipsContext  context,
> >                                          GObject            *owner,
> >                                          GtkTooltipsGroup    group);
> 
> I would code it as
> void gtk_tooltips_group_add(GtkTooltipsGroup *group, GtkWidget *widget)

That would be there for whole-widget tooltips, but the above is allow
grouping of fly-weight sub-widget areas. They have no persistent 
existence, so we can't permanently add them to a group.

> >  - The GtkTooltipsWindow keeps two stacks of "active objects" for
> >    keyboard and mouse focus. With each object in the stack, we
> >    store text/markup rectangle, and possible GtkTooltipsGroup.
> 
> Sounds like a heavyweight object. I'd like to store the information 
> inside the widgets.

Not at all heavyweight - the information is only stored for widgets,
or flyweight areas within widgets, that currently either:

 - Contain the pointer
 - Have keyboard focus

> >  - You call  tw.begin (MOUSE) on when the mouse enters a tooltips
> >    area, tw.begin (KEYBOARD) on a tooltips object getting 
> >    keyboard focus and tw.end (MOUSE/KEYBOARD) on 
> >    mouse leave / focus out.
> > 
> >  - The 'GObject *owner*' arguments allow proper handling of nested
> >    tooltips areas. (think a treeview with tooltips with tooltips
> >    on individual rows.) It can be any GObject - the widget itself,
> >    a GdkWindow, whatever.
> > 
> > A lot of the details of the above maybe should be a little different
> > than I've sketched out, but I think it is a whole lot simpler than
> > any callback-based mechanism with the same set of functionality.
> 
> I originally envisioned asking the toplevel widget for the 
> text/markup/widget to display when the mouse _rests_ at a certain spot 
> of the window. Containers would query their children in turn. Possibly a 
> container can return it's own tip when its child does not provide a tip.
> 
> So the tooltip text query signal/vfunc (I tend to use a vfunc) would 
> only get called when a tip is about to be displayed.

Hopefully the above will help explain what I was thinking about. But
Perhaps you do have a point that a pick interface might work better
(I'd tend to use a signal)

 - My interface clearly wasn't very easy to understand :-)
 - There are a lot of problems with enter/leave events not being
   received on widgets where people want to put tooltips. These
   can be *hard* to fix.

But there are also some issues with such an interface:

 - Currently we pop up tooltips based on enter/leave not on 
   lack-of-motion-events. To duplicate this, you'd have to 
   query the tooltip area for *every* enter/leave/motion
   event.

 - The toplevel doesn't get access to enter/leave/motion events
   on subwindows currently, so we'd have to hack this into
   the GTK+ event propagation system as a special case.
   (Which is possible.)

 - X doesn't *send* enter/leave/motion events for areas of the
   window where these events haven't been selected for. To make
   query-for-tooltips work reliably, we'd probably have to
   make gtk_widget_get_events() always include these events.
   That shouldn't cause compat problems (unless people have
   assertions in their code that they won't get events they
   haven't selected for.) Or even major performance problems.
   But it would be ironic considering that not sending 
   unnecessary motion events is the reason that X and thus GTK+
   has event masks at all.

Hard problem ... I don't have a good definitive answer at the moment,
but perhaps that will give you something to think about.

> Displaying the tooltip for the cursor focus is a different issue (mouse 
> movement does not affect the display but focus changes do) because the 
> actual on screen position is meaningless (that means we do not need to 
> hierarchically query the widget tree for the tip to display).

Issue that came up a few minutes ago talking to Matthias:

 GtkComboBox has a button in it that has the keyboard focus
 You set a tooltip on the GtkComboBox
 You hit Control-F1
 The tooltip doesn't display

So, there is hierarchy there, though it isn't a hierarchical pick.

Regards,
						Owen

Attachment: signature.asc
Description: This is a digitally signed message part



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