The only part of dealing with a context menu that is specific to applets is how to setup the context menu. Once it is setup, this is really just a matter of using GtkAction.
To setup the context menu of the applet, the panel_applet_setup_menu_from_file()
function should be used, with a path to a menu XML file and a GtkActionGroup object containing all actions that are used in the menu XML file. The example below shows how to achieve this:
Example 3. Hello World applet, with a context menu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
#include <glib/gi18n.h> #include <gtk/gtk.h> #include <panel-applet.h> /* This would usually be defined in config.h */ #define GETTEXT_PACKAGE "hello-world" /* This would usually be defined in Makefile.am */ #define HELLO_WORLD_UI_DIR "/usr/share/hello-world" static void hello_world_applet_prefs (GtkAction *action, PanelApplet *applet); static void hello_world_applet_say (GtkAction *action, PanelApplet *applet); static const GtkActionEntry hello_world_menu_actions [] = { { "HelloWorldPrefs", GTK_STOCK_HELP, N_("_Preferences"), NULL, NULL, G_CALLBACK (hello_world_applet_prefs) }, { "HelloWorldSay", GTK_STOCK_ABOUT, N_("_Say Hello"), NULL, NULL, G_CALLBACK (hello_world_applet_say) } }; static void hello_world_applet_prefs (GtkAction *action, PanelApplet *applet) { GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Preferences"); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); } static void hello_world_applet_say (GtkAction *action, PanelApplet *applet) { GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Hello World!"); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); } static gboolean hello_world_applet_start (PanelApplet *applet) { GtkWidget *label; GtkActionGroup *action_group; gchar *ui_path; label = gtk_label_new ("Hello World"); gtk_container_add (GTK_CONTAINER (applet), label); action_group = gtk_action_group_new ("Hello World Applet Actions"); gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); gtk_action_group_add_actions (action_group, hello_world_menu_actions, G_N_ELEMENTS (hello_world_menu_actions), applet); ui_path = g_build_filename (HELLO_WORLD_UI_DIR, "hello-world-menu.xml", NULL); panel_applet_setup_menu_from_file (applet, ui_path, action_group); g_free (ui_path); g_object_unref (action_group); gtk_widget_show_all (GTK_WIDGET (applet)); return TRUE; } static gboolean hello_world_factory_callback (PanelApplet *applet, const gchar *iid, gpointer data) { gboolean retval = FALSE; if (g_strcmp0 (iid, "HelloWorldApplet") == 0) retval = hello_world_applet_start (applet); return retval; } PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory", PANEL_TYPE_APPLET, hello_world_factory_callback, NULL) |
Here are the changes compared to the simple example with no context menu:
We define a list of GtkActionEntry entries:
hello_world_menu_actions
. This will be used later on to build GtkAction objects, with their label and callback. We obviously implement the callbacks.We change
hello_world_applet_start()
to define a GtkActionGroup object, to which we add, withgtk_action_group_add_actions()
, GtkAction objects based on the GtkActionEntry entries. Note that the the last argument togtk_action_group_add_actions()
will be passed as user data to the callbacks.We also change
hello_world_applet_start()
to add this GtkActionGroup object to the context menu of the applet, by callingpanel_applet_setup_menu_from_file()
. This function takes as argument a path to the menu XML file that will define how to display the GtkAction objects in the context menu.