mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 11:00:54 -05:00
MetaIdleMonitor: add wayland support
Keep a timer source that we reset when we capture an event in MetaWayland, and fire watches accordingly. https://bugzilla.gnome.org/show_bug.cgi?id=706005
This commit is contained in:
parent
c0acf3ae6d
commit
9affbf10a6
@ -26,5 +26,6 @@
|
|||||||
|
|
||||||
void meta_idle_monitor_handle_xevent_all (XEvent *xevent);
|
void meta_idle_monitor_handle_xevent_all (XEvent *xevent);
|
||||||
|
|
||||||
|
void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor);
|
||||||
|
|
||||||
void meta_idle_monitor_init_dbus (void);
|
void meta_idle_monitor_init_dbus (void);
|
||||||
|
@ -57,6 +57,9 @@ struct _MetaIdleMonitor
|
|||||||
int sync_event_base;
|
int sync_event_base;
|
||||||
XSyncCounter counter;
|
XSyncCounter counter;
|
||||||
XSyncAlarm user_active_alarm;
|
XSyncAlarm user_active_alarm;
|
||||||
|
|
||||||
|
/* Wayland implementation */
|
||||||
|
guint64 last_event_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaIdleMonitorClass
|
struct _MetaIdleMonitorClass
|
||||||
@ -75,6 +78,9 @@ typedef struct
|
|||||||
|
|
||||||
/* x11 */
|
/* x11 */
|
||||||
XSyncAlarm xalarm;
|
XSyncAlarm xalarm;
|
||||||
|
|
||||||
|
/* wayland */
|
||||||
|
GSource *timeout_source;
|
||||||
} MetaIdleMonitorWatch;
|
} MetaIdleMonitorWatch;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -290,6 +296,9 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch)
|
|||||||
g_hash_table_remove (monitor->alarms, (gpointer) watch->xalarm);
|
g_hash_table_remove (monitor->alarms, (gpointer) watch->xalarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (watch->timeout_source != NULL)
|
||||||
|
g_source_destroy (watch->timeout_source);
|
||||||
|
|
||||||
g_slice_free (MetaIdleMonitorWatch, watch);
|
g_slice_free (MetaIdleMonitorWatch, watch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,8 +377,11 @@ meta_idle_monitor_constructed (GObject *object)
|
|||||||
{
|
{
|
||||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
|
MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
|
||||||
|
|
||||||
|
if (!meta_is_wayland_compositor ())
|
||||||
|
{
|
||||||
monitor->display = meta_get_display ()->xdisplay;
|
monitor->display = meta_get_display ()->xdisplay;
|
||||||
init_xsync (monitor);
|
init_xsync (monitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -448,6 +460,25 @@ meta_idle_monitor_get_for_device (int device_id)
|
|||||||
return device_monitors[device_id];
|
return device_monitors[device_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
wayland_dispatch_timeout (GSource *source,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitorWatch *watch = user_data;
|
||||||
|
|
||||||
|
fire_watch (watch);
|
||||||
|
g_source_set_ready_time (watch->timeout_source, -1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSourceFuncs wayland_source_funcs = {
|
||||||
|
NULL, /* prepare */
|
||||||
|
NULL, /* check */
|
||||||
|
wayland_dispatch_timeout,
|
||||||
|
NULL, /* finalize */
|
||||||
|
};
|
||||||
|
|
||||||
static MetaIdleMonitorWatch *
|
static MetaIdleMonitorWatch *
|
||||||
make_watch (MetaIdleMonitor *monitor,
|
make_watch (MetaIdleMonitor *monitor,
|
||||||
guint64 timeout_msec,
|
guint64 timeout_msec,
|
||||||
@ -465,6 +496,22 @@ make_watch (MetaIdleMonitor *monitor,
|
|||||||
watch->notify = notify;
|
watch->notify = notify;
|
||||||
watch->timeout_msec = timeout_msec;
|
watch->timeout_msec = timeout_msec;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
{
|
||||||
|
if (timeout_msec != 0)
|
||||||
|
{
|
||||||
|
GSource *source = g_source_new (&wayland_source_funcs, sizeof (GSource));
|
||||||
|
|
||||||
|
g_source_set_callback (source, NULL, watch, NULL);
|
||||||
|
g_source_set_ready_time (source, monitor->last_event_time + timeout_msec * 1000);
|
||||||
|
g_source_attach (source, NULL);
|
||||||
|
g_source_unref (source);
|
||||||
|
|
||||||
|
watch->timeout_source = source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (timeout_msec != 0)
|
if (timeout_msec != 0)
|
||||||
{
|
{
|
||||||
watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE);
|
watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE);
|
||||||
@ -477,6 +524,7 @@ make_watch (MetaIdleMonitor *monitor,
|
|||||||
|
|
||||||
set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE);
|
set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_insert (monitor->watches,
|
g_hash_table_insert (monitor->watches,
|
||||||
GUINT_TO_POINTER (watch->id),
|
GUINT_TO_POINTER (watch->id),
|
||||||
@ -592,10 +640,69 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
|
|||||||
{
|
{
|
||||||
XSyncValue value;
|
XSyncValue value;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
{
|
||||||
|
return (g_get_monotonic_time () - monitor->last_event_time) / 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!XSyncQueryCounter (monitor->display, monitor->counter, &value))
|
if (!XSyncQueryCounter (monitor->display, monitor->counter, &value))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return _xsyncvalue_to_int64 (value);
|
return _xsyncvalue_to_int64 (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MetaIdleMonitor *monitor;
|
||||||
|
GList *fired_watches;
|
||||||
|
} CheckWaylandClosure;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
check_wayland_watch (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitorWatch *watch = value;
|
||||||
|
CheckWaylandClosure *closure = user_data;
|
||||||
|
gboolean steal;
|
||||||
|
|
||||||
|
if (watch->timeout_msec == 0)
|
||||||
|
{
|
||||||
|
closure->fired_watches = g_list_prepend (closure->fired_watches, watch);
|
||||||
|
steal = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_source_set_ready_time (watch->timeout_source,
|
||||||
|
closure->monitor->last_event_time +
|
||||||
|
watch->timeout_msec * 1000);
|
||||||
|
steal = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return steal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fire_wayland_watch (gpointer watch,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
fire_watch (watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
CheckWaylandClosure closure;
|
||||||
|
|
||||||
|
monitor->last_event_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
closure.monitor = monitor;
|
||||||
|
closure.fired_watches = NULL;
|
||||||
|
g_hash_table_foreach_steal (monitor->watches, check_wayland_watch, &closure);
|
||||||
|
|
||||||
|
g_list_foreach (closure.fired_watches, fire_wayland_watch, NULL);
|
||||||
|
g_list_free (closure.fired_watches);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include <meta/types.h>
|
#include <meta/types.h>
|
||||||
#include <meta/main.h>
|
#include <meta/main.h>
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
#include "meta-idle-monitor-private.h"
|
||||||
|
|
||||||
static MetaWaylandCompositor _meta_wayland_compositor;
|
static MetaWaylandCompositor _meta_wayland_compositor;
|
||||||
|
|
||||||
@ -1260,6 +1261,31 @@ synthesize_motion_event (MetaWaylandCompositor *compositor,
|
|||||||
meta_display_handle_event (display, (XEvent *) &generic_event);
|
meta_display_handle_event (display, (XEvent *) &generic_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reset_idletimes (const ClutterEvent *event)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *device, *source_device;
|
||||||
|
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||||
|
int device_id;
|
||||||
|
|
||||||
|
device = clutter_event_get_device (event);
|
||||||
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
|
|
||||||
|
core_monitor = meta_idle_monitor_get_core ();
|
||||||
|
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||||
|
|
||||||
|
meta_idle_monitor_reset_idletime (core_monitor);
|
||||||
|
meta_idle_monitor_reset_idletime (device_monitor);
|
||||||
|
|
||||||
|
source_device = clutter_event_get_source_device (event);
|
||||||
|
if (source_device != device)
|
||||||
|
{
|
||||||
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
|
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||||
|
meta_idle_monitor_reset_idletime (device_monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
event_cb (ClutterActor *stage,
|
event_cb (ClutterActor *stage,
|
||||||
const ClutterEvent *event,
|
const ClutterEvent *event,
|
||||||
@ -1270,6 +1296,8 @@ event_cb (ClutterActor *stage,
|
|||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
|
|
||||||
|
reset_idletimes (event);
|
||||||
|
|
||||||
meta_wayland_seat_handle_event (compositor->seat, event);
|
meta_wayland_seat_handle_event (compositor->seat, event);
|
||||||
|
|
||||||
/* HACK: for now, the surfaces from Wayland clients aren't
|
/* HACK: for now, the surfaces from Wayland clients aren't
|
||||||
|
Loading…
Reference in New Issue
Block a user