#### Moved this to api/ui-faq.xml
Frequently asked questions about the Bonobo UI Handler, version 0.1
by Michael Meeks <firstname.lastname@example.org>
* How do I port my App from the old to the new UI handler ?
If you have written a component, then ideally you should have to
make no code changes, nor re-link the component. There is a compatibility
layer that should just work. However, this exposes you to many evils of
the old interface, and does strange things to paths for radio items etc.
If you have a complex UI you will want to re-write it.
If you have written a container, then again the changes are
minimal, simply replace the gnome_app calls with bonobo_win calls. As long
as you only used the bonobo API to create menus you should be fine.
It is *important* that you replace the ui handler parameter to all calls
to bonobo_client_site_new_view to something of this form:
view_frame = bonobo_client_site_new_view (
This is also true of the UI handler you pass to
bonobo_widget_new_control (..., uih) and its variants
* Where do I find examples ?
See bonobo/app.c which shows several ways of constructing the
UI. See also bonobo/ui.xml. To build standard menus copy items from
std-ui.xml in the documentation.
* How does translation work ?
Every item has a non translated name which is used to construct
a path for programmatic use. This is invariant over translations, it
will often be similar to a label or verb name. User readable text is
prefixed in the XML file by an '_', the file is parsed as it is read
from disk and these '_' are removed as the strings are translated.
In order to extract translatable strings from a header file you
need to use the 'bonobo-ui-extract' utility which will be installed
with bonobo. Do:
bonobo-ui-extract my-app-ui.xml > my-app-ui.h
Ensure that you include my-app-ui.h in your POTFILES.in, but
there is no need to include it in any files.
* Why don't you use XPath / XPointer ?
These are fine reccomendations for addressing elements of an XML
document. A major contributor to these reccomendations is my friend
Daniel Velliard, with whom I discussed this issue. The UI handler
primarily is designed to deal with an extremely dynamic XML structure.
The whole point of a path is to be invariant over XML (de)merges.
It transpires that XPath addressing eg. /menuitem is not suitable
for this situation. Hence an alternative, simple path scheme was
* Where is the code for the UI handler ?
See bonobo-win, bonobo-ui-xml, bonobo-ui-container,
bonobo-ui-component, bonobo-ui-toolbar, bonobo-ui-item, bonobo-ui-compat
Do not see bonobo-ui-handler, bonobo-uih-menu, bonobo-uih-toolbar
bonobo-uih-private. These are the old code.
* But what happens when Component Foo implements 'FileSave' and Component
Baa also implements 'FileSave' ?
The verbs are emitted on the component that registers
them. In this case the verb gets sent to the component associated
with whatever item was activated.
* I'm confused by paths, where does the File menu live ?
In the old strategy there was a partition of the menu vs.
other APIs, so a different paths trategy was used, in the old
setup we would use:
/File [ old ]
In the new setup we use:
/menu/File [ new ]
Thus we can still use the same namespace for toolbars
and other misc. items.
* What does this cmd / widget separation really mean ?
** the plot:
Since we want to be able to allow the user to full customize his or
her menus and toolbars we need to be able to abstract the following
things away from the layout of the menus:
sensitivity, hiddenness, state ( such as toggledness )
Other things we want to separate are:
default labels, tips and pixmaps
** So; how is this separation achieved in practice ?
We have a namespace that 'commands' live in; these can either
be things like 'Save' ( a verb ) or 'Threaded View' ( a state with an
id ). Both verbs and id's are in the same space. So; we describe the
capbilities of a program in terms of the verbs and state inputs it can
handle, and provide a default UI layout, perhaps like this:
<cmd name="baa" _label="Our Label" _tip="Hello World"
<menuitem name="foo" verb="baa"/>
Now; the user can chose to remove the 'Our Label' button, or
more creatively might decide to convert it into a toolbar and change
the label to 'MyLabel':
- <menuitem name="foo" verb="baa"/>
+ <dockitem name="fishy">
+ <toolitem name="foo" verb="baa" _label="MyLabel"/>
** But what does this mean for the programmer ?
What it means, is that when you decided to make this (
dangerous lookin ) verb insensitive, instead of setting sensitive="0"
on the item at path /menu/foo, you instead do it on the item at path
/commands/baa. This then allows the user to have none, one or many
representations of each verb/id as either menu or toolbar items.
** But wait, don't you need Menu_Open for stock menu icons ?
In this case no; since we need to be able to generate either
a menu or a toolbar item view of this verb/id. Consequently the code
will add the Menu_ prefix where needed for you.
** But wait, what if the stock items are called Foo_Open and Baa_Open
for menu / toolbar items ? or ... what if I have a non-stock toolbar
icon that won't fit in a menu ?
Sadly there was not time to implement custom widget sizing
logic, so setting a single pixmap on the verb won't work. However, you
can still set the pixmap on the individual toolbar / menu items at the
expense of customization.
** But what about acclerators ?
** How do I get rid of '_'s in my toolbar labels.
Since accelerators are clearly part of the widget and not the
command it is important to put labels with accelerators in them in
the widget and not the command node. _But_ it is also important to
ensure that a non-accelerated version is left in the command for use
by GUI configuration software as a default label, it would also be
wise to use this as the default toolbar label. So this is good
<cmd name="FileOpen" _label="Open" hidden="1"
_tip="Open a file" pixtype="stock" pixname="Open"
<menuitem name="FileNew" verb="" _label="_New"/>
See std-ui.xml for a set of correctly organised useful cmd
and widget descriptions.
Note that 'verb=""' is shorthand for making the verb name
the same as the node name (in this example, "FileNew"). This is not
the same as leaving the verb out entirely.
* When I look at the xml being transfered I see that many elements
show up as hex strings; why is this ?
* I get a warning saying that something is not correctly encoded,
what does that mean ?
At a very late stage in the development of the new UI
handler two things were discovered:
a) Translated text is not encoded as UTF-8 instead some native
8bit encoding is used.
b) libxml 1 is not capable of cleanly handling UTF-8.
Incredible though it may sound, this is ostensibly for purposes of
validation [ see eg. entities.c (xmlEncodeEntitiesReenterant) ]
Consequently until Gnome 2.0, when we can switch all
translated strings to UTF-8 and also upgrade to libxml 2 ( which fixes
these issues ) the following hack has been added:
As properties are set; if they are named 'label' or 'tip',
they are encoded into hex. When these properties are read and synced
with widget's text they are de-coded back to a sequence of chars.
This also applies to the status text. This then allows translation
in the normal way. The changes involve no programmatic change. The
changes are also done on translation of xml files using the normal
However, some non translation aware code may need to be fixed,
if you see a warning about encoding, it means your code is i18n broken.
This most commonly happens when people construct fragments themselfs
const char xml  = "<menuitem label=\"Foo\">";
component, "/menu", xml, ev);
To do this correctly now, a helper function has been added,
the correct replacement for this is:
const char xml  = "<menuitem _label=\"Foo\">";
component, "/menu", xml,ev);
In the unlikely event that you want to encode strings
yourself, the routines that deal with the process are:
If you find yourself needing to use these a lot, something is
probably wrong ( or you are setting filenames as labels or somesuch ),
please mail the list.
* Why don't my old non-alphanumeric keyboard accelerators work anymore?
Keyboard accelerators are now specified in ItemFactory format, e.g.
"*Control*s". In old Bonobo, you would have passed 'S' to specify the
character. For alphanumeric keys, this translation is obvious and hard
to get wrong. But for non-alphanumeric keys, you now have to use the
symbolic name returned by gdk_keyval_name (which in turn is the symbolic
name returned by XKeysymToString). For example, to specify Control-equal-sign
as a keyboard accelerator now, you use "*Control*equal". "*Control*=" will
silently fail to do anything useful.
Standard KeySym names are obtained from <X11/keysymdef.h> by
removing the XK_ prefix from each name.
* Why do the menu bar titles flash when merging occurs?
They flash if the <submenu> node has been redefined, or if Bonobo
thinks it has been. A common cause for this is to define the label
for the menu in more than one place. Bonobo will not recognize that
<submenu name="File" _label="File"> is identical to a submenu already
defined exactly the same way elsewhere. If you're adding items to an
existing menu, don't redefine the label; refer to the existing submenu
node by name only, e.g. <submenu name="File">. Note that in addition to
flashiness this can also cause torn-off menus to hide themselves.
* Surely the radio group belongs on the Verb !?
Due to the way the group="whatever" works, it is not possible to have
the group set on the command, there can of course be mutiple sets of the
same radio verbs, but they cannot share the same group.
* How do I let the user customize a toolbar once it's hidden?
You really want to add a menu item with the builtin verb
'BonoboCustomize' that should magically do what you want.
* In a UI file I have two <menu> elements, and the menu items inside
the second <menu> do not show up in the application. What's wrong?
You have to put all menu items in a UI file in a single <menu>
element. Instead of this: