After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 527672 - Builder should support regular building of menus
Builder should support regular building of menus
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Class: GtkBuilder
unspecified
Other Linux
: Normal normal
: ---
Assigned To: GtkBuilder maintainers
GtkBuilder maintainers
Depends on:
Blocks:
 
 
Reported: 2008-04-12 08:17 UTC by Tristan Van Berkom
Modified: 2008-11-07 20:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Adds some properties and support to get menus loading from builder (16.29 KB, patch)
2008-04-12 08:22 UTC, Tristan Van Berkom
none Details | Review
Better patch (24.44 KB, patch)
2008-10-29 20:28 UTC, Tristan Van Berkom
none Details | Review
Same patch, now frees a string in a newly added gtk_image_menu_item_finalize() (25.40 KB, patch)
2008-10-29 20:48 UTC, Tristan Van Berkom
none Details | Review
Revised patch again (26.98 KB, patch)
2008-10-29 21:45 UTC, Tristan Van Berkom
needs-work Details | Review
New and improved (37.31 KB, patch)
2008-10-30 19:13 UTC, Tristan Van Berkom
needs-work Details | Review
The docs (2.99 KB, patch)
2008-10-30 19:15 UTC, Tristan Van Berkom
none Details | Review
good docs (2.99 KB, patch)
2008-10-30 19:19 UTC, Tristan Van Berkom
none Details | Review
docs (2.93 KB, patch)
2008-10-30 19:23 UTC, Tristan Van Berkom
committed Details | Review
Latest patch (41.62 KB, patch)
2008-10-31 19:40 UTC, Tristan Van Berkom
none Details | Review
Latest patch (41.62 KB, patch)
2008-10-31 19:41 UTC, Tristan Van Berkom
none Details | Review
Another bugfix (41.60 KB, patch)
2008-10-31 22:32 UTC, Tristan Van Berkom
none Details | Review
Latest update (41.80 KB, patch)
2008-11-01 20:41 UTC, Tristan Van Berkom
reviewed Details | Review
Complete with tests (41.65 KB, patch)
2008-11-05 16:06 UTC, Tristan Van Berkom
accepted-commit_now Details | Review
Improved add_child() approach/improved warnings (42.33 KB, patch)
2008-11-06 16:53 UTC, Tristan Van Berkom
committed Details | Review

Description Tristan Van Berkom 2008-04-12 08:17:03 UTC
attaching a patch.
Comment 1 Tristan Van Berkom 2008-04-12 08:22:55 UTC
Created attachment 109107 [details] [review]
Adds some properties and support to get menus loading from builder

Ok, havent had time to put tests yet, but I think its pretty good:

  - added gtk_menu_item_set_label() and gtk_menu_item_set_use_underline()
  - added "label" and "use-underline" properties to menuitem
  - gtk_*_menu_item_new_with_[label/mnemonic]() now simply use
    the properties instead of all that duplicated code
  - gtk_menu_item is buildable and adds child menus correctly
  - gtk_image_menu_item() added construct-only "use-stock" property

The "use-stock" property is tricky and only works from builder
parse finished, since it needs to get the accelerators from the toplevel.

Still need to add tests.
Comment 2 Tristan Van Berkom 2008-04-12 08:30:51 UTC
Ok on second thought Ill have to give it another go.

in the image menu item parse_finished I need to get the
real toplevel window it was created for, so that I can 
correctly attach to the accel_group, shouldnt be too
tricky.

also one more thing to do to get menu support complete
is to add support for the custom image, I suppose I might
pull that off by using the IconFactory & stock ids.
Comment 3 Johan (not receiving bugmail) Dahlin 2008-04-12 12:15:47 UTC
I'm still don't think this is a good idea. 
There is already a way of constructing menus using GtkBuilder, there should be no need to have another way of doing the same thing.

The part which uses g_object_new is probably a good idea though, but it's not builder specific and should be filed in separate bug(s).
Comment 4 Tristan Van Berkom 2008-04-12 15:11:54 UTC
There is no way of building menus in GtkBuilder strictly speaking,
only a way of building UIManagers, there's quite a difference, when
building menus normally you will be allowed although possibly not
recommended to connect to normal signals etc, and set menu properties
directly, such as custom filename images for image menu items, not
having that these capabilities would be quite a regression.

Normally, you should be able to attach actions to your menu items
and tool items post menu/toolbar creation, also via properties,
I also plan to take care of this.

I agree that a dual standard is a bad thing and would be more than
happy to work on what would need to be done to deprecate the UIManager
and finally have a singe standard ui parser in gtk+: GtkBuilder only :)

As I understand it the only feature remaining would be menu/toolbar
mergeability, this seems a little complex but doable possibly at a 
GMergableIface level, implemented by menus and toolbars.

I *dont* think that full deprecation of GtkUIManager should be a 
requesite of integration of real, direct menu building in gtk+.
Comment 5 Tristan Van Berkom 2008-04-13 14:02:02 UTC
You know, I'm a little tired right now - after 14hrs bus, I've
had time to relax and think about it - I dont feel so strongly
about menus in builder anymore.

Taking into consideration that we can generate icons using the 
icon factory to generate menu items with custom icons, there isnt
really regressions concerning old menus, if the general sentiment
is that menus should be built from actions, then lets concentrate
on making sure actions rock in gtk+ instead.

I will definitly still support toolbars in glade, since toolbars
cant be assumed to be "the main application toolbar", and it can
still be usefull to add custom widgets to toolbaritems.

Other than that I think I will still formally propose, with a patch
to the list, that we add a "proxy-for-action" property to GtkWidget 
class, allowing us to discourage direct use of widget signals in 
general... also will come around to close this bug, all this after 
I take a good sleep and make sure I'm thinking straight ;-)

Comment 6 Johan (not receiving bugmail) Dahlin 2008-04-13 15:32:01 UTC
I'm not against the patch per se, just the builder specific parts.
There's really nothing in the patch that should be tied to GtkBuilder. Cleaning up the construction of GtkMenuItems and adding an additional constructors to GtkImageMenuItem sounds like a very sane approach.

However, the add_child(submenu) is a critical part of this patch which cannot easily be replaced by other means. *just* adding that builder specific part to GtkMenuItem would but okay I guess.

I'm not the maintainer of the menus in gtk though, so you'd have to get that part reviewed by Mattias.
Comment 7 Matthias Clasen 2008-10-27 04:48:04 UTC
The label and use-underline properties look like a nice cleanup for the various menuitem constructors. 
I'm not really sold on the use-stock property yet. At least, the current implementation looks like it can only work in GtkBuilder ? 
If we add such a property, then e.g.

g_object_new (GTK_TYPE_IMAGE_MENUITEM, 
              "label", GTK_STOCK_OK, 
              "use-stock", TRUE, NULL);

ought to work too.
Comment 8 Tristan Van Berkom 2008-10-29 20:28:27 UTC
Created attachment 121600 [details] [review]
Better patch

Ok, this patch now allows:

g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
              "label", text,
              "use-underline", TRUE,
              "use-stock", TRUE,
              "accel-group", group,
              NULL);

(and appropriately fixes gtk_image_menu_item_new_from_stock() to use
that constructor).

The parser_finished() for the imagemenuitem will resolve the accel_group
for stock items automatically.

As for gtk_image_menu_item_set_image(), i.e. the "image" property,
I will in glade make a conversion to actually use that property instead
of the internal-child method of libglade, so no worries there.
Comment 9 Johan (not receiving bugmail) Dahlin 2008-10-29 20:40:19 UTC
Looking pretty good.

Quick review:
 - buildertest should be extended, constructing a normal and one with type=submenu should work as expected. Making sure that everything in _parser_finished() is executed is a good idea
 - You can't add new fields to the end of a public struct, since the size of the struct is used in subclassing for instance. Use the private data if there is one, if there isn't add one.
Comment 10 Tristan Van Berkom 2008-10-29 20:48:52 UTC
Created attachment 121603 [details] [review]
Same patch, now frees a string in a newly added gtk_image_menu_item_finalize()
Comment 11 Christian Dywan 2008-10-29 21:04:29 UTC
(In reply to comment #10)
> Created an attachment (id=121603) [edit]
> Same patch, now frees a string in a newly added gtk_image_menu_item_finalize()

Please add g_object_notify to all new accessors.

+  if (image_menu_item->label_copy)
+    g_free (image_menu_item->label_copy);

No need to check here, g_free does the NULL-check for free. You might even want to set the pointer to NULL in the _finalize handler.

+  gtk_menu_item_ensure_label (menu_item);
+  gtk_label_set_use_underline (GTK_LABEL (GTK_BIN (menu_item)->child), setting);

I would suggest you go the safe route and check if gtk_bin_get_child actually refers to a label. The current code will end up in a warning if a subclass placed a different widget there.
Comment 12 Tristan Van Berkom 2008-10-29 21:45:56 UTC
Created attachment 121609 [details] [review]
Revised patch again

Updated patch as per chirstians comments, now added property
notifications where needed (calling gtk_menu_item_set_label() from
gtkimagemenuitem.c will provoke a notificaion so I didnt add one
there), also made gtk_menu_item_* account for alien GTK_BIN(item)->child
widgets.

Also made GtkImageMenuItem's new struct members private
(I was somehow under the impression that GSEAL() made it
so I didnt need private structures... my bad).

I'll take care of adding tests to gtk/tests/builder.c 
hopefully later tonight...
Comment 13 Matthias Clasen 2008-10-30 14:59:05 UTC
I'm not sure I like the way in which the label property is duplicated between GtkMenuItem and GtkImageMenuItem. 

And I think the accelgroup handling in GtkImageMenuItem is at least dubious, if not outright wrong. I don't think gtk_image_menu_item_buildable_parser_finished 
has any business creating an accel group. Shouldn't it just do whatever gtk_image_menu_item_new_from_stock does ?

Also, the same comment I made about labels applies here too: menuitems are very common widgets, so I'd like to avoid blowing them up if at all possible.
Comment 14 Tristan Van Berkom 2008-10-30 16:00:32 UTC
Matthias, 
   thanks for reading the patch :)

a.) The label property was overridden, and only the value handled
    differently in the image menu item in the case of use_stock,
    I could try avoiding keeping the string around, but its risky,
    I need to have it stored somewhere if use-stock is changed,
    the resulting label will be corrupt (looking up in the stock
    for an ID based on an already rendered label), I dont see how
    that could work without the properties having a precise order
    in which they are to be setup.

b.) inasmuch as the parser_finished calls the same code that
    setting accel-group does with stock set, it works pretty much
    like new_from_stock(), it only exists to invent the accel_group,
    which is definitely a hack imported from libglade.

That being said, I'd love to do away with (b), I'll try removing
buildable completely from gtkimagemenuitem and building an explicit
accel_group for the toplevel window, and setting the property on
the menuitem, setting the "accel-group" should always result in
the menu item updating, and this way we could also afford to drop
the added struct member... I'll see what I can do...

Comment 15 Tristan Van Berkom 2008-10-30 19:13:36 UTC
Created attachment 121680 [details] [review]
New and improved

Ok I think I got it right this time :)

So differences from the last patch:
  - Now GtkMenuItemClass takes a set/get_label() vfunc
  - GtkImageMenuItem doesnt override properties, but has
    a different implementation of get/set_label() (I had
    it backwards before obviously).
  - GtkImageMenuItem is *not* a GtkBuildable, if there is
    ever an accel_group set, it will create its accel from the
    stock and connect to the group (provided stock is set
    and available)
  - GtkImageMenuItem knocks off the unneeded "accel_group" pointer
  - GtkWindow now takes an "accel-groups" custom tag to add
    accel groups to a window.

I have a skeleton for tests in there, that I have tested
as a file, but I havent quite figured how to test it yet,
since I cant find public apis to test the things that need
testing...
Comment 16 Tristan Van Berkom 2008-10-30 19:15:22 UTC
Created attachment 121681 [details] [review]
The docs

This covers GtkMenuItem child "submenus" and GtkWindow "accel-groups"
Comment 17 Tristan Van Berkom 2008-10-30 19:19:02 UTC
Created attachment 121682 [details] [review]
good docs

oops that was the outdated docs patch, this is the good one ;-)
Comment 18 Tristan Van Berkom 2008-10-30 19:23:17 UTC
Created attachment 121683 [details] [review]
docs

ok Im obviously not on the ball with the docs, and I have to 
admit I havent went though compiling them, which I know takes
a long time... sorry for the spam guys.
Comment 19 Tristan Van Berkom 2008-10-30 20:45:46 UTC
Just noting, theres something I can do more for the priv->label,
for it to work right I believe I still need the pointer, but
at least I can avoid the dupped string in the case of
use-stock=False... its alot of code now so for the moment, I'll 
wait for a review for the next patch.
Comment 20 Matthias Clasen 2008-10-31 04:58:53 UTC
Looks basically ok to me now. 

I don't think you can avoid duping the string.


Some details:

+  if (strcmp (element_name, "group") == 0)
+    for (i = 0; names[i]; i++)
+      if (strcmp (names[i], "name") == 0)
+	data->items = g_slist_prepend (data->items, g_strdup (values[i]));
+  else if (strcmp (element_name, "accel-groups") == 0)
+    return;
+  else
+    g_warning ("Unsupported tag type for GtkWindow: %s\n",
+	       element_name);

I'd insert some {} here, just for clarity.


  if (strcmp (tagname, "accel-groups"))
+    return;
+  

Please add an "!= 0" here.


+      g_value_set_object (value, (GObject*) image_menu_item->image);

(Not your fault, but) the cast is not needed here, g_value_set_object takes a gpointer.


+  if (priv->label != label)
+    {
+      g_free (priv->label);
+      priv->label = g_strdup (label);
+    }
+
+  gtk_image_menu_item_recalculate (GTK_IMAGE_MENU_ITEM (menu_item));
+
+  g_object_notify (G_OBJECT (menu_item), "label");

Should move the recalculate and the notify into the if as well.


+  void (* set_label)            (GtkMenuItem *menu_item,
+				 const gchar *label);
+  G_CONST_RETURN gchar *(* get_label) (GtkMenuItem *menu_item);
 
   /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);


Looks to me like you need to remove one more padding here. But please take away from the other end so that the reserved slots still start at 1.
Comment 21 Matthias Clasen 2008-10-31 05:08:53 UTC
The docs patch looks fine.
Comment 22 Tristan Van Berkom 2008-10-31 19:40:38 UTC
Created attachment 121743 [details] [review]
Latest patch

This patch is a bit more tidy, fixes the last comments
from Matthias + a possible double free when destroying
windows (using set_qdata_full() on an allocated list... fixed),
and a fixed crash in buildable warning messages.

I'm including commented test cases in this patch for 
buildable menus incase someone has a good idea how they
can be implemented.
Comment 23 Tristan Van Berkom 2008-10-31 19:41:27 UTC
Created attachment 121744 [details] [review]
Latest patch

This patch is a bit more tidy, fixes the last comments
from Matthias + a possible double free when destroying
windows (using set_qdata_full() on an allocated list... fixed),
and a fixed crash in buildable warning messages.

I'm including commented test cases in this patch for 
buildable menus incase someone has a good idea how they
can be implemented.
Comment 24 Tristan Van Berkom 2008-10-31 22:32:38 UTC
Created attachment 121758 [details] [review]
Another bugfix

The last patch was broken in cases where the GtkImageMenuItem has
to invent the child label 
(i.e. g_object_new (IMAGE_MENU_ITEM, "label", label, "image", image, NULL)).

In this update GtkImageMenuItem always uses GtkMenuItemClass->set_label to
update the text, so the menuitem class is still the only one responsable for
creating the label.
Comment 25 Matthias Clasen 2008-11-01 03:18:06 UTC
gtk_window_buildable_custom_tag_start needs to chain up
Comment 26 Matthias Clasen 2008-11-01 03:27:21 UTC
Looking at the test code, maybe you can use gtk_accelerator_parse to parse the label and compare the key and mods instead of formatting keys and mods and compare the strings...
Comment 27 Tristan Van Berkom 2008-11-01 20:41:57 UTC
Created attachment 121791 [details] [review]
Latest update

Ok fixed window to chain up from custom_tag_start/finish (my
mistake copy/pasting from sizegroup, which doesnt need that
treatment).

Unfortunately GtkAccelLabel makes a cute displayable string,
while gtk_accelerator_parse() hand checks for the '<' and '>'
(and accel-label doesnt create any of those).
Comment 28 Matthias Clasen 2008-11-04 02:20:32 UTC
Hmm, why do your patches not apply to gtk trunk here ?

Anyway, another idea for the test: 

- You can check the hierarchy (ie

  imagemenuitem1's parent is menu1, 
  menu1 is attached to menuitem1, 
  menuitem1's parent is menubar1,
  etc

- For the accel label check: how about contructing another stock gtk-new accellabel, and compare its accel_string to the menuitems ?
Comment 29 Tristan Van Berkom 2008-11-05 16:06:38 UTC
Created attachment 122033 [details] [review]
Complete with tests

Ok this one includes the accel_label test by way of creating
another imagemenuitem and checking that both accels are properly
set.

Also, I had made sure from gtk_menu_item_*() apis that alien children
of menuitems would be safe, but I had a remaining bug in buildable->add_child(),
thats fixed and a test is added to ensure alien children are allowed.
Comment 30 Matthias Clasen 2008-11-06 02:51:30 UTC
-  g_warning ("'%s' is not a valid child type of '%s'", type, g_type_name (G_OBJECT_TYPE (type)))
+  g_warning ("'%s' is not a valid child type of '%s'", type, g_type_name (G_OBJECT_TYPE (object)))

Please commit this fix separately.

Also, it would be good to commit the buildable implementation and tests separately from the new menuitem api.

Can you do that ?
Comment 31 Johan (not receiving bugmail) Dahlin 2008-11-06 11:20:18 UTC
I also have the feeling that gtk_menu_item_buildable_add_child can be simplified. Shouldn't it chain up to the parent for starters?
Comment 32 Tristan Van Berkom 2008-11-06 16:53:56 UTC
Created attachment 122122 [details] [review]
Improved add_child() approach/improved warnings

This one makes all the relavent warnings handled in the
gtkcontainer fallback implementation of buildable_add_child() instead
of doing anything from menuitems buildable_add_child().
Comment 33 Tristan Van Berkom 2008-11-06 17:37:25 UTC
With that, I committed it all seperately, here is the related 
changelog entries.

I made that last change to gtkmenuitem.c:buildable_add_child() to
offload the warnings to the container implementation, it was a minor
change and were deffinitly better off, I hope thats ok, I wont be
too far if theres any problems :)


2008-11-06  Tristan Van Berkom <tvb@gnome.org>

	* gtk/gtkmenuitem.c: Made buildable and added support for adding children
	of type "submenu"

	* gtk/gtkwindow.c: Added support for custom tag "accel-groups" to add GtkAccelGroups
	to the window.

	* gtk/gtkcontainer.c: Added builder contextual warnings in buildable_add_child()

	* gtk/tests/builder.c: Added tests for buildable menus (test that accelerators are
	properly connected on stock items, test the menu hierarchy, test permission to
	add alien/custom menuitem children).

	* docs/reference/gtk/tmpl/gtkbuilder.sgml, docs/reference/gtk/tmpl/gtkwindow.sgml,
	docs/reference/gtk/tmpl/gtkmenuitem.sgml: Updated docs for buildable submenus
	and accel groups.

2008-11-06  Tristan Van Berkom <tvb@gnome.org>

	* gtk/gtkmenuitem.[ch]: added new apis gtk_menu_item_[set/get]_label() and
	gtk_menu_item_[set/get]_use_underline() with "label" and "use-underline"
	properties, constructors cleaned up to use g_object_new().
	GtkMenuItemClass take new vfuncs ->get/set_label().

	* gtk/gtkcheckmenuitem.c: constructors cleaned up to use g_object_new().

	* gtk/gtkimagemenuitem.[ch]: added new apis gtk_image_menu_item_[get/set]_use_stock()
	and gtk_image_menu_item_set_accel_group() with "use-stock" and write-only
	"accel-group" properties. constructors cleaned up to use g_object_new().

2008-11-06  Tristan Van Berkom <tvb@gnome.org>

	* gtk/gtkbuilder.h: Fixed a crasher in GTK_BUILDER_WARN_INVALID_CHILD_TYPE()
Comment 34 Christian Dywan 2008-11-07 13:22:52 UTC
(In reply to comment #33)
> I made that last change to gtkmenuitem.c:buildable_add_child() to
> offload the warnings to the container implementation, it was a minor
> change and were deffinitly better off, I hope thats ok, I wont be
> too far if theres any problems :)

I ran gimp and midori on trunk today, and so far I didn't see any regressions at least.

Note that there are two attachments still not marked as obsolete, would be nice if you could check that just to make sure nothing was left open.