mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 04:36:17 +01:00
GApplication: use GDBusActionGroup
instead of the internal version of the same
This commit is contained in:
parent
c249e10d11
commit
df4cd241e5
@ -159,7 +159,7 @@ struct _GApplicationPrivate
|
||||
guint did_startup : 1;
|
||||
guint did_shutdown : 1;
|
||||
|
||||
GHashTable *remote_actions; /* string -> RemoteActionInfo */
|
||||
GActionGroup *remote_actions;
|
||||
GApplicationImpl *impl;
|
||||
};
|
||||
|
||||
@ -1361,23 +1361,7 @@ g_application_list_actions (GActionGroup *action_group)
|
||||
g_return_val_if_fail (application->priv->is_registered, NULL);
|
||||
|
||||
if (application->priv->remote_actions != NULL)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gint n, i = 0;
|
||||
gchar **keys;
|
||||
gpointer key;
|
||||
|
||||
n = g_hash_table_size (application->priv->remote_actions);
|
||||
keys = g_new (gchar *, n + 1);
|
||||
|
||||
g_hash_table_iter_init (&iter, application->priv->remote_actions);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
keys[i++] = g_strdup (key);
|
||||
g_assert_cmpint (i, ==, n);
|
||||
keys[n] = NULL;
|
||||
|
||||
return keys;
|
||||
}
|
||||
return g_action_group_list_actions (application->priv->remote_actions);
|
||||
|
||||
else if (application->priv->actions != NULL)
|
||||
return g_action_group_list_actions (application->priv->actions);
|
||||
@ -1398,35 +1382,18 @@ g_application_query_action (GActionGroup *group,
|
||||
{
|
||||
GApplication *application = G_APPLICATION (group);
|
||||
|
||||
g_return_val_if_fail (application->priv->is_registered, FALSE);
|
||||
|
||||
if (application->priv->remote_actions != NULL)
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
return g_action_group_query_action (application->priv->remote_actions,
|
||||
action_name,
|
||||
enabled,
|
||||
parameter_type,
|
||||
state_type,
|
||||
state_hint,
|
||||
state);
|
||||
|
||||
info = g_hash_table_lookup (application->priv->remote_actions,
|
||||
action_name);
|
||||
|
||||
if (info == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (enabled)
|
||||
*enabled = info->enabled;
|
||||
|
||||
if (parameter_type)
|
||||
*parameter_type = info->parameter_type;
|
||||
|
||||
if (state_type)
|
||||
*state_type = info->state ? g_variant_get_type (info->state) : NULL;
|
||||
|
||||
if (state_hint)
|
||||
*state_hint = NULL;
|
||||
|
||||
if (state)
|
||||
*state = info->state ? g_variant_ref (info->state) : NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (application->priv->actions != NULL)
|
||||
{
|
||||
if (application->priv->actions != NULL)
|
||||
return g_action_group_query_action (application->priv->actions,
|
||||
action_name,
|
||||
enabled,
|
||||
@ -1434,7 +1401,6 @@ g_application_query_action (GActionGroup *group,
|
||||
state_type,
|
||||
state_hint,
|
||||
state);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -1450,10 +1416,8 @@ g_application_change_action_state (GActionGroup *action_group,
|
||||
application->priv->actions != NULL);
|
||||
g_return_if_fail (application->priv->is_registered);
|
||||
|
||||
if (application->priv->is_remote)
|
||||
g_application_impl_change_action_state (application->priv->impl,
|
||||
action_name, value,
|
||||
get_platform_data (application));
|
||||
if (application->priv->remote_actions)
|
||||
return g_action_group_change_action_state (application->priv->remote_actions, action_name, value);
|
||||
|
||||
else
|
||||
g_action_group_change_action_state (application->priv->actions,
|
||||
@ -1471,10 +1435,8 @@ g_application_activate_action (GActionGroup *action_group,
|
||||
application->priv->actions != NULL);
|
||||
g_return_if_fail (application->priv->is_registered);
|
||||
|
||||
if (application->priv->is_remote)
|
||||
g_application_impl_activate_action (application->priv->impl,
|
||||
action_name, parameter,
|
||||
get_platform_data (application));
|
||||
if (application->priv->remote_actions)
|
||||
return g_action_group_change_action_state (application->priv->remote_actions, action_name, parameter);
|
||||
|
||||
else
|
||||
g_action_group_activate_action (application->priv->actions,
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "gactiongroup.h"
|
||||
#include "gactiongroupexporter.h"
|
||||
#include "gdbusactiongroup.h"
|
||||
#include "gapplication.h"
|
||||
#include "gfile.h"
|
||||
#include "gdbusconnection.h"
|
||||
@ -118,9 +119,6 @@ struct _GApplicationImpl
|
||||
guint object_id;
|
||||
gboolean actions_exported;
|
||||
gpointer app;
|
||||
|
||||
GHashTable *actions;
|
||||
guint signal_id;
|
||||
};
|
||||
|
||||
|
||||
@ -264,165 +262,18 @@ g_application_impl_destroy (GApplicationImpl *impl)
|
||||
g_slice_free (GApplicationImpl, impl);
|
||||
}
|
||||
|
||||
static void
|
||||
remote_action_info_free (gpointer user_data)
|
||||
{
|
||||
RemoteActionInfo *info = user_data;
|
||||
|
||||
g_free (info->name);
|
||||
|
||||
if (info->state)
|
||||
g_variant_unref (info->state);
|
||||
|
||||
if (info->parameter_type)
|
||||
g_variant_type_free (info->parameter_type);
|
||||
|
||||
g_slice_free (RemoteActionInfo, info);
|
||||
}
|
||||
|
||||
static RemoteActionInfo *
|
||||
remote_action_info_new_from_iter (GVariantIter *iter)
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
const gchar *param_str;
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
gchar *name;
|
||||
|
||||
if (!g_variant_iter_next (iter, "{&s(bg@av)}", &name,
|
||||
&enabled, ¶m_str, &state))
|
||||
return NULL;
|
||||
|
||||
info = g_slice_new (RemoteActionInfo);
|
||||
info->name = name;
|
||||
info->enabled = enabled;
|
||||
|
||||
if (g_variant_n_children (state))
|
||||
g_variant_get_child (state, 0, "v", &info->state);
|
||||
else
|
||||
info->state = NULL;
|
||||
g_variant_unref (state);
|
||||
|
||||
if (param_str[0])
|
||||
info->parameter_type = g_variant_type_copy ((GVariantType *) param_str);
|
||||
else
|
||||
info->parameter_type = NULL;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_impl_action_signal (GDBusConnection *connection,
|
||||
const gchar *sender_name,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
GApplicationImpl *impl = user_data;
|
||||
GActionGroup *action_group;
|
||||
|
||||
action_group = G_ACTION_GROUP (impl->app);
|
||||
|
||||
if (g_str_equal (signal_name, "Changed") &&
|
||||
g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(asa{sb}a{sv}a{s(bgav)})")))
|
||||
{
|
||||
/* Removes */
|
||||
{
|
||||
GVariantIter *iter;
|
||||
const gchar *name;
|
||||
|
||||
g_variant_get_child (parameters, 0, "as", &iter);
|
||||
while (g_variant_iter_next (iter, "&s", &name))
|
||||
{
|
||||
if (g_hash_table_lookup (impl->actions, name))
|
||||
{
|
||||
g_hash_table_remove (impl->actions, name);
|
||||
g_action_group_action_removed (action_group, name);
|
||||
}
|
||||
}
|
||||
g_variant_iter_free (iter);
|
||||
}
|
||||
|
||||
/* Enable changes */
|
||||
{
|
||||
GVariantIter *iter;
|
||||
const gchar *name;
|
||||
gboolean enabled;
|
||||
|
||||
g_variant_get_child (parameters, 1, "a{sb}", &iter);
|
||||
while (g_variant_iter_next (iter, "{&sb}", &name, &enabled))
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
|
||||
info = g_hash_table_lookup (impl->actions, name);
|
||||
|
||||
if (info && info->enabled != enabled)
|
||||
{
|
||||
info->enabled = enabled;
|
||||
g_action_group_action_enabled_changed (action_group,
|
||||
name, enabled);
|
||||
}
|
||||
}
|
||||
g_variant_iter_free (iter);
|
||||
}
|
||||
|
||||
/* State changes */
|
||||
{
|
||||
GVariantIter *iter;
|
||||
const gchar *name;
|
||||
GVariant *state;
|
||||
|
||||
g_variant_get_child (parameters, 2, "a{sv}", &iter);
|
||||
while (g_variant_iter_next (iter, "{&sv}", &name, &state))
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
|
||||
info = g_hash_table_lookup (impl->actions, name);
|
||||
|
||||
if (info && info->state && !g_variant_equal (state, info->state) &&
|
||||
g_variant_is_of_type (state, g_variant_get_type (info->state)))
|
||||
{
|
||||
g_variant_unref (info->state);
|
||||
info->state = g_variant_ref (state);
|
||||
|
||||
g_action_group_action_state_changed (action_group, name, state);
|
||||
}
|
||||
|
||||
g_variant_unref (state);
|
||||
}
|
||||
g_variant_iter_free (iter);
|
||||
}
|
||||
|
||||
/* Additions */
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
GVariantIter *iter;
|
||||
|
||||
g_variant_get_child (parameters, 3, "a{s(bgav)}", &iter);
|
||||
while ((info = remote_action_info_new_from_iter (iter)))
|
||||
{
|
||||
if (!g_hash_table_lookup (impl->actions, info->name))
|
||||
g_hash_table_replace (impl->actions, info->name, info);
|
||||
else
|
||||
remote_action_info_free (info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GApplicationImpl *
|
||||
g_application_impl_register (GApplication *application,
|
||||
const gchar *appid,
|
||||
GApplicationFlags flags,
|
||||
GHashTable **remote_actions,
|
||||
GActionGroup **remote_actions,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
const static GDBusInterfaceVTable vtable = {
|
||||
g_application_impl_method_call
|
||||
};
|
||||
GDBusActionGroup *actions;
|
||||
GApplicationImpl *impl;
|
||||
GVariant *reply;
|
||||
guint32 rval;
|
||||
@ -558,22 +409,10 @@ g_application_impl_register (GApplication *application,
|
||||
* This also serves as a mechanism to ensure that the primary exists
|
||||
* (ie: DBus service files installed correctly, etc).
|
||||
*/
|
||||
impl->signal_id =
|
||||
g_dbus_connection_signal_subscribe (impl->session_bus, impl->bus_name,
|
||||
"org.gtk.Actions", NULL,
|
||||
impl->object_path, NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
g_application_impl_action_signal,
|
||||
impl, NULL);
|
||||
actions = g_dbus_action_group_new_sync (impl->session_bus, impl->bus_name, impl->object_path,
|
||||
G_DBUS_ACTION_GROUP_FLAGS_NONE, NULL, error);
|
||||
|
||||
reply = g_dbus_connection_call_sync (impl->session_bus, impl->bus_name,
|
||||
impl->object_path, "org.gtk.Actions",
|
||||
"DescribeAll", NULL,
|
||||
G_VARIANT_TYPE ("(a{s(bgav)})"),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
cancellable, error);
|
||||
|
||||
if (reply == NULL)
|
||||
if (actions == NULL)
|
||||
{
|
||||
/* The primary appears not to exist. Fail the registration. */
|
||||
g_object_unref (impl->session_bus);
|
||||
@ -585,24 +424,7 @@ g_application_impl_register (GApplication *application,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create and populate the hashtable */
|
||||
{
|
||||
RemoteActionInfo *info;
|
||||
GVariant *descriptions;
|
||||
GVariantIter iter;
|
||||
|
||||
impl->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, remote_action_info_free);
|
||||
descriptions = g_variant_get_child_value (reply, 0);
|
||||
g_variant_iter_init (&iter, descriptions);
|
||||
|
||||
while ((info = remote_action_info_new_from_iter (&iter)))
|
||||
g_hash_table_replace (impl->actions, info->name, info);
|
||||
|
||||
g_variant_unref (descriptions);
|
||||
|
||||
*remote_actions = impl->actions;
|
||||
}
|
||||
*remote_actions = G_ACTION_GROUP (actions);
|
||||
|
||||
return impl;
|
||||
}
|
||||
@ -753,46 +575,6 @@ g_application_impl_command_line (GApplicationImpl *impl,
|
||||
return data.status;
|
||||
}
|
||||
|
||||
void
|
||||
g_application_impl_change_action_state (GApplicationImpl *impl,
|
||||
const gchar *action_name,
|
||||
GVariant *value,
|
||||
GVariant *platform_data)
|
||||
{
|
||||
g_dbus_connection_call (impl->session_bus,
|
||||
impl->bus_name,
|
||||
impl->object_path,
|
||||
"org.gtk.Actions",
|
||||
"SetState",
|
||||
g_variant_new ("(sv@a{sv})", action_name,
|
||||
value, platform_data),
|
||||
NULL, 0, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
g_application_impl_activate_action (GApplicationImpl *impl,
|
||||
const gchar *action_name,
|
||||
GVariant *parameter,
|
||||
GVariant *platform_data)
|
||||
{
|
||||
GVariant *param;
|
||||
|
||||
if (parameter)
|
||||
parameter = g_variant_new_variant (parameter);
|
||||
|
||||
param = g_variant_new_array (G_VARIANT_TYPE_VARIANT,
|
||||
¶meter, parameter != NULL);
|
||||
|
||||
g_dbus_connection_call (impl->session_bus,
|
||||
impl->bus_name,
|
||||
impl->object_path,
|
||||
"org.gtk.Actions",
|
||||
"Activate",
|
||||
g_variant_new ("(s@av@a{sv})", action_name,
|
||||
param, platform_data),
|
||||
NULL, 0, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
g_application_impl_flush (GApplicationImpl *impl)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ G_GNUC_INTERNAL
|
||||
GApplicationImpl * g_application_impl_register (GApplication *application,
|
||||
const gchar *appid,
|
||||
GApplicationFlags flags,
|
||||
GHashTable **remote_actions,
|
||||
GActionGroup **remote_actions,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
@ -38,17 +38,5 @@ int g_application_impl_command_line (GApplic
|
||||
gchar **arguments,
|
||||
GVariant *platform_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void g_application_impl_change_action_state (GApplicationImpl *impl,
|
||||
const gchar *action_name,
|
||||
GVariant *value,
|
||||
GVariant *platform_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void g_application_impl_activate_action (GApplicationImpl *impl,
|
||||
const gchar *action_name,
|
||||
GVariant *parameter,
|
||||
GVariant *platform_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void g_application_impl_flush (GApplicationImpl *impl);
|
||||
|
Loading…
Reference in New Issue
Block a user