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.
tags/xfce4-panel-4.10.0
Nick Schermer 11 years ago
parent
commit
f56f0609af
15 changed files with 330 additions and 55 deletions
  1. +1
    -0
      libxfce4panel/libxfce4panel-marshal.list
  2. +1
    -0
      libxfce4panel/libxfce4panel.symbols
  3. +12
    -0
      libxfce4panel/xfce-panel-plugin-provider.c
  4. +7
    -0
      libxfce4panel/xfce-panel-plugin-provider.h
  5. +47
    -0
      libxfce4panel/xfce-panel-plugin.c
  6. +3
    -0
      libxfce4panel/xfce-panel-plugin.h
  7. +12
    -4
      panel/main.c
  8. +105
    -0
      panel/panel-dbus-client.c
  9. +3
    -0
      panel/panel-dbus-client.h
  10. +16
    -0
      panel/panel-dbus-service-infos.xml
  11. +55
    -14
      panel/panel-dbus-service.c
  12. +43
    -34
      panel/panel-module-factory.c
  13. +2
    -2
      panel/panel-module-factory.h
  14. +22
    -0
      panel/panel-plugin-external.c
  15. +1
    -1
      wrapper/main.c

+ 1
- 0
libxfce4panel/libxfce4panel-marshal.list View File

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

+ 1
- 0
libxfce4panel/libxfce4panel.symbols View File

@@ -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
- 0
libxfce4panel/xfce-panel-plugin-provider.c View File

@@ -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
- 0
libxfce4panel/xfce-panel-plugin-provider.h View File

@@ -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
- 0
libxfce4panel/xfce-panel-plugin.c View File

@@ -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
- 0
libxfce4panel/xfce-panel-plugin.h View File

@@ -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);


+ 12
- 4
panel/main.c View File

@@ -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
- 0
panel/panel-dbus-client.c View File

@@ -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
- 0
panel/panel-dbus-client.h View File

@@ -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
- 0
panel/panel-dbus-service-infos.xml View File

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


+ 55
- 14
panel/panel-dbus-service.c View File

@@ -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,


+ 43
- 34
panel/panel-module-factory.c View File

@@ -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 */


+ 2
- 2
panel/panel-module-factory.h View File

@@ -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
- 0
panel/panel-plugin-external.c View File

@@ -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)
{


+ 1
- 1
wrapper/main.c View File

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