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-cacheThis 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 |