mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
application: Add dbus register/unregister hooks
When the application is using its D-Bus backend, it is useful to be able to export extra D-Bus objects at the right time, i.e. *before* the application tries to own the bus name. This is accomplished here by adding a hook in GApplicationClass for this; and a corresponding hook that will be called on unregistration to undo whatever the register hook did. Bug #675509.
This commit is contained in:
parent
f642209ef4
commit
4979c1d075
@ -159,6 +159,14 @@
|
||||
* </xi:include>
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* <example id="gapplication-example-dbushooks"><title>Using extra D-Bus hooks with a GApplication</title>
|
||||
* <programlisting>
|
||||
* <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-dbushooks.c">
|
||||
* <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
|
||||
* </xi:include>
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -190,6 +198,16 @@
|
||||
* g_application_run() if the use-count is non-zero. Since 2.32,
|
||||
* GApplication is iterating the main context directly and is not
|
||||
* using @run_mainloop anymore
|
||||
* @dbus_register: invoked locally during registration, if the application is
|
||||
* using its D-Bus backend. You can use this to export extra objects on the
|
||||
* bus, that need to exist before the application tries to own the bus name.
|
||||
* The function is passed the #GDBusConnection to to session bus, and the
|
||||
* object path that #GApplication will use to export is D-Bus API.
|
||||
* If this function returns %TRUE, registration will proceed; otherwise
|
||||
* registration will abort. Since: 2.34
|
||||
* @dbus_unregister: invoked locally during unregistration, if the application
|
||||
* is using its D-Bus backend. Use this to undo anything done by the
|
||||
* @dbus_register vfunc. Since: 2.34
|
||||
*
|
||||
* Virtual function table for #GApplication.
|
||||
*
|
||||
@ -506,6 +524,22 @@ g_application_real_add_platform_data (GApplication *application,
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_application_real_dbus_register (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_real_dbus_unregister (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path)
|
||||
{
|
||||
}
|
||||
|
||||
/* GObject implementation stuff {{{1 */
|
||||
static void
|
||||
g_application_set_property (GObject *object,
|
||||
@ -682,6 +716,8 @@ g_application_class_init (GApplicationClass *class)
|
||||
class->command_line = g_application_real_command_line;
|
||||
class->local_command_line = g_application_real_local_command_line;
|
||||
class->add_platform_data = g_application_real_add_platform_data;
|
||||
class->dbus_register = g_application_real_dbus_register;
|
||||
class->dbus_unregister = g_application_real_dbus_unregister;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_APPLICATION_ID,
|
||||
g_param_spec_string ("application-id",
|
||||
|
@ -90,8 +90,16 @@ struct _GApplicationClass
|
||||
void (* run_mainloop) (GApplication *application);
|
||||
void (* shutdown) (GApplication *application);
|
||||
|
||||
gboolean (* dbus_register) (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path,
|
||||
GError **error);
|
||||
void (* dbus_unregister) (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path);
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[11];
|
||||
gpointer padding[9];
|
||||
};
|
||||
|
||||
GType g_application_get_type (void) G_GNUC_CONST;
|
||||
|
@ -97,7 +97,7 @@ struct _GApplicationImpl
|
||||
|
||||
gboolean properties_live;
|
||||
gboolean primary;
|
||||
gpointer app;
|
||||
GApplication *app;
|
||||
};
|
||||
|
||||
|
||||
@ -228,6 +228,7 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
|
||||
const static GDBusInterfaceVTable vtable = {
|
||||
g_application_impl_method_call,
|
||||
};
|
||||
GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
|
||||
GVariant *reply;
|
||||
guint32 rval;
|
||||
|
||||
@ -271,6 +272,12 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
|
||||
if (impl->actions_id == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!app_class->dbus_register (impl->app,
|
||||
impl->session_bus,
|
||||
impl->object_path,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (impl->bus_name == NULL)
|
||||
{
|
||||
/* If this is a non-unique application then it is sufficient to
|
||||
@ -315,6 +322,12 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
|
||||
static void
|
||||
g_application_impl_stop_primary (GApplicationImpl *impl)
|
||||
{
|
||||
GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
|
||||
|
||||
app_class->dbus_unregister (impl->app,
|
||||
impl->session_bus,
|
||||
impl->object_path);
|
||||
|
||||
if (impl->object_id)
|
||||
{
|
||||
g_dbus_connection_unregister_object (impl->session_bus, impl->object_id);
|
||||
|
@ -120,6 +120,7 @@ SAMPLE_PROGS = \
|
||||
gapplication-example-cmdline2 \
|
||||
gapplication-example-cmdline3 \
|
||||
gapplication-example-actions \
|
||||
gapplication-example-dbushooks \
|
||||
gdbus-daemon \
|
||||
$(NULL)
|
||||
|
||||
@ -451,6 +452,9 @@ gapplication_example_cmdline3_LDADD = $(progs_ldadd)
|
||||
gapplication_example_actions_SOURCES = gapplication-example-actions.c
|
||||
gapplication_example_actions_LDADD = $(progs_ldadd)
|
||||
|
||||
gapplication_example_dbushooks_SOURCES = gapplication-example-dbushooks.c
|
||||
gapplication_example_dbushooks_LDADD = $(progs_ldadd)
|
||||
|
||||
gmenumodel_SOURCES = gmenumodel.c gdbus-sessionbus.h gdbus-sessionbus.c
|
||||
gmenumodel_LDADD = $(progs_ldadd)
|
||||
|
||||
|
99
gio/tests/gapplication-example-dbushooks.c
Normal file
99
gio/tests/gapplication-example-dbushooks.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include <gio/gio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
activate (GApplication *application)
|
||||
{
|
||||
g_print ("activated\n");
|
||||
|
||||
/* Note: when doing a longer-lasting action here that returns
|
||||
* to the mainloop, you should use g_application_hold() and
|
||||
* g_application_release() to keep the application alive until
|
||||
* the action is completed.
|
||||
*/
|
||||
}
|
||||
|
||||
typedef GApplication TestApplication;
|
||||
typedef GApplicationClass TestApplicationClass;
|
||||
|
||||
static GType test_application_get_type (void);
|
||||
G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION)
|
||||
|
||||
static gboolean
|
||||
test_application_dbus_register (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path,
|
||||
GError **error)
|
||||
{
|
||||
/* We must chain up to the parent class */
|
||||
if (!G_APPLICATION_CLASS (test_application_parent_class)->dbus_register (application,
|
||||
connection,
|
||||
object_path,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* Now we can do our own stuff here. For example, we could export some D-Bus objects */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_application_dbus_unregister (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const gchar *object_path)
|
||||
{
|
||||
/* Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register
|
||||
* hook above. Be sure to check that we actually did export them, since the hook
|
||||
* above might have returned early due to the parent class' hook returning FALSE!
|
||||
*/
|
||||
|
||||
/* Lastly, we must chain up to the parent class */
|
||||
G_APPLICATION_CLASS (test_application_parent_class)->dbus_unregister (application,
|
||||
connection,
|
||||
object_path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_application_init (TestApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
test_application_class_init (TestApplicationClass *class)
|
||||
{
|
||||
GApplicationClass *g_application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
g_application_class->dbus_register = test_application_dbus_register;
|
||||
g_application_class->dbus_unregister = test_application_dbus_unregister;
|
||||
}
|
||||
|
||||
static GApplication *
|
||||
test_application_new (const gchar *application_id,
|
||||
GApplicationFlags flags)
|
||||
{
|
||||
g_return_val_if_fail (g_application_id_is_valid (application_id), NULL);
|
||||
|
||||
g_type_init ();
|
||||
|
||||
return g_object_new (test_application_get_type (),
|
||||
"application-id", application_id,
|
||||
"flags", flags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GApplication *app;
|
||||
int status;
|
||||
|
||||
app = test_application_new ("org.gtk.TestApplication", 0);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
g_application_set_inactivity_timeout (app, 10000);
|
||||
|
||||
status = g_application_run (app, argc, argv);
|
||||
|
||||
g_object_unref (app);
|
||||
|
||||
return status;
|
||||
}
|
Loading…
Reference in New Issue
Block a user