Proposal for new tooltips API


We've had a bug opened on reworking the tooltips API since 2001 (#50619) and
GtkTreeView needs this in order to be able to support tooltips on rows, cells,
etc.  So it's about time to do something about it.  In this proposal I am
basically building forth on the work of Owen Taylor and Christof Petig, the
e-mail thread is archived at [1].

Basically, we see two kinds of tooltips:
  a) A simple widget which just has a single tip (eg. GtkButton),
  b) A complex widget which can have multiple tips, which tip is shown is
     usually determined by the position of the mouse cursor or keyboard focus
     (eg. GtkTreeView).

As a main encompassing object we would introduce GtkTooltipsWindow.  This
widget would take care of displaying the yellow rectangle and logic for
showing/hiding the tooltip based on keyboard and mouse actions.  Its API
will be described later on.  The plan is to have a single GtkTooltipsWindow
per widget, created on demand.

Now, tooltip kind a) is easily solved by introducing "tooltip" and
"tooltip-uses-markup" properties in the GtkWidget object.  GtkWidget would
create a GtkTooltipsWindow on demand and showing the tooltip will be handled

For the more complex tooltips handling, the widget would manipulate the
GtkTooltipsWindow itself.  The tooltips window can be acquired using:


the tooltips window will be created on demand if required.  The object can be
manipulated with the following functions:

  typedef enum { GTK_TOOLTIPS_MOUSE, GTK_TOOLTIPS_KEYBOARD } GtkTooltipsContext;

  void gtk_tooltips_window_begin (GtkTooltipsWindow *window,
				  GtkTooltipsContext context,
				  GObject           *owner);
  void gtk_tooltips_window_end   (GtkTooltipsWindow *window,
				  GtkTooltipsContext context,
				  GObject           *owner);

For widget global tooltips (the properties), these functions are called by
gtkwidget.c. But for widgets with multiple tooltips within them, it would be
called by the widget implementation as it receives enter/leave
focus-in/focus-out events.  These functions would update internal state
variables, set 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);

The widget can use these functions to update the contents on the tooltip.
For example when the mouse pointer changes position.  These functions would
only be used for the complex tooltips case (b).

  void gtk_tooltips_window_set_area   (GtkTooltipsWindow  *window,
				       GtkTooltipsContext  context,
				       GObject            *owner,
				       GdkWindow          *relative_to,
				       int                 x,
				       int                 y,
				       int                 width,
				       int                 height);

The window, x, y, width, height arguments indicate the area of the object to
which the tooltip refers. The tooltip would be placed completely 
clear of this area. (As it is placed to avoid widgets today).

For supporting sticky delay (imagine a toolbar, where each button has a
tooltip; there you do not want to wait for each tooltip to pop up.  Once
a tooltip on the toolbar has popped up and the mouse is moved to another
toolbar button that tooltip will popup instantly) we will introduce
GtkTooltipsGroup along the lines of GtkSizeGroup. Tooltips windows can then
be added using

  void gtk_tooltips_window_set_group  (GtkTooltipsWindow  *window,
				       GtkTooltipsContext  context,
				       GObject            *owner,
				       GtkTooltipsGroup   *group);

This API should be sufficient for supporting all kinds of tooltips and thus
the plan is to deprecate GtkTooltips.

GtkTreeView needs support for tooltips on a per cell basis.  I am thinking
of extending the GtkCellRenderer interface with:

  gchar * (* get_tooltip) (GtkCellRenderer  *cell,
                           gboolean         *uses_markup);



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