GNOME Goal: Applets Dbus Migration
Introduccion
Gnome Panel drop the libbonobo dependency recently (see bug #572131). The objective of this GnomeGoal is to port all Gnome applets to the new DBUS api.
Guidelines
Application code
- libpanel-applet now uses GTK+3 so the first thing you need to do is porting your applet to GTK+3.
Factory macro: change PANEL_APPLET_BONOBO_FACTORY with PANEL_APPLET_OUT_PROCESS_FACTORY. New macro has the same parameters except version that has been removed. Remove the prefix 'OAFIID:GNOME_' from the factory name. See the example:
Old macro:
PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_Wncklet_Factory", PANEL_TYPE_APPLET, "WindowNavigationApplets", "0", wncklet_factory, NULL)
The new version of the macro should be:
PANEL_APPLET_OUT_PROCESS_FACTORY ("WnckletFactory", PANEL_TYPE_APPLET, wncklet_factory, NULL)
Remove the prefix 'OAFIID:GNOME_' from the factory method too:
Old factory method:
static gboolean wncklet_factory (PanelApplet *applet, const char *iid, gpointer data) { gboolean retval = FALSE; static gboolean type_registered = FALSE; if (!type_registered) { wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER); type_registered = TRUE; } if (!strcmp (iid, "OAFIID:GNOME_WindowMenuApplet")) retval = window_menu_applet_fill (applet); else if (!strcmp (iid, "OAFIID:GNOME_WorkspaceSwitcherApplet")|| !strcmp (iid, "OAFIID:GNOME_PagerApplet")) retval = workspace_switcher_applet_fill (applet); else if (!strcmp (iid, "OAFIID:GNOME_WindowListApplet") || !strcmp (iid, "OAFIID:GNOME_TasklistApplet")) retval = window_list_applet_fill (applet); else if (!strcmp (iid, "OAFIID:GNOME_ShowDesktopApplet")) retval = show_desktop_applet_fill (applet); return retval; }
The new one it's the same without the 'OAFIID:GNOME_' prefix
static gboolean wncklet_factory (PanelApplet *applet, const char *iid, gpointer data) { gboolean retval = FALSE; static gboolean type_registered = FALSE; if (!type_registered) { wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER); type_registered = TRUE; } if (!strcmp (iid, "WindowMenuApplet")) retval = window_menu_applet_fill (applet); else if (!strcmp (iid, "WorkspaceSwitcherApplet")|| !strcmp (iid, "PagerApplet")) retval = workspace_switcher_applet_fill (applet); else if (!strcmp (iid, "WindowListApplet") || !strcmp (iid, "TasklistApplet")) retval = window_list_applet_fill (applet); else if (!strcmp (iid, "ShowDesktopApplet")) retval = show_desktop_applet_fill (applet); return retval; }
Applet menu: the new API uses GtkAction to build the menu, so we need to define GtkActionEntry instead of BonoboUIVerb. See the example:
Old menu verbs definition:
static const BonoboUIVerb show_desktop_menu_verbs [] = { BONOBO_UI_UNSAFE_VERB ("ShowDesktopHelp", display_help_dialog), BONOBO_UI_UNSAFE_VERB ("ShowDesktopAbout", display_about_dialog), BONOBO_UI_VERB_END };
New menu actions definition should be:
static const GtkActionEntry show_desktop_menu_actions [] = { { "ShowDesktopHelp", GTK_STOCK_HELP, N_("_Help"), NULL, NULL, G_CALLBACK (display_help_dialog) }, { "ShowDesktopAbout", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, G_CALLBACK (display_about_dialog) } };
If you have toggle action you need to define GtkToggleActionEntry actions too:
static const GtkToggleActionEntry toggle_actions[] = { { "Mute", NULL, N_("Mu_te"), NULL, NULL, G_CALLBACK (cb_verb), FALSE } };
Callbacks should be changed to match the GtkAction callback prototype:
Old callback:
static void display_help_dialog (BonoboUIComponent *uic, ShowDesktopData *sdd, const gchar *verbname)
The new version would be:
static void display_help_dialog (GtkAction *action, ShowDesktopData *sdd)
To setup the menu we use panel_applet_setup_menu_from_file() which has a new API. It takes the file with the ui definitions and a GtkActionGroup, so we need to build a new action group first:
Old code for setting up the menu:
panel_applet_setup_menu_from_file (PANEL_APPLET (sdd->applet), NULL, "GNOME_ShowDesktopApplet.xml", NULL, show_desktop_menu_verbs, sdd);
The new code should be something like:
action_group = gtk_action_group_new ("ShowDesktop Applet Actions"); gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); gtk_action_group_add_actions (action_group, show_desktop_menu_actions, G_N_ELEMENTS (show_desktop_menu_actions), sdd); ui_path = g_build_filename (WNCK_MENU_UI_DIR, "showdesktop-menu.xml", NULL); panel_applet_setup_menu_from_file (PANEL_APPLET (sdd->applet), ui_path, action_group); g_free (ui_path); g_object_unref (action_group);
If the applet has toggle actions you have to call gtk_action_group_add_toggle_actions() to add toggle actions to the action group:
gtk_action_group_add_toggle_actions (action_group, toggle_actions, G_N_ELEMENTS (toggle_actions), applet);
If you need to change any property of a menu item, for example when applet is locked down, you can just get the action from the action group:
if (panel_applet_get_locked_down (PANEL_APPLET (tasklist->applet))) { GtkAction *action; action = gtk_action_group_get_action (action_group, "TasklistPreferences"); gtk_action_set_visible (action, FALSE); }
Menu UI XML file
The new menu xml file is a normal GtkUIManager ui file. It should contain just menutiem entries and separators. See the example:
<menuitem name="Mute" action="Mute" /> <menuitem name="RunMixer" action="RunMixer" /> <separator/> <menuitem name="Pref" action="Pref" /> <menuitem name="Help" action="Help" /> <menuitem name="About" action="About" />
Panel Applet File
It's a key file with information about the applet. Most of the information can be copied from the old .server.in.in file. It must contain a group called 'Applet Factory' with information about the factory and one group for every applet with the applet identifier as the name of the group.
Applet Factory group keys:
- Id: it's the name of the factory, it must be the same name used as the first parameter in PANEL_APPLET_OUT_PROCESS_FACTORY macro
- Location: the path to the applet executable
- Name: factory name (it can be copy-pasted from the .server.in.in file)
- Description: factory description (it can be copy-pasted from the .server.in.in file)
Applet groups keys:
- Name: applet name
- Description: applet description
- Icon: applet icon name
BonoboId: old bonobo identifier, for compatibility. It allows the panel to load applets using the current configuration. It can be a single string or a list of strings in case of applets with more than one identifier.
- Bugzilla fields
All of these keys can be copy-pasted from the .server.in.in file. See the example:
org.gnome.panel.Wncklet.panel-applet.in.in
[Applet Factory] Id=WnckletFactory Location=@LOCATION@ _Name=Window Navigation Applet Factory _Description=Factory for the window navigation related applets [WindowMenuApplet] _Name=Window Selector _Description=Switch between open windows using a menu Icon=gnome-panel-window-menu BonoboId=OAFIID:GNOME_WindowMenuApplet X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=gnome-panel X-GNOME-Bugzilla-Component=window selector X-GNOME-Bugzilla-Version=@VERSION@ X-GNOME-Bugzilla-OtherBinaries=wnck-applet [WorkspaceSwitcherApplet] _Name=Workspace Switcher _Description=Switch between workspaces Icon=gnome-panel-workspace-switcher BonoboId=OAFIID:GNOME_WorkspaceSwitcherApplet;OAFIID:GNOME_PagerApplet X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=gnome-panel X-GNOME-Bugzilla-Component=workspace switcher X-GNOME-Bugzilla-Version=@VERSION@ X-GNOME-Bugzilla-OtherBinaries=wnck-applet [WindowListApplet] _Name=Window List _Description=Switch between open windows using buttons Icon=gnome-panel-window-list BonoboId=OAFIID:GNOME_TasklistApplet;OAFIID:GNOME_WindowListApplet X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=gnome-panel X-GNOME-Bugzilla-Component=window list X-GNOME-Bugzilla-Version=@VERSION@ X-GNOME-Bugzilla-OtherBinaries=wnck-applet [ShowDesktopApplet] _Name=Show Desktop _Description=Hide application windows and show the desktop Icon=user-desktop BonoboId=OAFIID:GNOME_ShowDesktopApplet X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=gnome-panel X-GNOME-Bugzilla-Component=Show Desktop Button X-GNOME-Bugzilla-Version=@VERSION@ X-GNOME-Bugzilla-OtherBinaries=wnck-applet
D-Bus service file
In addition to the panel-applet file we use a D-Bus service file so that applets can be started by the session bus. It's a normal D-Bus file
org.gnome.panel.applet.WnckletFactory.service.in
[D-BUS Service] Name=org.gnome.panel.applet.WnckletFactory Exec=@LOCATION@
Build system (configure)
- Check for libpanel-applet-4 in your configure file, and get the directory where .panel-applet files should go from the pkg-config file, with something like:
LIBPANEL_APPLET_DIR=`$PKG_CONFIG --variable=libpanel_applet_dir libpanelapplet-4.0`
Build system (Makefile.am)
- Add the ui xml path to the CFLAGS:
-DWNCK_MENU_UI_DIR=\""$(xmluidir)"\" \
This is the macro you use when setting up the applet menu
- Panel-applet file:
appletdir = $(LIBPANEL_APPLET_DIR) applet_in_files = GNOME_MixerApplet.panel-applet.in applet_DATA = $(applet_in_files:.panel-applet.in=.panel-applet) $(applet_in_files): $(applet_in_files).in Makefile $(AM_V_GEN)sed \ -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \ $< > $@ %.panel-applet: %.panel-applet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
This rule should probably be moved to intltool as something like:
INTLTOOL_PANEL_APPLET_RULE='%.panel-applet: %.panel-applet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(AM_V_GEN) LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
- D-Bus service file:
servicedir = $(datadir)/dbus-1/services service_in_files = org.gnome.panel.applet.FishAppletFactory.service.in service_DATA = $(service_in_files:.service.in=.service) org.gnome.panel.applet.FishAppletFactory.service: $(service_in_files) $(AM_V_GEN)sed \ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \ $< > $@
- Add panel-applet .in.in and service file to EXTRA_DIST and $(applet_DATA) $(applet_DATA).in to CLEANFILES
EXTRA_DIST = \ GNOME_MixerApplet.panel-applet.in.in \ $(service_in_files) \ $(ui_DATA) \ $(schemas_in_files) CLEANFILES = $(applet_DATA) $(applet_DATA).in $(service_DATA) $(schemas_DATA)
- Remove all references to bonobo, orbit, etc, from configure script. Remove references to .server files and INTLTOOL_SERVER_RULE from Makefile.am and remove .server.in.in file.
Comments before approval
|
Status of this goal
|
State |
Markup |
todo |
<: #ff8080> todo |
patch |
<: #ffcc50> [[GnomeBug:xxxxx|patch]] |
done |
<: #80ff80> [[GnomeBug:xxxxx|done]] |
not needed |
<: #80ff80> not needed |
Above are the states and corresponding markup to update the modules state table below.
Tarball |
Status |
Desktop |
|
bug-buddy |
|
gnome-control-center |
to do |
gnome-netstatus |
to do |
gnome-power-manager |
|
gnome-python-desktop |
|
gnome-utils |
to do |
mousetweaks |
|
tomboy |
|
vinagre |
to do |
Admin |
|
sabayon |
|
Development Tools |
|
glade3 |
to do |
Bindings (python) |
|
gnome-python |
to do |
Bindings (mono) |
|
gnome-sharp |
to do |
External Dependencies |
|
tracker |
|
Other |
|
apt-watch-gnome |
to do |
balsa |
to do |
byzanz |
|
bubblemon |
to do |
fast-user-switch-applet |
to do |
gnote-main-menu |
to do |
gnome-pilot |
|
gnote |
to do |
netspeed |
|
to do |
|
pnee |
to do |
sensors-applet |
|
workrave |
to do |