Browse Source

Implement a remote-event signal for plugins.

This allows to send messages to plugins using the (hidden)
xfce4-panel command line option
--plugin-event=plugin-name:name:type:value. This can for
example be used to popup a plugin menu from a script.

Plugins running in a wrapper don't support the boolean return
value yet.
upstream/xfce4-panel-4.10.1
Nick Schermer 13 years ago
parent
commit
f56f0609af
  1. 1
      libxfce4panel/libxfce4panel-marshal.list
  2. 1
      libxfce4panel/libxfce4panel.symbols
  3. 12
      libxfce4panel/xfce-panel-plugin-provider.c
  4. 7
      libxfce4panel/xfce-panel-plugin-provider.h
  5. 47
      libxfce4panel/xfce-panel-plugin.c
  6. 3
      libxfce4panel/xfce-panel-plugin.h
  7. 16
      panel/main.c
  8. 105
      panel/panel-dbus-client.c
  9. 3
      panel/panel-dbus-client.h
  10. 16
      panel/panel-dbus-service-infos.xml
  11. 69
      panel/panel-dbus-service.c
  12. 77
      panel/panel-module-factory.c
  13. 4
      panel/panel-module-factory.h
  14. 22
      panel/panel-plugin-external.c
  15. 2
      wrapper/main.c

1
libxfce4panel/libxfce4panel-marshal.list

@ -1 +1,2 @@
BOOLEAN:INT
BOOLEAN:STRING,BOXED

1
libxfce4panel/libxfce4panel.symbols

@ -131,5 +131,6 @@ xfce_panel_plugin_provider_show_configure
xfce_panel_plugin_provider_get_show_about
xfce_panel_plugin_provider_show_about
xfce_panel_plugin_provider_remove
xfce_panel_plugin_provider_remote_event
#endif
#endif

12
libxfce4panel/xfce-panel-plugin-provider.c

@ -206,5 +206,17 @@ xfce_panel_plugin_provider_remove (XfcePanelPluginProvider *provider)
gboolean
xfce_panel_plugin_provider_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value)
{
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
return (*XFCE_PANEL_PLUGIN_PROVIDER_GET_IFACE (provider)->remote_event) (provider, name, value);
}
#define __XFCE_PANEL_PLUGIN_PROVIDER_C__
#include <libxfce4panel/libxfce4panel-aliasdef.c>

7
libxfce4panel/xfce-panel-plugin-provider.h

@ -67,6 +67,9 @@ struct _XfcePanelPluginProviderIface
gboolean (*get_show_about) (XfcePanelPluginProvider *provider);
void (*show_about) (XfcePanelPluginProvider *provider);
void (*remove) (XfcePanelPluginProvider *provider);
gboolean (*remote_event) (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value);
};
/* signals send from the plugin to the panel (possibly
@ -123,6 +126,10 @@ void xfce_panel_plugin_provider_show_about (XfcePanelPluginProv
void xfce_panel_plugin_provider_remove (XfcePanelPluginProvider *provider);
gboolean xfce_panel_plugin_provider_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value);
G_END_DECLS
#endif /* !__XFCE_PANEL_PLUGIN_PROVIDER_H__ */

47
libxfce4panel/xfce-panel-plugin.c

@ -79,6 +79,9 @@ static void xfce_panel_plugin_show_configure (XfcePanelPluginPr
static gboolean xfce_panel_plugin_get_show_about (XfcePanelPluginProvider *provider);
static void xfce_panel_plugin_show_about (XfcePanelPluginProvider *provider);
static void xfce_panel_plugin_remove (XfcePanelPluginProvider *provider);
static gboolean xfce_panel_plugin_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value);
static void xfce_panel_plugin_take_window_notify (gpointer data,
GObject *where_the_object_was);
@ -104,6 +107,7 @@ enum
CONFIGURE_PLUGIN,
FREE_DATA,
ORIENTATION_CHANGED,
REMOTE_EVENT,
REMOVED,
SAVE,
SIZE_CHANGED,
@ -260,6 +264,29 @@ xfce_panel_plugin_class_init (XfcePanelPluginClass *klass)
g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1, GTK_TYPE_ORIENTATION);
/**
* XfcePanelPlugin::remote-event
* @plugin : an #XfcePanelPlugin.
* @name : name of the signal.
* @value : value of the signal.
*
* This signal is emmitted by the user by running
* xfce4-panel --plugin-event=plugin-name:name:type:value. It can be
* used for remote communication, like for example to popup a menu.
*
* Returns: %TRUE to stop signal emission to other plugins, %FALSE
* to send the signal also to other plugins with the same
* name.
**/
plugin_signals[REMOTE_EVENT] =
g_signal_new (g_intern_static_string ("remote-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (XfcePanelPluginClass, remote_event),
NULL, NULL,
_libxfce4panel_marshal_BOOLEAN__STRING_BOXED,
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_VALUE);
/**
* XfcePanelPlugin::removed
* @plugin : an #XfcePanelPlugin.
@ -517,6 +544,7 @@ xfce_panel_plugin_provider_init (XfcePanelPluginProviderIface *iface)
iface->get_show_about = xfce_panel_plugin_get_show_about;
iface->show_about = xfce_panel_plugin_show_about;
iface->remove = xfce_panel_plugin_remove;
iface->remote_event = xfce_panel_plugin_remote_event;
}
@ -1192,6 +1220,25 @@ xfce_panel_plugin_remove (XfcePanelPluginProvider *provider)
static gboolean
xfce_panel_plugin_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value)
{
gboolean stop_emission;
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN (provider), TRUE);
panel_return_val_if_fail (name != NULL, TRUE);
panel_return_val_if_fail (G_IS_VALUE (value), TRUE);
g_signal_emit (G_OBJECT (provider), plugin_signals[REMOTE_EVENT], 0,
name, value, &stop_emission);
return stop_emission;
}
static void
xfce_panel_plugin_take_window_notify (gpointer data,
GObject *where_the_object_was)

3
libxfce4panel/xfce-panel-plugin.h

@ -59,6 +59,9 @@ struct _XfcePanelPluginClass
void (*about) (XfcePanelPlugin *plugin);
void (*configure_plugin) (XfcePanelPlugin *plugin);
void (*removed) (XfcePanelPlugin *plugin);
gboolean (*remote_event) (XfcePanelPlugin *plugin,
const gchar *name,
const GValue *value);
/*< private >*/
void (*reserved1) (void);

16
panel/main.c

@ -56,6 +56,7 @@ static gchar *opt_add = NULL;
static gboolean opt_restart = FALSE;
static gboolean opt_quit = FALSE;
static gboolean opt_version = FALSE;
static gchar *opt_plugin_event = NULL;
static gchar **opt_arguments = NULL;
@ -71,13 +72,14 @@ static gboolean callback_handler (const gchar *name,
#define PANEL_CALLBACK_OPTION G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_handler
static GOptionEntry option_entries[] =
{
{ "preferences", 'p', PANEL_CALLBACK_OPTION, N_("Show the 'Panel Preferences' dialog"), N_("PANEL NUMBER") },
{ "add-items", 'a', PANEL_CALLBACK_OPTION, N_("Show the 'Add New Items' dialog"), N_("PANEL NUMBER") },
{ "preferences", 'p', PANEL_CALLBACK_OPTION, N_("Show the 'Panel Preferences' dialog"), N_("PANEL-NUMBER") },
{ "add-items", 'a', PANEL_CALLBACK_OPTION, N_("Show the 'Add New Items' dialog"), N_("PANEL-NUMBER") },
{ "save", 's', 0, G_OPTION_ARG_NONE, &opt_save, N_("Save the panel configuration"), NULL },
{ "add", '\0', 0, G_OPTION_ARG_STRING, &opt_add, N_("Add a new plugin to the panel"), N_("PLUGIN NAME") },
{ "add", '\0', 0, G_OPTION_ARG_STRING, &opt_add, N_("Add a new plugin to the panel"), N_("PLUGIN-NAME") },
{ "restart", 'r', 0, G_OPTION_ARG_NONE, &opt_restart, N_("Restart the running panel instance"), NULL },
{ "quit", 'q', 0, G_OPTION_ARG_NONE, &opt_quit, N_("Quit the running panel instance"), NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &opt_version, N_("Print version information and exit"), NULL },
{ "plugin-event", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_plugin_event, NULL, NULL },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_arguments, NULL, NULL },
{ NULL }
};
@ -192,7 +194,7 @@ main (gint argc, gchar **argv)
result = panel_dbus_client_save (&error);
goto dbus_return;
}
else if (opt_add)
else if (opt_add != NULL)
{
/* stop any running startup notification */
gdk_notify_startup_complete ();
@ -207,6 +209,12 @@ main (gint argc, gchar **argv)
result = panel_dbus_client_terminate (opt_restart, &error);
goto dbus_return;
}
else if (opt_plugin_event != NULL)
{
/* send the plugin event to the running instance */
result = panel_dbus_client_plugin_event (opt_plugin_event, &error);
goto dbus_return;
}
else if (panel_dbus_client_check_instance_running ())
{
/* quit without error if and instance is running */

105
panel/panel-dbus-client.c

@ -20,6 +20,10 @@
#include <config.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <dbus/dbus-glib.h>
#include <libxfce4util/libxfce4util.h>
#include <common/panel-private.h>
@ -34,6 +38,17 @@
enum
{
PLUGIN_NAME,
NAME,
TYPE,
VALUE,
N_TOKENS
};
static DBusGProxy *
panel_dbus_client_get_proxy (GError **error)
{
@ -175,6 +190,96 @@ panel_dbus_client_add_new_item (const gchar *plugin_name,
static GType
panel_dbus_client_gtype_from_string (const gchar *str)
{
if (strcmp (str, "bool") == 0)
return G_TYPE_BOOLEAN;
else if (strcmp (str, "double") == 0)
return G_TYPE_DOUBLE;
else if (strcmp (str, "int") == 0)
return G_TYPE_INT;
else if (strcmp (str, "string") == 0)
return G_TYPE_STRING;
else if (strcmp (str, "uint") == 0)
return G_TYPE_UINT;
else
return G_TYPE_NONE;
}
gboolean
panel_dbus_client_plugin_event (const gchar *plugin_event,
GError **error)
{
DBusGProxy *dbus_proxy;
gboolean result = FALSE;
gchar **tokens;
GType type;
GValue value = { 0, };
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
dbus_proxy = panel_dbus_client_get_proxy (error);
if (G_UNLIKELY (dbus_proxy == NULL))
return FALSE;
tokens = g_strsplit (plugin_event, ":", -1);
if (G_LIKELY (g_strv_length (tokens) == N_TOKENS
&& IS_STRING (tokens[VALUE])
&& IS_STRING (tokens[NAME])
&& *tokens[NAME] != SIGNAL_PREFIX))
{
type = panel_dbus_client_gtype_from_string (tokens[TYPE]);
if (G_LIKELY (type != G_TYPE_NONE))
{
g_value_init (&value, type);
if (type == G_TYPE_BOOLEAN)
g_value_set_boolean (&value, strcmp (tokens[VALUE], "true") == 0);
else if (type == G_TYPE_DOUBLE)
g_value_set_double (&value, g_ascii_strtod (tokens[VALUE], NULL));
else if (type == G_TYPE_INT)
g_value_set_int (&value, strtol (tokens[VALUE], NULL, 0));
else if (type == G_TYPE_STRING)
g_value_set_static_string (&value, tokens[VALUE]);
else if (type == G_TYPE_UINT)
g_value_set_uint (&value, strtol (tokens[VALUE], NULL, 0));
else
panel_assert_not_reached ();
result = _panel_dbus_client_plugin_event (dbus_proxy,
tokens[PLUGIN_NAME],
tokens[NAME],
&value,
error);
g_value_unset (&value);
}
else
{
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
_("Invalid hint type \"%s\". Valid types "
"are bool, double, int, string and uint."),
tokens[TYPE]);
}
}
else
{
g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
_("Invalid plugin event syntax specified. "
"Use PLUGIN-NAME:NAME:TYPE:VALUE."));
}
g_strfreev (tokens);
g_object_unref (G_OBJECT (dbus_proxy));
return result;
}
gboolean
panel_dbus_client_terminate (gboolean restart,
GError **error)

3
panel/panel-dbus-client.h

@ -36,6 +36,9 @@ gboolean panel_dbus_client_add_new_item (const gchar *plugin_nam
gchar **arguments,
GError **error);
gboolean panel_dbus_client_plugin_event (const gchar *plugin_event,
GError **error);
gboolean panel_dbus_client_terminate (gboolean restart,
GError **error);

16
panel/panel-dbus-service-infos.xml

@ -53,6 +53,22 @@
<arg name="plugin_name" direction="in" type="s" />
<arg name="arguments" direction="in" type="as" />
</method>
<!--
PluginEvent (plugin-name : STRING, name : STRING, value : VARIANT)
plugin-name : Name of the panel plugins to send this event to.
name : Event signal name.
value : GValue holding the event data.
Send a plugin to a group of plugins using the remote-event
XfcePanelPlugin signal.
-->
<method name="PluginEvent">
<arg name="plugin_name" direction="in" type="s" />
<arg name="name" direction="in" type="s" />
<arg name="value" direction="in" type="v" />
</method>
<!--
Terminate (restart : BOOL) : VOID

69
panel/panel-dbus-service.c

@ -42,22 +42,27 @@
static void panel_dbus_service_finalize (GObject *object);
static gboolean panel_dbus_service_display_preferences_dialog (PanelDBusService *service,
guint active,
GError **error);
static gboolean panel_dbus_service_display_items_dialog (PanelDBusService *service,
guint active,
GError **error);
static gboolean panel_dbus_service_save (PanelDBusService *service,
GError **error);
static gboolean panel_dbus_service_add_new_item (PanelDBusService *service,
static void panel_dbus_service_finalize (GObject *object);
static gboolean panel_dbus_service_display_preferences_dialog (PanelDBusService *service,
guint active,
GError **error);
static gboolean panel_dbus_service_display_items_dialog (PanelDBusService *service,
guint active,
GError **error);
static gboolean panel_dbus_service_save (PanelDBusService *service,
GError **error);
static gboolean panel_dbus_service_add_new_item (PanelDBusService *service,
const gchar *plugin_name,
gchar **arguments,
GError **error);
static gboolean panel_dbus_service_plugin_event (PanelDBusService *service,
const gchar *plugin_name,
gchar **arguments,
GError **error);
static gboolean panel_dbus_service_terminate (PanelDBusService *service,
gboolean restart,
const gchar *name,
const GValue *value,
GError **error);
static gboolean panel_dbus_service_terminate (PanelDBusService *service,
gboolean restart,
GError **error);
@ -242,6 +247,42 @@ panel_dbus_service_add_new_item (PanelDBusService *service,
static gboolean
panel_dbus_service_plugin_event (PanelDBusService *service,
const gchar *plugin_name,
const gchar *name,
const GValue *value,
GError **error)
{
GSList *plugins, *li;
PanelModuleFactory *factory;
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
panel_return_val_if_fail (plugin_name != NULL, FALSE);
panel_return_val_if_fail (name != NULL, FALSE);
panel_return_val_if_fail (G_IS_VALUE (value), FALSE);
factory = panel_module_factory_get ();
plugins = panel_module_factory_get_plugins (factory, plugin_name);
for (li = plugins; li != NULL; li = li->next)
{
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (li->data), FALSE);
if (xfce_panel_plugin_provider_remote_event (li->data, name, value))
break;
}
g_slist_free (plugins);
g_object_unref (G_OBJECT (factory));
return TRUE;
}
static gboolean
panel_dbus_service_terminate (PanelDBusService *service,
gboolean restart,

77
panel/panel-module-factory.c

@ -254,6 +254,22 @@ panel_module_factory_remove_plugin (gpointer user_data,
static gboolean
panel_module_factory_unique_id_exists (PanelModuleFactory *factory,
gint unique_id)
{
GSList *li;
for (li = factory->plugins; li != NULL; li = li->next)
if (xfce_panel_plugin_provider_get_unique_id (
XFCE_PANEL_PLUGIN_PROVIDER (li->data)) == unique_id)
return TRUE;
return FALSE;
}
PanelModuleFactory *
panel_module_factory_get (void)
{
@ -318,20 +334,6 @@ panel_module_factory_emit_unique_changed (PanelModule *module)
#if !GLIB_CHECK_VERSION (2,14,0)
static void
panel_module_factory_get_modules_foreach (gpointer key,
gpointer value,
gpointer user_data)
{
GList **keys = user_data;
*keys = g_list_prepend (*keys, key);
}
#endif
GList *
panel_module_factory_get_modules (PanelModuleFactory *factory)
{
@ -344,16 +346,7 @@ panel_module_factory_get_modules (PanelModuleFactory *factory)
g_hash_table_foreach_remove (factory->modules,
panel_module_factory_modules_cleanup, factory);
#if !GLIB_CHECK_VERSION (2,14,0)
GList *value = NULL;
g_hash_table_foreach (factory->modules,
panel_module_factory_get_modules_foreach, &value);
return value;
#else
return g_hash_table_get_values (factory->modules);
#endif
}
@ -370,22 +363,38 @@ panel_module_factory_has_module (PanelModuleFactory *factory,
GtkWidget *
panel_module_factory_get_plugin (PanelModuleFactory *factory,
gint unique_id)
GSList *
panel_module_factory_get_plugins (PanelModuleFactory *factory,
const gchar *plugin_name)
{
GSList *li;
GSList *li, *plugins = NULL;
gchar *unique_name;
panel_return_val_if_fail (PANEL_IS_MODULE_FACTORY (factory), NULL);
panel_return_val_if_fail (unique_id != -1, NULL);
panel_return_val_if_fail (plugin_name != NULL, NULL);
/* traverse the list to find the plugin with this unique id */
/* first assume a global plugin name is provided */
for (li = factory->plugins; li != NULL; li = li->next)
if (xfce_panel_plugin_provider_get_unique_id (
XFCE_PANEL_PLUGIN_PROVIDER (li->data)) == unique_id)
return GTK_WIDGET (li->data);
{
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (li->data), NULL);
if (strcmp (xfce_panel_plugin_provider_get_name (li->data), plugin_name) == 0)
plugins = g_slist_prepend (plugins, li->data);
}
/* try the unique plugin name (with id) if nothing is found */
for (li = factory->plugins; plugins == NULL && li != NULL; li = li->next)
{
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (li->data), NULL);
unique_name = g_strdup_printf ("%s-%d", xfce_panel_plugin_provider_get_name (li->data),
xfce_panel_plugin_provider_get_unique_id (li->data));
if (strcmp (unique_name, plugin_name) == 0)
plugins = g_slist_prepend (plugins, li->data);
g_free (unique_name);
}
return NULL;
return plugins;
}
@ -418,7 +427,7 @@ panel_module_factory_new_plugin (PanelModuleFactory *factory,
/* make sure this plugin has a unique id */
while (unique_id == -1
|| panel_module_factory_get_plugin (factory, unique_id) != NULL)
|| panel_module_factory_unique_id_exists (factory, unique_id))
unique_id = ++unique_id_counter;
/* set the return value with an always valid unique id */

4
panel/panel-module-factory.h

@ -53,8 +53,8 @@ GList *panel_module_factory_get_modules (PanelModuleFactory
gboolean panel_module_factory_has_module (PanelModuleFactory *factory,
const gchar *name);
GtkWidget *panel_module_factory_get_plugin (PanelModuleFactory *factory,
gint unique_id);
GSList *panel_module_factory_get_plugins (PanelModuleFactory *factory,
const gchar *plugin_name);
GtkWidget *panel_module_factory_new_plugin (PanelModuleFactory *factory,
const gchar *name,

22
panel/panel-plugin-external.c

@ -101,6 +101,9 @@ static void panel_plugin_external_show_configure (XfcePanelPlugin
static gboolean panel_plugin_external_get_show_about (XfcePanelPluginProvider *provider);
static void panel_plugin_external_show_about (XfcePanelPluginProvider *provider);
static void panel_plugin_external_remove (XfcePanelPluginProvider *provider);
static gboolean panel_plugin_external_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value);
static void panel_plugin_external_set_sensitive (PanelPluginExternal *external);
static void panel_plugin_external_child_watch (GPid pid,
gint status,
@ -279,6 +282,7 @@ panel_plugin_external_provider_init (XfcePanelPluginProviderIface *iface)
iface->get_show_about = panel_plugin_external_get_show_about;
iface->show_about = panel_plugin_external_show_about;
iface->remove = panel_plugin_external_remove;
iface->remote_event = panel_plugin_external_remote_event;
}
@ -901,6 +905,24 @@ panel_plugin_external_remove (XfcePanelPluginProvider *provider)
static gboolean
panel_plugin_external_remote_event (XfcePanelPluginProvider *provider,
const gchar *name,
const GValue *value)
{
panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), TRUE);
panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), TRUE);
/* TODO handle the return value */
panel_plugin_external_dbus_set (PANEL_PLUGIN_EXTERNAL (provider),
name, value);
return TRUE;
}
static void
panel_plugin_external_set_sensitive (PanelPluginExternal *external)
{

2
wrapper/main.c

@ -122,7 +122,7 @@ wrapper_gproxy_set (DBusGProxy *dbus_gproxy,
}
else
{
/* external event */
xfce_panel_plugin_provider_remote_event (provider, property, value);
}
}

Loading…
Cancel
Save