Bug 4718 (int-125177)

Summary: GtkButton + hildon_gtk_widget_set_theme_size() has wrong style when created via GtkBuilder
Product: [Maemo Official Platform] Desktop platform Reporter: Thomas Perl <m>
Component: gtkAssignee: unassigned <nobody>
Status: RESOLVED FIXED QA Contact: gtk-bugs
Severity: normal    
Priority: Low CC: agarcia, andre_klapper, christian, csaavedra, daniel.borgmann, hald
Version: 5.0/(2.2009.51-1)   
Target Milestone: 5.0/(10.2010.19-1)   
Hardware: All   
OS: Windows   
URL: https://bugzilla.gnome.org/show_bug.cgi?id=591085
Attachments: Screenshot showing the different style in the beta SDK
Testcase: C sourcecode
Testcase: GtkBuilder .ui file
fix for HildonButton

Description Thomas Perl (reporter) 2009-06-20 01:33:04 UTC
SOFTWARE VERSION:
Fremantle beta SDK

STEPS TO REPRODUCE THE PROBLEM:

 * Create a HildonButton with a GtkBuilder .ui file and
HILDON_SIZE_THUMB_HEIGHT

EXPECTED OUTCOME:

 * The appearance of the widget is correct

ACTUAL OUTCOME:

 * The appearance of the widget is different

REPRODUCIBILITY:

always

OTHER COMMENTS:

Will attach screenshot and example code snippet soon.
Comment 1 Thomas Perl (reporter) 2009-06-20 01:35:47 UTC
Created an attachment (id=1233) [details]
Screenshot showing the different style in the beta SDK
Comment 2 Thomas Perl (reporter) 2009-06-20 01:36:12 UTC
Created an attachment (id=1234) [details]
Testcase: C sourcecode
Comment 3 Thomas Perl (reporter) 2009-06-20 01:36:32 UTC
Created an attachment (id=1235) [details]
Testcase: GtkBuilder .ui file
Comment 4 Thomas Perl (reporter) 2009-06-20 01:39:11 UTC
Steps to reproduce:

 * Download the two Testcase files attached to this bug
   in the same folder inside the SDK
 * Compile hildonbutton.c in Scratchbox with:

  gcc -o hildonbutton hildonbutton.c \
     `pkg-config --libs --cflags hildon-1 gtk+-2.0 gobject-2.0`

 * Run the compiled binary in scratchbox:

  run-standalone.sh ./hildonbutton

This produces the result shown in the screenshot. The widget appearance should
be the same, independent of whether the widget is created using GtkBuilder or
via code.
Comment 5 Claudio Saavedra 2009-06-21 08:27:35 UTC
The problem here is that the proper theming of different-size buttons is set by
using the GtkWidget::name property. GtkBuilder, otoh, uses this property to
store the "id" attribute.
Comment 6 Claudio Saavedra 2009-06-21 08:31:55 UTC
One possible fix is to make HildonButton implement GtkBuildable, store the "id"
in a different form, by implementing (* set_name). This might probably be
necessary for other widgets that use named widgets to get the proper theming.

I'll look into this.
Comment 7 Claudio Saavedra 2009-06-21 09:05:25 UTC
Created an attachment (id=1237) [details]
fix for HildonButton

This is a preliminary fix for this problem in HildonButton. It stores the
GtkBuildable name to a private buildable_name string, leaving the
GtkWidget::name id untouched. This way, HildonButton gets the proper theming.

A similar patch could be cooked for all the hildon widgets that rely in
GtkWidget::name to get proper theming, but I think this deserves a bit of
discussion before proceeding.
Comment 8 Claudio Saavedra 2009-06-21 09:07:15 UTC
Berto, what do you think?
Comment 9 Thomas Perl (reporter) 2009-06-21 14:40:19 UTC
(In reply to comment #5)
> The problem here is that the proper theming of different-size buttons is set by
> using the GtkWidget::name property. GtkBuilder, otoh, uses this property to
> store the "id" attribute.

That's just stupid! Changing the widget name (that should "belong" to the
developer) in order to get themeing right is The Wrong Way (themeing a "group"
of widget, like "thumb button", "finger button", "normal button", that is...).

There are several cases (i.e. a generic signal handler that chooses its action
based on the widget name) and even gtk_builder_get_object() that depend on the
name of the widget.

Please tell me that I'm wrong, but this smells fishy. I don't know of any other
stock GTK widgets that change the name in order to get themeing right.
Comment 10 Claudio Saavedra 2009-06-21 15:35:05 UTC
(In reply to comment #9)
> (In reply to comment #5)
> > The problem here is that the proper theming of different-size buttons is set by
> > using the GtkWidget::name property. GtkBuilder, otoh, uses this property to
> > store the "id" attribute.
> 
> That's just stupid!

This is unnecessary.

> Changing the widget name (that should "belong" to the
> developer) in order to get themeing right is The Wrong Way (themeing a "group"
> of widget, like "thumb button", "finger button", "normal button", that is...).

The difference, of course, being that we use the sapwood theme engine, which is
pixmap-based. For performance reasons (basically to avoid pixmap scaling), the
theme includes specific theming for all the standard button sizes.

In GTK+, there are three ways in which you can tell the theme engine (through
GtkRC) how to select a specific theming for a particular widget instance:

1. By its class.
2. By its widget hierarchy in the UI.
3. By its widget name.

Using (1) and (2) is definitely not enough for perfect-size matching, unless
you want to have a different class for each different button size (which would
be horrible, I'd say). The only resource left is to use the widget name.

> There are several cases (i.e. a generic signal handler that chooses its action
> based on the widget name) and even gtk_builder_get_object() that depend on the
> name of the widget.

I think you are confusing the GtkWidget::name with GtkBuildable's
set/get_name(). In the GtkWidget implementation of the interface, the
GtkBuilder object's name is stored in the GtkWidget::name property, but there's
nothing, AFAIK, that stops a widget from keeping the object name stored in a
different way, as long as the interface is kept consistent and the name stored
in a different place. That's what I did in my patch.

There might be another limitations when using GtkWidget::name for theming, of
course, but that's certainly a different topic.

> Please tell me that I'm wrong, but this smells fishy. I don't know of any
> other stock GTK widgets that change the name in order to get themeing right.

Most likely, there aren't. In the desktop. Desktop theme engines are not using
perfect-size theming, because scaling is hardly an issue (and, anyway, most
modern theme engines are rendering on the fly, using cairo, for instance). This
is a well known difference between the maemo UI and the desktop environments.
Comment 11 Claudio Saavedra 2009-06-21 15:35:36 UTC
Btw, I just noticed that it is possible to set the set/get_name interface
methods to NULL, and GtkBuildable will store then the buildable object's name
as object data. This is even better than adding a private field to
HildonButton.
Comment 12 Thomas Perl (reporter) 2009-06-21 16:00:56 UTC
(In reply to comment #10)
> pixmap-based. For performance reasons (basically to avoid pixmap scaling), the
> theme includes specific theming for all the standard button sizes.
> 
> In GTK+, there are three ways in which you can tell the theme engine (through
> GtkRC) how to select a specific theming for a particular widget instance:
> 
> 1. By its class.
> 2. By its widget hierarchy in the UI.
> 3. By its widget name.
> 
> Using (1) and (2) is definitely not enough for perfect-size matching, unless
> you want to have a different class for each different button size (which would
> be horrible, I'd say). The only resource left is to use the widget name.

How many button sizes are there? From what I know after playing a bit with the
widgets, there is "auto", "finger" and "thumb":

http://maemo.org/api_refs/5.0/pre-alpha/apis/libhildon-2.1.24/hildon-hildon-gtk.html#HildonSizeType

That means in addition to HildonButton, you would have to introduce two more
widgets (HildonFingerButton and HildonThumbButton) in order to be able to
differentiate between these three styles (and the FingerButton and ThumbButton
probably just need to be subclasses of HildonButton without any added
functionality).

> > There are several cases (i.e. a generic signal handler that chooses its action
> > based on the widget name) and even gtk_builder_get_object() that depend on the
> > name of the widget.
> 
> I think you are confusing the GtkWidget::name with GtkBuildable's
> set/get_name(). In the GtkWidget implementation of the interface, the
> GtkBuilder object's name is stored in the GtkWidget::name property, but there's
> nothing, AFAIK, that stops a widget from keeping the object name stored in a
> different way, as long as the interface is kept consistent and the name stored
> in a different place. That's what I did in my patch.

Still, when I'm loading my interface from the .ui file, I use the
"gtk_builder_get_objects()" function to get all objects and store them
somewhere, so I can access them later on. After getting these objects, I use
the get_name method on them to find out which widget it is. If the name is
mangled, things stop working from here. Special-casing the name-getting for
Hildon widgets and using some other method to get the name is tedious and not
really obvious.

> There might be another limitations when using GtkWidget::name for theming, of
> course, but that's certainly a different topic.
> 
> > Please tell me that I'm wrong, but this smells fishy. I don't know of any
> > other stock GTK widgets that change the name in order to get themeing right.
> 
> Most likely, there aren't. In the desktop. Desktop theme engines are not using
> perfect-size theming, because scaling is hardly an issue (and, anyway, most
> modern theme engines are rendering on the fly, using cairo, for instance). This
> is a well known difference between the maemo UI and the desktop environments.

Agreed. Still, I think using subclasses instead of changing the content of
existing properties would be the right way to go. I am sure several developers
that come from a "Desktop" background will be confused by this.

It would be nice to have an overview of how many different button types there
are to differentiate for themes. Currently, setting the widget name involves
some "magic" for the developer that just uses the widgets to get work done.
Having different widget classes makes it obvious what to use and also does not
cause side-effects (i.e. the get_name method returning a different value than
expected).
Comment 13 Claudio Saavedra 2009-06-21 16:04:49 UTC
(In reply to comment #12)
> Still, when I'm loading my interface from the .ui file, I use the
> "gtk_builder_get_objects()" function to get all objects and store them
> somewhere, so I can access them later on. After getting these objects, I use
> the get_name method on them to find out which widget it is.

You should use gtk_buildable_get_name() for this. That works perfectly fine
with/without the patch and is the correct way of accessing the object name.
Comment 14 Alberto Garcia Gonzalez 2009-06-22 14:10:46 UTC
(In reply to comment #7)
> A similar patch could be cooked for all the hildon widgets that rely
> in GtkWidget::name to get proper theming, but I think this deserves
> a bit of discussion before proceeding.

Yes, because that includes standard Gtk buttons (set with
_set_theme_size()).
Comment 15 Claudio Saavedra 2009-06-22 18:21:59 UTC
I discussed with Daniel, Berto, and Kris about using a different approach for
specifying the size of the buttons to the theme. One possibility would be to
use the detail in gtk_paint_box() and change the theming to filter the size of
the button in this way. However, this would imply modifications in GTK+, the
theme, and hildon, and even then, it's hard to be sure that we wouldn't be
breaking applications relying on the widget name to get the proper theming,
unless we propagate the fix for all of them. This is, at this point, unlikely
to be accepted.

(In reply to comment #14)
> (In reply to comment #7)
> > A similar patch could be cooked for all the hildon widgets that rely
> > in GtkWidget::name to get proper theming, but I think this deserves
> > a bit of discussion before proceeding.
> 
> Yes, because that includes standard Gtk buttons (set with
> _set_theme_size()).
> 

In that case, we will probably need to change the GtkBuildable implementation
in the GtkButton class itself or even in GtKWidget. I think that the only risk
here is that applications ported to maemo using GtkBuilder that rely on
gtk_widget_get_name() might not work, but switching to gtk_buildable_set_name()
is an easy fix and also the right thing to do.

Moving to GTK+. The GTK+ people can decide how to deal with this.
Comment 16 Thomas Perl (reporter) 2009-08-28 14:33:08 UTC
Any progress on this? Having the correct themeing when using GtkBuilder would
be very important for many app developers that don't create their UI in code.
Comment 17 Andre Klapper maemo.org 2009-08-28 14:50:12 UTC
This currently does not have a high priority and most likely will not get fixed
for the final Fremantle release.
Comment 18 Thomas Perl (reporter) 2009-09-04 19:39:54 UTC
Just a quick follow-up for developers who ran into the same problem and want to
work around this bug in their apps for Fremantle until it gets fixed:

You can get the desired style by calling gtk_widget_set_name() on your
HildonButton with the correct name (after it has been created by GtkBuilder,
but before it is displayed preferably). For my purposes, this is
"HildonButton-thumb" (have not found a list of possible names, though..)

Example in Python:

  # blubb_button is the button you want to style
  blubb_button.set_name('HildonButton-thumb')

Example in C:

  GtkWidget* blubb_button = /* the button you want to style */;
  gtk_widget_set_name(blubb_button, "HildonButton-thumb");

This works at least in the beta2 SDK. The file in which this style is defined
seems to be /usr/share/themes/default/gtk-2.0/gtkrc. It might be hacky and not
work for all use cases, but it works for me :)
Comment 19 Andre Klapper maemo.org 2009-10-15 13:58:13 UTC
Upstream ticket at https://bugzilla.gnome.org/show_bug.cgi?id=591085 .
Comment 20 Thomas Perl (reporter) 2009-12-03 14:50:27 UTC
FYI, the upstream bug has now been closed as RESOLVED/FIXED:

https://bugzilla.gnome.org/show_bug.cgi?id=591085

Maybe this fix can be backported to the GTK+/Hildon version in Fremantle?
Comment 21 Andre Klapper maemo.org 2009-12-03 15:02:35 UTC
This is done currently - that's why I've set the Target Milestone. :)
Comment 22 Thomas Perl (reporter) 2009-12-23 17:29:00 UTC
Still an issue in 2.2009.51-1. Compiled the example code from comment 2 in
Scratchbox and copied the resulting binary and the .ui file from comment 3 to
the device, and the result is still the same as shown in the screenshot in
comment 1 (although of course the themeing is different).
Comment 23 Christian Dywan 2010-01-06 14:10:10 UTC
This was fixed in the GTK+ repository.
Comment 24 Andre Klapper maemo.org 2010-01-13 18:22:15 UTC
This has been fixed in package
gtk+2.0 2:2.14.7-1maemo23+0m5
which is part of the internal build version
2010.02-5
(Note: 2010 is the year, and the number after is the week.)

A future public update released with the year/week later than this internal
build version will include the fix. (This is not always already the next public
update.)
Please verify that this new version fixes the bug by marking this bug report as
VERIFIED after the public update has been released and if you have some time.


To answer popular followup questions:
 * Nokia does not announce release dates of public updates in advance.
 * There is currently no access to these internal, non-public build versions.
   A Brainstorm proposal to change this exists at
http://maemo.org/community/brainstorm/view/undelayed_bugfix_releases_for_nokia_open_source_packages-002/
Comment 25 Andre Klapper maemo.org 2010-03-15 20:53:30 UTC
Setting explicit PR1.2 milestone (so it's clearer in which public release the
fix will be available to users).

Sorry for the bugmail noise (you can filter on this message).