style->font



I'm currently trying to figure out what to do about style->font
in order to not cause breakage when we add multi-head support
in GTK+-2.2. (The idea is to do multi-head support with no
binary incompatible changes or incompatible changes in behavior.)


How does style->font work currently:

 * style->font is only there for backwards compatibility. The
   actual real font field in the style is style->font_desc
   which is a PangoFontDescription.

 * style->font is initialized from style->font_desc:

    a) When an empty style is initially created.
    b) When an RC style is converted into a style.

  In other cases, style->font is left untouched, and it is
  freed when the style is finalized.


What are some of the things people do with style->font:

 * Use it on un-realized styles.

 * Change the font directly:

    new_style = gtk_style_copy (widget->style);
    gdk_font_unref (new_style->font);
    new_style->font = myfont;
 
    gtk_widget_set_style (widget, new_style);
    

What are the problems with multihead:

 * GdkFont structures are display-specific, but GtkStyle objects
   are not display specific until they are realized. (Attaching
   a style to a widget realizes it for that widget's colormap,
   or copies it and realizes the copy if it is already realized for a
   different colormap.)

 * If we move the conversion of style->font_desc to style->font
   to the point where the style is realized, and free style->font
   when it is unrealized, then we break both of the above usages.

    - style->font is NULL until the widget is realized. (This
      causes big problems with almost any old-fashion size
      request routine that uses style->font.)

    - If you change the font directly, then GDK will free
      it when unrealizing the style, because it thinks that
      style->font is the font derived from style->font_desc.


Possible fixes:

 * Remove style->font entirely. Tempting, but I think it would
   increase the burden of porting existing code to GTK+-2.0
   substantially.

 * Rename style->font to something private, and accessors
   gtk_style_get_font(), gtk_style_set_font(). This causes
   a lot of breakage, but it's breakage that can be fixed
   very mechanically. And we get the advantages:
   
    - We can emulate the current non-multihead safe behavior

    - We avoid loading style->font if nobody uses it; currently
      we always load it even if there is no legacy code accessing
      the style at all.

    - We can cleanly mark gtk_style_get/set_font as deprecated
      and not-multihead safe, something we can't do with
      direct style->font access.

 * Try to fix the two problems piecemeal:

    - Always keep widget->style realized for the colormap for the
      widget. When the colormap for the widget changes, unrealize
      and realize the widget again. 
   
    - we keep a separately refenced copy of widget->font in
      style->internal_font and only NULL out style->font when
      unrealizing a style if style->font == style->internal_font.
 
   Unfortunately, this is expensive and still leaves problems; 
   in particular, making gtk_style_copy() produce a realized style 
   doesn't work since every realized style must have an "owner" for properly
   maintaining style->attach_count. But it's reasonable to:

    copy style of widget
    modify (e.g. bold) font of copied style
    set modified font on the style, and set style on the widget.

   Also, fundamentally, almost all code modifying widget->style
   currently is broken one way or the other.

   First two examples I found of style modification were:

     evolution/shell/e-shell-folder-title-bar.c/label_realize_callback()

   Which does:

        style = gtk_style_copy (widget->style);
        gtk_style_unref (widget->style);
        widget->style = style;

   !!!! and gnome-applets/battery.c/make_new_battery_applet, which
   does:

    label_style = gtk_style_copy (GTK_WIDGET (bat->readout_label_time)->style);
    label_style->font = gdk_font_load ("6x10");
    gtk_widget_set_style (bat->readout_label_time, label_style);
    gtk_widget_set_style (bat->readout_label_percentage, label_style);

   (You are never supposed to access widget->style without adding
   the widget into its final place in a widget heirarchy and
   calling gtk_widget_ensure_style())

   Trying to guess whether hacks will keep broken code working is
   pretty hard.

Of these options, I slightly favor the the second, but I'm not very
happy about the amount of breakage involved. I'd appreciate any
feedback people have on this subject and especially better ideas about
how to handle this.

Thanks,
                                        Owen

      

  
   




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