Entries from July 2007 ↓

Where’s My Rocket-Powered Themes?

Recently, there was some gtk+webkit goodness posted on Planet GNOME [1], [2], and it seems quite an easy (open source) project to check out and get your head around, given its size. There’s been some recent activity with the GTK-specific code to draw e.g. buttons and checkboxes that look like the GTK theme. I thought I’d start with the simple task of fixing up the radio buttons to actually look like radio buttons, and for the push-buttons to react to mouse-overs and mouse-presses, and not have the bounding box filled in with the default GTK background color (as I’ve helpfully called out with my hot pink arrow on the 8x blow-up below).

gdk-webkit-buttons.png

The hover / pressed stuff is pretty straightforward, it looks like this

GtkStateType state_type = isHovered(o)
  ? (isPressed(o) ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT)
  : GTK_STATE_NORMAL;

But to avoid the background-box being filled in, spot the hack in the following code:

bool RenderThemeGdk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
  GtkWidget *button = gtkButton();
  button->allocation.x = -2;  // HACK
  GtkStateType state_type = isHovered(o)
    ? (isPressed(o) ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT)
    : GTK_STATE_NORMAL;
  gtk_paint_box(button->style, i.context->gdkDrawable(),
    state_type, GTK_SHADOW_OUT,
    NULL, button, "button",
    rect.x(), rect.y(), rect.width(), rect.height());
  return false;
}

Yes, I explicitly set button->allocation.x to be -2 instead of the default -1. Is that fragile and will that probably break something inexplicably in the future? Probably yes. Why does that have any effect? Well, if you look at clearlooks_style_draw_box in the Clearlooks engine code, it says this:

/* Fix some firefox crap. */
if (GE_IS_BUTTON (widget) && GE_IS_FIXED (widget->parent) && widget->allocation.x == -1 &&  widget->allocation.y == -1)
{
  gtk_style_apply_default_background (...);
}

Indeed, it looks like GTK theme engines are a tangle of special cases [3][4]. So, dearest lazyweb of benevolent GTK theme gurus, if I were to do this properly, what would be the ‘correct’ way to do this?

Oh, and with painting the radio buttons, I seem to be setting shadow_type = GTK_SHADOW_IN to mean ‘checked’. Again, I have no idea whether this is a coincidental hack or if this is the right way to do it.

Dang it, isn’t it supposed to be the future? Where’s my jetpackTiger Stripes?