GMenuModel has landed



hi,

Today I landed the GMenuModel work on glib master.  A release will be
following shortly.

There is related work in the 'wip/gmenu' branch of Gtk+ that will
hopefully be landing soon.  There is a trivial example in
gtk+/examples/bloatpad.c that demonstrates some of the ideas here.

The main thing to understand about this work is that we are changing how
menus work in Gtk+.  The days of constructing a GtkMenuBar widget and
packing it into a VBox at the top of your window are gone.

GMenuModel is an interface to describe the content of a menu and GMenu
is its obvious implementation (think GtkTreeView vs. GtkTreeStore).
Your application will construct a series of interlinked GMenu instances
to describe the content of your menus.  Fortunately, there is an XML
parser to do this automatically.  It is integrated with GtkBuilder.

Providing the menu in abstract form instead of GtkWidget form addresses
a few long-standing issues in Gtk.  The most notable one is that we will
finally have proper support for the menubar on the mac.

Menubars are no longer a per-window concept.  They are now set for the
entire application.  This is done for two reasons:

  1) every app already has the same menubar (content) in each window

  2) this is how the mac universe operates

The API to set the menubar for the application is, unsurprisingly:

void      g_application_set_menubar     (GApplication *application,
                                         GMenuModel   *menubar);

A new type of menu has also been introduced: the application menu.  This
is the menu that gnome-shell currently only has a "Quit" item in.  Your
application can now control the contents of this menu by whipping up a
GMenu and setting it:

void      g_application_set_app_menu     (GApplication *application,
                                          GMenuModel   *app_menu);


We may add other types of menus in the future.  A jumplist/dock menu
comes to mind.

GMenuModel is a strictly read-only API.  It describes the structure of a
menu, but has no support for invoking actions when items in the menu are
clicked.  This is handled through the already-existing (but now
improved) GActionGroup API.

When creating a menu item, you specify an action name.  This looks like
"app.preferences" or "win.fullscreen".  The part before the dot is the
location of the action (in this case the hard-coded strings "app" and
"win" refer to app-wide and window-specific actions, respectively).

For example:

  <item label='_Quit' action='app.quit'/>

Clicking this menu item would result in the 'quit' action being invoked
on your GApplication.

There is a new GActionMap interface that GApplication now implements.
It can be used to easily add actions to your GApplication.

Gtk also has a new class called GtkApplicationWindow that implements
GActionMap.  That's where the "win." actions go.  Even though the menu
is globally-specified at the level of the application, the actions are
correctly routed to the appropriate window automatically.

There are two new XSettings properties that have been added to
gnome-settings-daemon that specify if the shell will show the
application menu or the menubar.  These values have hard-wired defaults
on non-X platforms.

                    shows-app-menu       shows-menubar
  gnome-shell:      yes                  no
  GNOME 2:          no                   no
  unity:            yes                  yes
  mac os:           yes                  yes

If a particular desktop environment doesn't show a menu then it will be
displayed at the top of each GtkApplicationWindow associated with that
application.  For example, on gnome-shell, the menubar set with
g_application_set_menubar() will be at the top of each window, but on
the mac, it will be at the top of the screen.


We're currently open to making changes to the APIs, so please check them
out and give feedback, but remember that they may change.  If you have
questions about how to use something, please reply here and I'll answer
it for the benefit of all.  I hope to use the contents of this thread as
the basis for writing some introductory material on the topic.

Cheers



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]