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
Add your comments to this goal proposal here |
Status of this goal
Tip: If you choose to work on a module, create the bug report on the GNOME bugzilla for the relevant module, and make it block bug 620830. This way people will know someone already works on it, and won't duplicate the work you're doing. |
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 |