Commit eefd0899 authored by Allison Karlitskaya's avatar Allison Karlitskaya

introduce GRemoteActionGroup

This interfaceifies the extra functions that were on GDBusActionGroup
for dealing with platform data.

The two main benefits of doing this:

  - no longer have to do a silly song and dance in GApplication to avoid
    calling GDBusActionGroup API from non-dbus-aware code

  - the interface can be reused by the action group exporter to avoid
    ugly and unbindable hook callbacks

https://bugzilla.gnome.org/show_bug.cgi?id=665737
parent ee9f1044
......@@ -199,6 +199,7 @@
<xi:include href="xml/gsimpleactiongroup.xml"/>
<xi:include href="xml/gaction.xml"/>
<xi:include href="xml/gsimpleaction.xml"/>
<xi:include href="xml/gremoteactiongroup.xml"/>
<xi:include href="xml/gactiongroupexporter.xml"/>
<xi:include href="xml/gdbusactiongroup.xml"/>
<xi:include href="xml/gmenumodel.xml"/>
......
......@@ -2940,6 +2940,22 @@ G_DBUS_ACTION_GROUP_GET_CLASS
g_dbus_action_group_get_type
</SECTION>
<SECTION>
<FILE>gremoteactiongroup</FILE>
GRemoteActionGroup
GRemoteActionGroupInterface
<SUBSECTION>
g_remote_action_group_activate_action_full
g_remote_action_group_change_action_state_full
<SUBSECTION Standard>
G_TYPE_REMOTE_ACTION_GROUP
G_REMOTE_ACTION_GROUP
G_IS_REMOTE_ACTION_GROUP
G_REMOTE_ACTION_GROUP_GET_IFACE
</SECTION>
<SECTION>
<FILE>gaction</FILE>
<TITLE>GAction</TITLE>
......
......@@ -131,6 +131,7 @@ application_headers = \
gactiongroup.h \
gactionmap.h \
gsimpleactiongroup.h \
gremoteactiongroup.h \
gactiongroupexporter.h \
gdbusactiongroup.h \
gaction.h \
......@@ -152,6 +153,7 @@ application_sources = \
gactiongroup.c \
gactionmap.c \
gsimpleactiongroup.c \
gremoteactiongroup.c \
gactiongroupexporter.c \
gdbusactiongroup.c \
gaction.c \
......
......@@ -26,6 +26,7 @@
#include "gapplicationcommandline.h"
#include "gsimpleactiongroup.h"
#include "gremoteactiongroup.h"
#include "gapplicationimpl.h"
#include "gactiongroup.h"
#include "gactionmap.h"
......@@ -213,8 +214,8 @@ struct _GApplicationPrivate
guint did_startup : 1;
guint did_shutdown : 1;
GActionGroup *remote_actions;
GApplicationImpl *impl;
GRemoteActionGroup *remote_actions;
GApplicationImpl *impl;
};
enum
......@@ -1590,7 +1591,7 @@ g_application_list_actions (GActionGroup *action_group)
g_return_val_if_fail (application->priv->is_registered, NULL);
if (application->priv->remote_actions != NULL)
return g_action_group_list_actions (application->priv->remote_actions);
return g_action_group_list_actions (G_ACTION_GROUP (application->priv->remote_actions));
else if (application->priv->actions != NULL)
return g_action_group_list_actions (application->priv->actions);
......@@ -1614,7 +1615,7 @@ g_application_query_action (GActionGroup *group,
g_return_val_if_fail (application->priv->is_registered, FALSE);
if (application->priv->remote_actions != NULL)
return g_action_group_query_action (application->priv->remote_actions,
return g_action_group_query_action (G_ACTION_GROUP (application->priv->remote_actions),
action_name,
enabled,
parameter_type,
......@@ -1646,8 +1647,8 @@ g_application_change_action_state (GActionGroup *action_group,
g_return_if_fail (application->priv->is_registered);
if (application->priv->remote_actions)
g_application_impl_change_action_state (application->priv->impl, action_name, value,
get_platform_data (application));
g_remote_action_group_change_action_state_full (application->priv->remote_actions,
action_name, value, get_platform_data (application));
else
g_action_group_change_action_state (application->priv->actions, action_name, value);
......@@ -1664,9 +1665,9 @@ 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)
g_remote_action_group_activate_action_full (application->priv->remote_actions,
action_name, parameter, get_platform_data (application));
else
g_action_group_activate_action (application->priv->actions, action_name, parameter);
......
......@@ -23,6 +23,7 @@
#include "gactiongroup.h"
#include "gactiongroupexporter.h"
#include "gremoteactiongroup.h"
#include "gdbusactiongroup.h"
#include "gapplication.h"
#include "gfile.h"
......@@ -86,7 +87,6 @@ static GDBusInterfaceInfo *org_gtk_private_CommandLine;
struct _GApplicationImpl
{
GDBusConnection *session_bus;
GDBusActionGroup *remote_actions;
const gchar *bus_name;
gchar *object_path;
......@@ -474,12 +474,12 @@ g_application_impl_destroy (GApplicationImpl *impl)
}
GApplicationImpl *
g_application_impl_register (GApplication *application,
const gchar *appid,
GApplicationFlags flags,
GActionGroup **remote_actions,
GCancellable *cancellable,
GError **error)
g_application_impl_register (GApplication *application,
const gchar *appid,
GApplicationFlags flags,
GRemoteActionGroup **remote_actions,
GCancellable *cancellable,
GError **error)
{
GDBusActionGroup *actions;
GApplicationImpl *impl;
......@@ -543,8 +543,7 @@ g_application_impl_register (GApplication *application,
return NULL;
}
*remote_actions = G_ACTION_GROUP (actions);
impl->remote_actions = actions;
*remote_actions = G_REMOTE_ACTION_GROUP (actions);
return impl;
}
......@@ -593,24 +592,6 @@ g_application_impl_open (GApplicationImpl *impl,
NULL, 0, -1, NULL, NULL, NULL);
}
void
g_application_impl_activate_action (GApplicationImpl *impl,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data)
{
g_dbus_action_group_activate_action_full (impl->remote_actions, action_name, parameter, platform_data);
}
void
g_application_impl_change_action_state (GApplicationImpl *impl,
const gchar *action_name,
GVariant *value,
GVariant *platform_data)
{
g_dbus_action_group_change_action_state_full (impl->remote_actions, action_name, value, platform_data);
}
static void
g_application_impl_cmdline_method_call (GDBusConnection *connection,
const gchar *sender,
......
......@@ -18,7 +18,7 @@ G_GNUC_INTERNAL
GApplicationImpl * g_application_impl_register (GApplication *application,
const gchar *appid,
GApplicationFlags flags,
GActionGroup **remote_actions,
GRemoteActionGroup**remote_actions,
GCancellable *cancellable,
GError **error);
......@@ -33,18 +33,6 @@ void g_application_impl_open (GApplic
const gchar *hint,
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_change_action_state (GApplicationImpl *impl,
const gchar *action_name,
GVariant *value,
GVariant *platform_data);
G_GNUC_INTERNAL
int g_application_impl_command_line (GApplicationImpl *impl,
gchar **arguments,
......
......@@ -24,6 +24,7 @@
#include "gdbusactiongroup.h"
#include "gremoteactiongroup.h"
#include "gdbusconnection.h"
#include "gactiongroup.h"
......@@ -122,9 +123,11 @@ action_info_new_from_iter (GVariantIter *iter)
return info;
}
static void g_dbus_action_group_iface_init (GActionGroupInterface *);
static void g_dbus_action_group_remote_iface_init (GRemoteActionGroupInterface *iface);
static void g_dbus_action_group_iface_init (GActionGroupInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GDBusActionGroup, g_dbus_action_group, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_dbus_action_group_iface_init))
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_dbus_action_group_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_REMOTE_ACTION_GROUP, g_dbus_action_group_remote_iface_init))
static void
g_dbus_action_group_changed (GDBusConnection *connection,
......@@ -363,23 +366,53 @@ g_dbus_action_group_query_action (GActionGroup *g_group,
}
static void
g_dbus_action_group_change_state (GActionGroup *g_group,
g_dbus_action_group_activate_action_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data)
{
GDBusActionGroup *group = G_DBUS_ACTION_GROUP (remote);
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
if (parameter)
g_variant_builder_add (&builder, "v", parameter);
g_dbus_connection_call (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", "Activate",
g_variant_new ("(sav@a{sv})", action_name, &builder, platform_data),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}
static void
g_dbus_action_group_change_action_state_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *value,
GVariant *platform_data)
{
GDBusActionGroup *group = G_DBUS_ACTION_GROUP (remote);
g_dbus_connection_call (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", "SetState",
g_variant_new ("(sv@a{sv})", action_name, value, platform_data),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}
static void
g_dbus_action_group_change_state (GActionGroup *group,
const gchar *action_name,
GVariant *value)
{
GDBusActionGroup *group = G_DBUS_ACTION_GROUP (g_group);
g_dbus_action_group_change_action_state_full (group, action_name, value, g_variant_new ("a{sv}", NULL));
g_dbus_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (group),
action_name, value, g_variant_new ("a{sv}", NULL));
}
static void
g_dbus_action_group_activate (GActionGroup *g_group,
g_dbus_action_group_activate (GActionGroup *group,
const gchar *action_name,
GVariant *parameter)
{
GDBusActionGroup *group = G_DBUS_ACTION_GROUP (g_group);
g_dbus_action_group_activate_action_full (group, action_name, parameter, g_variant_new ("a{sv}", NULL));
g_dbus_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (group),
action_name, parameter, g_variant_new ("a{sv}", NULL));
}
static void
......@@ -414,6 +447,13 @@ g_dbus_action_group_class_init (GDBusActionGroupClass *class)
object_class->finalize = g_dbus_action_group_finalize;
}
static void
g_dbus_action_group_remote_iface_init (GRemoteActionGroupInterface *iface)
{
iface->activate_action_full = g_dbus_action_group_activate_action_full;
iface->change_action_state_full = g_dbus_action_group_change_action_state_full;
}
static void
g_dbus_action_group_iface_init (GActionGroupInterface *iface)
{
......@@ -496,81 +536,3 @@ g_dbus_action_group_sync (GDBusActionGroup *group,
return reply != NULL;
}
/**
* g_dbus_action_group_activate_action_full:
* @action_group: a #GDBusActionGroup
* @action_name: the name of the action to activate
* @parameter: (allow none): the optional parameter to the activation
* @platform_data: the platform data to send
*
* Activates the remote action.
*
* This is the same as g_action_group_activate_action() except that it
* allows for provision of "platform data" to be sent along with the
* activation request. This typically contains details such as the user
* interaction timestamp or startup notification information.
*
* @platform_data must be non-%NULL and must have the type
* %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed.
*
* Since: 2.32
**/
void
g_dbus_action_group_activate_action_full (GDBusActionGroup *action_group,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data)
{
GVariantBuilder builder;
g_return_if_fail (G_IS_DBUS_ACTION_GROUP (action_group));
g_return_if_fail (action_name != NULL);
g_return_if_fail (platform_data != NULL);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
if (parameter)
g_variant_builder_add (&builder, "v", parameter);
g_dbus_connection_call (action_group->connection, action_group->bus_name, action_group->object_path,
"org.gtk.Actions", "Activate",
g_variant_new ("(sav@a{sv})", action_name, &builder, platform_data),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}
/**
* g_dbus_action_group_activate_action_full:
* @action_group: a #GDBusActionGroup
* @action_name: the name of the action to change the state of
* @value: the new requested value for the state
* @platform_data: the platform data to send
*
* Changes the state of a remote action.
*
* This is the same as g_action_group_change_action_state() except that
* it allows for provision of "platform data" to be sent along with the
* state change request. This typically contains details such as the
* user interaction timestamp or startup notification information.
*
* @platform_data must be non-%NULL and must have the type
* %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed.
*
* Since: 2.32
**/
void
g_dbus_action_group_change_action_state_full (GDBusActionGroup *action_group,
const gchar *action_name,
GVariant *value,
GVariant *platform_data)
{
g_return_if_fail (G_IS_DBUS_ACTION_GROUP (action_group));
g_return_if_fail (action_name != NULL);
g_return_if_fail (value != NULL);
g_return_if_fail (platform_data != NULL);
g_dbus_connection_call (action_group->connection, action_group->bus_name, action_group->object_path,
"org.gtk.Actions", "SetState",
g_variant_new ("(sv@a{sv})", action_name, value, platform_data),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}
......@@ -49,15 +49,6 @@ GDBusActionGroup * g_dbus_action_group_get (GDBusConn
const gchar *bus_name,
const gchar *object_path);
void g_dbus_action_group_activate_action_full (GDBusActionGroup *action_group,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data);
void g_dbus_action_group_change_action_state_full (GDBusActionGroup *action_group,
const gchar *action_name,
GVariant *value,
GVariant *platform_data);
G_END_DECLS
#endif /* __G_DBUS_ACTION_GROUP_H__ */
......@@ -147,6 +147,7 @@
#include <gio/gdbusobjectmanagerclient.h>
#include <gio/gdbusobjectmanagerserver.h>
#include <gio/gdbusactiongroup.h>
#include <gio/gremoteactiongroup.h>
#include <gio/gmenumodel.h>
#include <gio/gmenu.h>
#include <gio/gmenuexporter.h>
......
......@@ -1443,8 +1443,9 @@ g_simple_action_set_enabled
g_simple_action_set_state
g_dbus_action_group_get_type
g_dbus_action_group_get
g_dbus_action_group_activate_action_full
g_dbus_action_group_change_action_state_full
g_remote_action_group_get_type
g_remote_action_group_activate_action_full
g_remote_action_group_change_action_state_full
g_dbus_menu_model_get_type
g_dbus_menu_model_get
g_dbus_connection_export_action_group
......
......@@ -48,6 +48,7 @@ typedef struct _GZlibCompressor GZlibCompressor;
typedef struct _GZlibDecompressor GZlibDecompressor;
typedef struct _GSimpleActionGroup GSimpleActionGroup;
typedef struct _GRemoteActionGroup GRemoteActionGroup;
typedef struct _GDBusActionGroup GDBusActionGroup;
typedef struct _GActionMap GActionMap;
typedef struct _GActionGroup GActionGroup;
......
/*
* Copyright © 2010 Codethink Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gsimpleaction.h"
#include "gactiongroup.h"
#include "gactionmap.h"
#include "gaction.h"
/**
* SECTION:gremoteactiongroup
* @title: GRemoteActionGroup
* @short_description: a #GActionGroup that interacts with other processes
*
* The GRemoteActionGroup interface is implemented by #GActionGroup
* instances that either transmit action invocations to other processes
* or receive action invocations in the local process from other
* processes.
*
* The interface has <literal>_full</literal> variants of the two
* methods on #GActionGroup used to activate actions:
* g_action_group_activate_action() and
* g_action_group_change_action_state(). These variants allow a
* "platform data" #GVariant to be specified: a dictionary providing
* context for the action invocation (for example: timestamps, startup
* notification IDs, etc).
*
* #GDBusActionGroup implements #GRemoteActionGroup. This provides a
* mechanism to send platform data for action invocations over D-Bus.
*
* Additionally, g_dbus_connection_export_action_group() will check if
* the exported #GActionGroup implements #GRemoteActionGroup and use the
* <literal>_full</literal> variants of the calls if available. This
* provides a mechanism by which to receive platform data for action
* invocations that arrive by way of D-Bus.
*
* Since: 2.32
**/
/**
* GRemoteActionGroupInterface:
* @activate_action_full: the virtual function pointer for g_remote_action_group_activate_action_full()
* @change_action_state_full: the virtual function pointer for g_remote_action_group_change_action_state_full()
*
* The virtual function table for #GRemoteActionGroup.
*
* Since: 2.32
**/
#include "config.h"
#include "gremoteactiongroup.h"
G_DEFINE_INTERFACE (GRemoteActionGroup, g_remote_action_group, G_TYPE_ACTION_GROUP)
static void
g_remote_action_group_default_init (GRemoteActionGroupInterface *iface)
{
}
/**
* g_remote_action_group_activate_action_full:
* @action_group: a #GDBusActionGroup
* @action_name: the name of the action to activate
* @parameter: (allow none): the optional parameter to the activation
* @platform_data: the platform data to send
*
* Activates the remote action.
*
* This is the same as g_action_group_activate_action() except that it
* allows for provision of "platform data" to be sent along with the
* activation request. This typically contains details such as the user
* interaction timestamp or startup notification information.
*
* @platform_data must be non-%NULL and must have the type
* %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed.
*
* Since: 2.32
**/
void
g_remote_action_group_activate_action_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data)
{
G_REMOTE_ACTION_GROUP_GET_IFACE (remote)
->activate_action_full (remote, action_name, parameter, platform_data);
}
/**
* g_remote_action_group_activate_action_full:
* @remote: a #GRemoteActionGroup
* @action_name: the name of the action to change the state of
* @value: the new requested value for the state
* @platform_data: the platform data to send
*
* Changes the state of a remote action.
*
* This is the same as g_action_group_change_action_state() except that
* it allows for provision of "platform data" to be sent along with the
* state change request. This typically contains details such as the
* user interaction timestamp or startup notification information.
*
* @platform_data must be non-%NULL and must have the type
* %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed.
*
* Since: 2.32
**/
void
g_remote_action_group_change_action_state_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *value,
GVariant *platform_data)
{
G_REMOTE_ACTION_GROUP_GET_IFACE (remote)
->change_action_state_full (remote, action_name, value, platform_data);
}
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
#error "Only <gio/gio.h> can be included directly."
#endif
#ifndef __G_REMOTE_ACTION_GROUP_H__
#define __G_REMOTE_ACTION_GROUP_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_REMOTE_ACTION_GROUP (g_remote_action_group_get_type ())
#define G_REMOTE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_REMOTE_ACTION_GROUP, GRemoteActionGroup))
#define G_IS_REMOTE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_REMOTE_ACTION_GROUP))
#define G_REMOTE_ACTION_GROUP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
G_TYPE_REMOTE_ACTION_GROUP, \
GRemoteActionGroupInterface))
typedef struct _GRemoteActionGroupInterface GRemoteActionGroupInterface;
struct _GRemoteActionGroupInterface
{
GTypeInterface g_iface;
void (* activate_action_full) (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data);
void (* change_action_state_full) (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *value,
GVariant *platform_data);
};
GType g_remote_action_group_get_type (void) G_GNUC_CONST;
void g_remote_action_group_activate_action_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *parameter,
GVariant *platform_data);
void g_remote_action_group_change_action_state_full (GRemoteActionGroup *remote,
const gchar *action_name,
GVariant *value,
GVariant *platform_data);
G_END_DECLS
#endif /* __G_REMOTE_ACTION_GROUP_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment