shell: Use GVariant to convey panel arguments instead of a string array
By using a GVariant of type "av" we can potentially pass more structured data to panels, which will become relevant with the ability to invoke them by GAction-based DBus-activation introduced in the following patch. https://bugzilla.gnome.org/show_bug.cgi?id=696054
This commit is contained in:
parent
397181e5d2
commit
9977bb200e
11 changed files with 127 additions and 60 deletions
|
@ -37,7 +37,7 @@ struct _CcKeyboardPanelPrivate
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ARGV
|
||||
PROP_PARAMETERS
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -81,13 +81,31 @@ cc_keyboard_panel_set_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ARGV: {
|
||||
gchar **args;
|
||||
case PROP_PARAMETERS: {
|
||||
GVariant *parameters, *v;
|
||||
const gchar *page, *section;
|
||||
|
||||
args = g_value_get_boxed (value);
|
||||
|
||||
if (args && args[0]) {
|
||||
cc_keyboard_panel_set_page (panel, args[0], args[1]);
|
||||
parameters = g_value_get_variant (value);
|
||||
if (!parameters)
|
||||
break;
|
||||
page = section = NULL;
|
||||
switch (g_variant_n_children (parameters))
|
||||
{
|
||||
case 2:
|
||||
g_variant_get_child (parameters, 1, "v", &v);
|
||||
section = g_variant_get_string (v, NULL);
|
||||
g_variant_unref (v);
|
||||
/* fall-through */
|
||||
case 1:
|
||||
g_variant_get_child (parameters, 0, "v", &v);
|
||||
page = g_variant_get_string (v, NULL);
|
||||
g_variant_unref (v);
|
||||
cc_keyboard_panel_set_page (panel, page, section);
|
||||
/* fall-through */
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unexpected parameters found, ignore request");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -164,7 +182,7 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
|
|||
object_class->dispose = cc_keyboard_panel_dispose;
|
||||
object_class->finalize = cc_keyboard_panel_finalize;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ARGV, "argv");
|
||||
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -102,7 +102,7 @@ enum {
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ARGV
|
||||
PROP_PARAMETERS
|
||||
};
|
||||
|
||||
static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
|
||||
|
@ -163,6 +163,23 @@ verify_argv (CcNetworkPanel *self,
|
|||
}
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
variant_av_to_string_array (GVariant *array)
|
||||
{
|
||||
GVariantIter iter;
|
||||
GVariant *v;
|
||||
GPtrArray *strv;
|
||||
gsize count;
|
||||
count = g_variant_iter_init (&iter, array);
|
||||
strv = g_ptr_array_sized_new (count + 1);
|
||||
while (g_variant_iter_next (&iter, "v", &v)) {
|
||||
g_ptr_array_add (strv, (gpointer *)g_variant_get_string (v, NULL));
|
||||
g_variant_unref (v);
|
||||
}
|
||||
g_ptr_array_add (strv, NULL); /* NULL-terminate the strv data array */
|
||||
return strv;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_network_panel_set_property (GObject *object,
|
||||
guint property_id,
|
||||
|
@ -173,14 +190,18 @@ cc_network_panel_set_property (GObject *object,
|
|||
CcNetworkPanelPrivate *priv = self->priv;
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_ARGV: {
|
||||
gchar **args;
|
||||
case PROP_PARAMETERS: {
|
||||
GVariant *parameters;
|
||||
|
||||
reset_command_line_args (self);
|
||||
|
||||
args = g_value_get_boxed (value);
|
||||
parameters = g_value_get_variant (value);
|
||||
if (parameters) {
|
||||
GPtrArray *array;
|
||||
const gchar **args;
|
||||
array = variant_av_to_string_array (parameters);
|
||||
args = array->pdata;
|
||||
|
||||
if (args) {
|
||||
g_debug ("Invoked with operation %s", args[0]);
|
||||
|
||||
if (args[0])
|
||||
|
@ -192,9 +213,10 @@ cc_network_panel_set_property (GObject *object,
|
|||
|
||||
if (verify_argv (self, (const char **) args) == FALSE) {
|
||||
reset_command_line_args (self);
|
||||
g_ptr_array_unref (array);
|
||||
return;
|
||||
}
|
||||
|
||||
g_ptr_array_unref (array);
|
||||
g_debug ("Calling handle_argv() after setting property");
|
||||
handle_argv (self);
|
||||
}
|
||||
|
@ -377,7 +399,7 @@ cc_network_panel_class_init (CcNetworkPanelClass *klass)
|
|||
object_class->finalize = cc_network_panel_finalize;
|
||||
object_class->constructed = cc_network_panel_constructed;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ARGV, "argv");
|
||||
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
||||
}
|
||||
|
||||
static NetObject *
|
||||
|
|
|
@ -91,7 +91,7 @@ CC_PANEL_REGISTER (CcGoaPanel, cc_goa_panel);
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ARGV
|
||||
PROP_PARAMETERS
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -102,14 +102,29 @@ cc_goa_panel_set_property (GObject *object,
|
|||
{
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ARGV:
|
||||
case PROP_PARAMETERS:
|
||||
{
|
||||
gchar **args;
|
||||
GVariant *parameters, *v;
|
||||
const gchar *first_arg = NULL;
|
||||
|
||||
args = g_value_get_boxed (value);
|
||||
parameters = g_value_get_variant (value);
|
||||
if (parameters == NULL)
|
||||
return;
|
||||
|
||||
if (g_variant_n_children (parameters) > 0)
|
||||
{
|
||||
g_variant_get_child (parameters, 0, "v", &v);
|
||||
if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
|
||||
first_arg = g_variant_get_string (v, NULL);
|
||||
else
|
||||
g_warning ("Wrong type for the second argument GVariant, expected 's' but got '%s'",
|
||||
(gchar *)g_variant_get_type (v));
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
if (first_arg != NULL)
|
||||
select_account_by_id (CC_GOA_PANEL (object), first_arg);
|
||||
|
||||
if (args != NULL && *args != '\0')
|
||||
select_account_by_id (CC_GOA_PANEL (object), args[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +295,7 @@ cc_goa_panel_class_init (CcGoaPanelClass *klass)
|
|||
object_class->set_property = cc_goa_panel_set_property;
|
||||
object_class->finalize = cc_goa_panel_finalize;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ARGV, "argv");
|
||||
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -38,7 +38,7 @@ CC_PANEL_REGISTER (CcSoundPanel, cc_sound_panel)
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ARGV
|
||||
PROP_PARAMETERS
|
||||
};
|
||||
|
||||
static void cc_sound_panel_finalize (GObject *object);
|
||||
|
@ -52,13 +52,15 @@ cc_sound_panel_set_property (GObject *object,
|
|||
CcSoundPanel *self = CC_SOUND_PANEL (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_ARGV: {
|
||||
gchar **args;
|
||||
case PROP_PARAMETERS: {
|
||||
GVariant *parameters;
|
||||
|
||||
args = g_value_get_boxed (value);
|
||||
|
||||
if (args && args[0]) {
|
||||
gvc_mixer_dialog_set_page (self->dialog, args[0]);
|
||||
parameters = g_value_get_variant (value);
|
||||
if (parameters && g_variant_n_children (parameters) > 0) {
|
||||
GVariant *v;
|
||||
g_variant_get_child (parameters, 0, "v", &v);
|
||||
gvc_mixer_dialog_set_page (self->dialog, g_variant_get_string (v, NULL));
|
||||
g_variant_unref (v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ cc_sound_panel_class_init (CcSoundPanelClass *klass)
|
|||
object_class->finalize = cc_sound_panel_finalize;
|
||||
object_class->set_property = cc_sound_panel_set_property;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ARGV, "argv");
|
||||
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -180,6 +180,9 @@ cc_application_command_line (GApplication *application,
|
|||
{
|
||||
const char *start_id;
|
||||
GError *err = NULL;
|
||||
GVariant *parameters;
|
||||
GVariantBuilder *builder;
|
||||
int i;
|
||||
|
||||
start_id = start_panels[0];
|
||||
|
||||
|
@ -188,7 +191,11 @@ cc_application_command_line (GApplication *application,
|
|||
else
|
||||
g_debug ("No extra argument");
|
||||
|
||||
if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->priv->window), start_id, (const gchar**)start_panels+1, &err))
|
||||
builder = g_variant_builder_new (G_VARIANT_TYPE ("av"));
|
||||
for (i = 1; start_panels[i] != NULL; i++)
|
||||
g_variant_builder_add (builder, "v", g_variant_new_string (start_panels[i]));
|
||||
parameters = g_variant_builder_end (builder);
|
||||
if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->priv->window), start_id, parameters, &err))
|
||||
{
|
||||
g_warning ("Could not load setting panel \"%s\": %s", start_id,
|
||||
(err) ? err->message : "Unknown error");
|
||||
|
|
|
@ -200,7 +200,7 @@ ensure_panel_types (void)
|
|||
CcPanel *
|
||||
cc_panel_loader_load_by_name (CcShell *shell,
|
||||
const char *name,
|
||||
const char **argv)
|
||||
GVariant *parameters)
|
||||
{
|
||||
GType (*get_type) (void);
|
||||
|
||||
|
@ -211,7 +211,7 @@ cc_panel_loader_load_by_name (CcShell *shell,
|
|||
|
||||
return g_object_new (get_type (),
|
||||
"shell", shell,
|
||||
"argv", argv,
|
||||
"parameters", parameters,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ void cc_panel_loader_fill_model (CcShellModel *model);
|
|||
GList *cc_panel_loader_get_panels (void);
|
||||
CcPanel *cc_panel_loader_load_by_name (CcShell *shell,
|
||||
const char *name,
|
||||
const char **argv);
|
||||
GVariant *parameters);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ enum
|
|||
{
|
||||
PROP_0,
|
||||
PROP_SHELL,
|
||||
PROP_ARGV
|
||||
PROP_PARAMETERS
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (CcPanel, cc_panel, GTK_TYPE_BIN)
|
||||
|
@ -80,11 +80,12 @@ cc_panel_set_property (GObject *object,
|
|||
panel->priv->shell = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_ARGV:
|
||||
case PROP_PARAMETERS:
|
||||
{
|
||||
gchar **argv = g_value_get_boxed (value);
|
||||
if (argv && argv[0])
|
||||
g_warning ("Ignoring additional argument %s", argv[0]);
|
||||
GVariant *parameters = g_value_get_variant (value);
|
||||
|
||||
if (parameters)
|
||||
g_warning ("Ignoring additional parameters");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -208,12 +209,13 @@ cc_panel_class_init (CcPanelClass *klass)
|
|||
| G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_property (object_class, PROP_SHELL, pspec);
|
||||
|
||||
pspec = g_param_spec_boxed ("argv",
|
||||
"Argument vector",
|
||||
"Additional arguments passed on the command line",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_ARGV, pspec);
|
||||
pspec = g_param_spec_variant ("parameters",
|
||||
"Structured parameters",
|
||||
"Additional parameters passed externally (ie. command line, dbus activation)",
|
||||
G_VARIANT_TYPE ("av"),
|
||||
NULL,
|
||||
G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_PARAMETERS, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -89,7 +89,8 @@ cc_shell_set_active_panel (CcShell *shell,
|
|||
/**
|
||||
* cc_shell_set_active_panel_from_id:
|
||||
* @shell: A #CcShell
|
||||
* @id: the ID of the panel to set as active
|
||||
* @id: The ID of the panel to set as active
|
||||
* @parameters: A #GVariant with additional parameters
|
||||
* @error: A #GError
|
||||
*
|
||||
* Find a panel corresponding to the specified id and set it as active.
|
||||
|
@ -99,7 +100,7 @@ cc_shell_set_active_panel (CcShell *shell,
|
|||
gboolean
|
||||
cc_shell_set_active_panel_from_id (CcShell *shell,
|
||||
const gchar *id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **error)
|
||||
{
|
||||
CcShellInterface *iface;
|
||||
|
@ -117,7 +118,7 @@ cc_shell_set_active_panel_from_id (CcShell *shell,
|
|||
}
|
||||
else
|
||||
{
|
||||
return iface->set_active_panel_from_id (shell, id, argv, error);
|
||||
return iface->set_active_panel_from_id (shell, id, parameters, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ struct _CcShellInterface
|
|||
/* methods */
|
||||
gboolean (*set_active_panel_from_id) (CcShell *shell,
|
||||
const gchar *id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **error);
|
||||
GtkWidget * (*get_toplevel) (CcShell *shell);
|
||||
void (*embed_widget_in_header) (CcShell *shell,
|
||||
|
@ -66,7 +66,7 @@ void cc_shell_set_active_panel (CcShell *shell,
|
|||
CcPanel *panel);
|
||||
gboolean cc_shell_set_active_panel_from_id (CcShell *shell,
|
||||
const gchar *id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **error);
|
||||
GtkWidget * cc_shell_get_toplevel (CcShell *shell);
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ enum
|
|||
|
||||
static gboolean cc_window_set_active_panel_from_id (CcShell *shell,
|
||||
const gchar *start_id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **err);
|
||||
|
||||
static const gchar *
|
||||
|
@ -136,7 +136,7 @@ get_icon_name_from_g_icon (GIcon *gicon)
|
|||
static gboolean
|
||||
activate_panel (CcWindow *self,
|
||||
const gchar *id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
const gchar *name,
|
||||
GIcon *gicon)
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ activate_panel (CcWindow *self,
|
|||
if (!id)
|
||||
return FALSE;
|
||||
|
||||
priv->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, argv));
|
||||
priv->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, parameters));
|
||||
cc_shell_set_active_panel (CC_SHELL (self), CC_PANEL (priv->current_panel));
|
||||
gtk_widget_show (priv->current_panel);
|
||||
|
||||
|
@ -933,7 +933,7 @@ _shell_embed_widget_in_header (CcShell *shell,
|
|||
static gboolean
|
||||
cc_window_set_active_panel_from_id (CcShell *shell,
|
||||
const gchar *start_id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **err)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
@ -943,10 +943,10 @@ cc_window_set_active_panel_from_id (CcShell *shell,
|
|||
CcWindowPrivate *priv = CC_WINDOW (shell)->priv;
|
||||
GtkWidget *old_panel;
|
||||
|
||||
/* When loading the same panel again, just set the argv */
|
||||
/* When loading the same panel again, just set its parameters */
|
||||
if (g_strcmp0 (priv->current_panel_id, start_id) == 0)
|
||||
{
|
||||
g_object_set (G_OBJECT (priv->current_panel), "argv", argv, NULL);
|
||||
g_object_set (G_OBJECT (priv->current_panel), "parameters", parameters, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -994,7 +994,7 @@ cc_window_set_active_panel_from_id (CcShell *shell,
|
|||
{
|
||||
g_warning ("Could not find settings panel \"%s\"", start_id);
|
||||
}
|
||||
else if (activate_panel (CC_WINDOW (shell), start_id, argv,
|
||||
else if (activate_panel (CC_WINDOW (shell), start_id, parameters,
|
||||
name, gicon) == FALSE)
|
||||
{
|
||||
/* Failed to activate the panel for some reason,
|
||||
|
@ -1020,11 +1020,11 @@ cc_window_set_active_panel_from_id (CcShell *shell,
|
|||
static gboolean
|
||||
_shell_set_active_panel_from_id (CcShell *shell,
|
||||
const gchar *start_id,
|
||||
const gchar **argv,
|
||||
GVariant *parameters,
|
||||
GError **err)
|
||||
{
|
||||
add_current_panel_to_history (shell, start_id);
|
||||
return cc_window_set_active_panel_from_id (shell, start_id, argv, err);
|
||||
return cc_window_set_active_panel_from_id (shell, start_id, parameters, err);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue