MetaIdleMonitor: add a DBus interface for the idle monitor
To allow other clients (gnome-session, gnome-settings-daemon) to monitor user activity, introduce a DBus interface for the idle monitor inside mutter. https://bugzilla.gnome.org/show_bug.cgi?id=706005
This commit is contained in:
parent
c63e5f755f
commit
387b53977d
@ -30,8 +30,9 @@ INCLUDES= \
|
|||||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
|
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
|
||||||
|
|
||||||
mutter_built_sources = \
|
mutter_built_sources = \
|
||||||
|
$(dbus_idle_built_sources) \
|
||||||
$(dbus_xrandr_built_sources) \
|
$(dbus_xrandr_built_sources) \
|
||||||
mutter-enum-types.h \
|
mutter-enum-types.h \
|
||||||
mutter-enum-types.c
|
mutter-enum-types.c
|
||||||
|
|
||||||
libmutter_la_SOURCES = \
|
libmutter_la_SOURCES = \
|
||||||
@ -342,8 +343,18 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
|
|||||||
dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h
|
dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h
|
||||||
|
|
||||||
$(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
|
$(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
|
||||||
$(AM_V_GEN)gdbus-codegen \
|
$(AM_V_GEN)gdbus-codegen \
|
||||||
--interface-prefix org.gnome.Mutter \
|
--interface-prefix org.gnome.Mutter \
|
||||||
--c-namespace MetaDBus \
|
--c-namespace MetaDBus \
|
||||||
--generate-c-code meta-dbus-xrandr \
|
--generate-c-code meta-dbus-xrandr \
|
||||||
$(srcdir)/xrandr.xml
|
$(srcdir)/xrandr.xml
|
||||||
|
|
||||||
|
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||||
|
|
||||||
|
$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
|
||||||
|
$(AM_V_GEN)gdbus-codegen \
|
||||||
|
--interface-prefix org.gnome.Mutter \
|
||||||
|
--c-namespace MetaDBus \
|
||||||
|
--generate-c-code meta-dbus-idle-monitor \
|
||||||
|
--c-generate-object-manager \
|
||||||
|
idle-monitor.xml
|
||||||
|
@ -975,8 +975,10 @@ meta_display_open (void)
|
|||||||
|
|
||||||
meta_error_trap_pop (the_display);
|
meta_error_trap_pop (the_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_display_ungrab (the_display);
|
meta_idle_monitor_init_dbus ();
|
||||||
|
|
||||||
|
meta_display_ungrab (the_display);
|
||||||
|
|
||||||
/* Done opening new display */
|
/* Done opening new display */
|
||||||
the_display->display_opening = FALSE;
|
the_display->display_opening = FALSE;
|
||||||
@ -2265,8 +2267,8 @@ event_callback (XEvent *event,
|
|||||||
meta_window_update_sync_request_counter (alarm_window, new_counter_value);
|
meta_window_update_sync_request_counter (alarm_window, new_counter_value);
|
||||||
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
meta_idle_monitor_handle_xevent_all (event);
|
meta_idle_monitor_handle_xevent_all (event);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
|
||||||
|
@ -27,3 +27,4 @@
|
|||||||
void meta_idle_monitor_handle_xevent_all (XEvent *xevent);
|
void meta_idle_monitor_handle_xevent_all (XEvent *xevent);
|
||||||
|
|
||||||
|
|
||||||
|
void meta_idle_monitor_init_dbus (void);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <meta/meta-idle-monitor.h>
|
#include <meta/meta-idle-monitor.h>
|
||||||
#include "display-private.h"
|
#include "display-private.h"
|
||||||
#include "meta-idle-monitor-private.h"
|
#include "meta-idle-monitor-private.h"
|
||||||
|
#include "meta-dbus-idle-monitor.h"
|
||||||
|
|
||||||
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
|
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
|
||||||
|
|
||||||
@ -596,3 +597,261 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
|
|||||||
|
|
||||||
return _xsyncvalue_to_int64 (value);
|
return _xsyncvalue_to_int64 (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_get_idletime (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
guint64 idletime;
|
||||||
|
|
||||||
|
idletime = meta_idle_monitor_get_idletime (monitor);
|
||||||
|
meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MetaDBusIdleMonitor *dbus_monitor;
|
||||||
|
MetaIdleMonitor *monitor;
|
||||||
|
char *dbus_name;
|
||||||
|
guint watch_id;
|
||||||
|
guint name_watcher_id;
|
||||||
|
} DBusWatch;
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_dbus_watch (gpointer data)
|
||||||
|
{
|
||||||
|
DBusWatch *watch = data;
|
||||||
|
|
||||||
|
g_object_unref (watch->dbus_monitor);
|
||||||
|
g_object_unref (watch->monitor);
|
||||||
|
g_free (watch->dbus_name);
|
||||||
|
g_bus_unwatch_name (watch->name_watcher_id);
|
||||||
|
|
||||||
|
g_slice_free (DBusWatch, watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbus_idle_callback (MetaIdleMonitor *monitor,
|
||||||
|
guint watch_id,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
DBusWatch *watch = user_data;
|
||||||
|
GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor);
|
||||||
|
|
||||||
|
g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton),
|
||||||
|
watch->dbus_name,
|
||||||
|
g_dbus_interface_skeleton_get_object_path (skeleton),
|
||||||
|
"org.gnome.Mutter.IdleMonitor",
|
||||||
|
"WatchFired",
|
||||||
|
g_variant_new ("(u)", watch_id),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
name_vanished_callback (GDBusConnection *connection,
|
||||||
|
const char *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
DBusWatch *watch = user_data;
|
||||||
|
|
||||||
|
meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusWatch *
|
||||||
|
make_dbus_watch (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
DBusWatch *watch;
|
||||||
|
|
||||||
|
watch = g_slice_new (DBusWatch);
|
||||||
|
watch->dbus_monitor = g_object_ref (skeleton);
|
||||||
|
watch->monitor = g_object_ref (monitor);
|
||||||
|
watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation));
|
||||||
|
watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation),
|
||||||
|
watch->dbus_name,
|
||||||
|
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||||
|
NULL, /* appeared */
|
||||||
|
name_vanished_callback,
|
||||||
|
watch, NULL);
|
||||||
|
|
||||||
|
return watch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_add_idle_watch (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
guint64 interval,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
DBusWatch *watch;
|
||||||
|
|
||||||
|
watch = make_dbus_watch (skeleton, invocation, monitor);
|
||||||
|
watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval,
|
||||||
|
dbus_idle_callback, watch, destroy_dbus_watch);
|
||||||
|
|
||||||
|
meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_add_user_active_watch (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
DBusWatch *watch;
|
||||||
|
|
||||||
|
watch = make_dbus_watch (skeleton, invocation, monitor);
|
||||||
|
watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor,
|
||||||
|
dbus_idle_callback, watch,
|
||||||
|
destroy_dbus_watch);
|
||||||
|
|
||||||
|
meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_remove_watch (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
guint id,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
meta_idle_monitor_remove_watch (monitor, id);
|
||||||
|
meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
||||||
|
MetaIdleMonitor *monitor,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
MetaDBusIdleMonitor *skeleton;
|
||||||
|
MetaDBusObjectSkeleton *object;
|
||||||
|
|
||||||
|
skeleton = meta_dbus_idle_monitor_skeleton_new ();
|
||||||
|
g_signal_connect_object (skeleton, "handle-add-idle-watch",
|
||||||
|
G_CALLBACK (handle_add_idle_watch), monitor, 0);
|
||||||
|
g_signal_connect_object (skeleton, "handle-add-user-active-watch",
|
||||||
|
G_CALLBACK (handle_add_user_active_watch), monitor, 0);
|
||||||
|
g_signal_connect_object (skeleton, "handle-remove-watch",
|
||||||
|
G_CALLBACK (handle_remove_watch), monitor, 0);
|
||||||
|
g_signal_connect_object (skeleton, "handle-get-idletime",
|
||||||
|
G_CALLBACK (handle_get_idletime), monitor, 0);
|
||||||
|
|
||||||
|
object = meta_dbus_object_skeleton_new (path);
|
||||||
|
meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
|
||||||
|
|
||||||
|
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_added (ClutterDeviceManager *device_manager,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
GDBusObjectManagerServer *manager)
|
||||||
|
{
|
||||||
|
|
||||||
|
MetaIdleMonitor *monitor;
|
||||||
|
int device_id;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
|
monitor = meta_idle_monitor_get_for_device (device_id);
|
||||||
|
path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id);
|
||||||
|
|
||||||
|
create_monitor_skeleton (manager, monitor, path);
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_removed (ClutterDeviceManager *device_manager,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
GDBusObjectManagerServer *manager)
|
||||||
|
{
|
||||||
|
int device_id;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
|
path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id);
|
||||||
|
g_dbus_object_manager_server_unexport (manager, path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
g_clear_object (&device_monitors[device_id]);
|
||||||
|
if (device_id == device_id_max)
|
||||||
|
device_id_max--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_bus_acquired (GDBusConnection *connection,
|
||||||
|
const char *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusObjectManagerServer *manager;
|
||||||
|
ClutterDeviceManager *device_manager;
|
||||||
|
MetaIdleMonitor *monitor;
|
||||||
|
GSList *devices, *iter;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor");
|
||||||
|
|
||||||
|
/* We never clear the core monitor, as that's supposed to cumulate idle times from
|
||||||
|
all devices */
|
||||||
|
monitor = meta_idle_monitor_get_core ();
|
||||||
|
path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core");
|
||||||
|
create_monitor_skeleton (manager, monitor, path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
device_manager = clutter_device_manager_get_default ();
|
||||||
|
devices = clutter_device_manager_list_devices (device_manager);
|
||||||
|
|
||||||
|
for (iter = devices; iter; iter = iter->next)
|
||||||
|
on_device_added (device_manager, iter->data, manager);
|
||||||
|
|
||||||
|
g_signal_connect_object (device_manager, "device-added",
|
||||||
|
G_CALLBACK (on_device_added), manager, 0);
|
||||||
|
g_signal_connect_object (device_manager, "device-removed",
|
||||||
|
G_CALLBACK (on_device_removed), manager, 0);
|
||||||
|
|
||||||
|
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_name_acquired (GDBusConnection *connection,
|
||||||
|
const char *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
meta_verbose ("Acquired name %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_name_lost (GDBusConnection *connection,
|
||||||
|
const char *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
meta_verbose ("Lost or failed to acquire name %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_idle_monitor_init_dbus (void)
|
||||||
|
{
|
||||||
|
static int dbus_name_id;
|
||||||
|
|
||||||
|
if (dbus_name_id > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
||||||
|
"org.gnome.Mutter.IdleMonitor",
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
|
||||||
|
(meta_get_replace_current_wm () ?
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_REPLACE : 0),
|
||||||
|
on_bus_acquired,
|
||||||
|
on_name_acquired,
|
||||||
|
on_name_lost,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
35
src/idle-monitor.xml
Normal file
35
src/idle-monitor.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||||
|
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||||
|
<node>
|
||||||
|
<!--
|
||||||
|
org.gnome.Mutter.IdleMonitor:
|
||||||
|
@short_description: idle monitor interface
|
||||||
|
|
||||||
|
This interface is used by gnome-desktop to implement
|
||||||
|
user activity monitoring.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<interface name="org.gnome.Mutter.IdleMonitor">
|
||||||
|
<method name="GetIdletime">
|
||||||
|
<arg name="idletime" direction="out" type="t"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="AddIdleWatch">
|
||||||
|
<arg name="interval" direction="in" type="t" />
|
||||||
|
<arg name="id" direction="out" type="u" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="AddUserActiveWatch">
|
||||||
|
<arg name="id" direction="out" type="u" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="RemoveWatch">
|
||||||
|
<arg name="id" direction="in" type="u" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<signal name="WatchFired">
|
||||||
|
<arg name="id" direction="out" type="u" />
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
Loading…
Reference in New Issue
Block a user