Hi Axel,
  Thank you very much! It really works! By the way, do you know some resource about gtkrc files, just like introductions or tutorials?

Deng Chao

2007/10/1, Axel Simon < A.Simon@kent.ac.uk>:
Dear Deng,

I tried your example and sure enough it doesn't work as expected. I
tried to understand the (really bad) documentation and came up with
the following:

>     windowXml <- xmlNew "myStyle.glade"
>     let window = case windowXml of
>         (Just window) -> window
>         Nothing       -> error "Can't read glade file!"
>     winMain  <- xmlGetWidget window castToWindow "winMain"
>     btnStyle <- xmlGetWidget window castToButton "btnStyle"
>     widgetSetName winMain "winMain"
>     widgetSetName btnStyle "btnStyle"

a) You've already named you widgets in the .glade file, so you don't
need to use the functions widgetSetName.

> then this is my .gtkrc-2.0 file:
> style "mySize" {
>     GtkButton::default_outside_border = { 10, 10, 10, 10 }
> }
> widget "btnStyle" style "mySize"

The property "default_outside_border" only works if the button has
the "CAN_DEFAULT" flag set. AFAIK this means the button must be the
default button of a dialog box. I think you can set this flag using
Glade, Gtk2Hs lacks the functions for this at the moment. Anyway, if
the Button you're creating is not the default button of a dialog box,
then setting this property has no effect. There is an "inner-border"
property, though. You could try that.

b) "widget" and "widget_class" both use the layout hierarchy to
specify widgets. "class" uses the inheritance relationship. Thus if
you create a layout tree like this one:

Window     win
   VBox     box
     Button b1
     Button b2
     ToggleButton b3
     HBox   box2
        Button b4

then you can set the style "myStyle" for b1 and b2 as follows:

widget "GtkWindow.GtkVBox.GtkButton" style "myStyle"
widget_class "GtkWindow.GtkVBox.GtkButton" style "myStyle"

If you only want to affect b1, you need to use its name:

widget "GtkWindow.VBox.b1" style "myStyle"

If you want to apply your style to all buttons below the VBox, you
can use

widget "GtkWindow.*.GtkButton" style "myStyle"
widget_class "GtkWindow.*.GtkButton" style "myStyle"

and maybe also

widget "GtkWindow.GtkVBox.*.GtkButton" style "myStyle"
widget_class "GtkWindow.GtkVBox.*.GtkButton " style "myStyle"

If you want to change all button and also those that derive from
button, i.e. if you want to change b1, b2, b3 and b4, use

class "GtkButton" style "myStyle"

Note that only 'class' uses the inheritance hierarchy and that both,
'widget' and 'widget_class' use the layout of the widget tree.
'widget' is like 'widget_class' but in addition can match against the
name of a widget that needs to be set by 'widgetSetName' before you
realise the widget (i.e. call widgetShowAll on it).

In your example:

style "mySize" {
     GtkButton::inner_border = { 10, 10, 10, 10 }
     GtkButton::child-displacement-x = 10
widget "*.btnStyle" style "mySize"

works (at least the displacement works, when you click the widget).
Observe that the wildcard which means "apply this style for every
widget that is a leaf in the layout hierarchy and whose name is

I hope this helps -- I gradually get to know how styles work, too. I
think the documentation could really be improved.


Deng Chao