GNOME Bugzilla – Bug 667779
Add label-format attribute for GMenuModel
Last modified: 2018-05-24 13:40:08 UTC
Created attachment 205107 [details] [review] simple patch showing the bug See the attached patch hacking example/plugman.c to demonstrate the bug. The menu should display "Snake" but it displays "Mushroom" instead.
I guess g_menu_item_set_label needs to call g_menu_model_items_changed
This is by design. http://developer.gnome.org/gio/unstable/GMenu.html#g-menu-insert-item """ The "insertion" is actually done by copying all of the attribute and link values of item and using them to form a new item within menu. As such, item itself is not really inserted, but rather, a menu item that is exactly the same as the one presently described by item. This means that item is essentially useless after the insertion occurs. Any changes you make to it are ignored unless it is inserted again (at which point its updated values will be copied). You should probably just free item once you're done. """ In short: it's not possible to change attribute values on a menu item after it is added. You have two options for dealing with this. The first is that you remove the item from the menu and add a new one. That's not so great. The second is that we come up with some way for connecting menu text with action state. For example, we could have an item like: <item label='Fullscreen' active-label='Leave Fullscreen'/> for a menu item that shows 'Fullscreen' or 'Leave Fullscreen' depending on whether the associated action is 'active' or not. Can you give more information about your specific use case?
In Empathy we have a menu item displaying the credit you have one a specific account; clicking on it opens a webpage to topup this account. For example: "Top Up SIP (€10.20)" So the item has to be updated each time the credit is changed. We use to do that usinggtk_action_set_label() and so was expecting to do the same using g_menu_item_set_label().
You will just have to do g_menu_remove / g_menu_insert_item. Ryan, do we batch the D-Bus updates for that kind of sequence ? I guess we do, because the signals are emitted out of an idle...
I'm not sure that has to be the final word. I wouldn't mind introducing the possibility to introduce the state from the related action into the label text using a format-string sort of construction. This is something that I've often thought about doing before... This sort of thing is really necessary when you consider that different windows in the application could be using the same menu but have different state. The fullscreen window one is a good example. You certainly don't want to go changing the structure of the menu in that case because it won't be true for all windows. It's probably not true in this particular case, but I could easily imagine a situation in which we have separate sipphone windows for two different accounts, each of which presumably has a different balance......
Sure, g_menu_replace_item ?
I was planning to create one action per SIP account in that case, but yeah, being able to re-use the same one would be cool. Btw, while it has been pretty straightforward to port the simple use cases (static menus defined in a XML file) the more complex (ie, dynamic ones) are a real pain to re-implement using the new API. So I really think that having more helper API on this side is needed.
Review of attachment 205107 [details] [review]: not meant to be committed
I'm working on this now. Some initial thoughts: We will have a new label-format='' attribute on GMenuItem. It will be based on python format strings with the % operator and a dictionary, where the dictionary is the (effective) GActionMuxer visible from the menuitem. So for example, you could write: label-format='Top up SIP (€%(win.sip-balance).2d)' to get the value of the "win.sip-balance" attribute as part of the label, formatted as '%.2d' would. This is the same(ish) syntax used from python: 'Top up SIP (€%(sip-balance).2d)' % { "sip-balance": 10.20, "other stuff": ... } In your case I'd actually expect you to deal with the currency formatting on the other side because showing the correct currency symbol and the appropriate amount of decimal places is difficult, so you could just send it as a string "€ 10.20". You could of course imagine trying to use a format like: %(currency-symbol)s %(sip-balance).*(currency-precision)d but even that has the possibility to get the symbol on the wrong end (since afaik it's more customary to put the € at the end, but $ at the start). The intention is to support (nearly) all of printf formats, minus the field width specifiers (being unnecessary because we are not actually collecting varargs) and minus weird things like %m and %n. I'd also want not to support field width and precision on %s because the C spec says that these are measured in bytes, which means we could split a utf8 char down the middle, and that's ridiculous... It's also somewhat less useful to have string field widths in a UI environment with variable-width fonts. One feature that this format will absolutely have is a limited 'dereferencing' language into GVariants, thus: If the action named in the parens [ %(action)s ] has a simple-valued state then it is used directly (and hopefully it is compatible, ints for ints, strings for strings, etc). If the action has a dictionary-valued state then you will be able to perform lookups in that dictionary using this sort of syntax: %(action-name['key'])s and if the action is another container type (ie: most useful with tuples) then %(action-name[3])s would pick the tuple item at index 3. _Maybe_ we support multiple dereferences, but probably not at first. ie: %(action-name[3]['key'])s is the 'key' item in the dictionary that is item-3 on the tuple that is the state of action-name. Past that, I don't expect or intend to further expand the expressions that are supported, so I don't think we're particularly in danger of accidentally creating a general-purpose expression language here. The only other possibility in my opinion is that we implement a format closer to PEP 3101: spec: http://www.python.org/dev/peps/pep-3101/ better docs: http://docs.python.org/2/library/string.html#formatstrings Although this has a 'more modern' feel to it, I hesitate because it will not be as familiar to people as printf-style formatting.
I'm somewhat opposed to introducing an alternative string formatting syntax here.
Something like this is required for apps where the menus change frequently, e.g. the tabs menu in gnome-terminal where the menu item's label is the tab title.
*** Bug 764000 has been marked as a duplicate of this bug. ***
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/498.