[mutter/wip/texture-purge-on-nvidia: 12/17] clutter-stage: add mechanism for peeking at queued events
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/texture-purge-on-nvidia: 12/17] clutter-stage: add mechanism for peeking at queued events
- Date: Fri, 11 Jan 2019 23:51:19 +0000 (UTC)
commit 02e3192a06b7f9117fe4ce7bcae281d731471cb8
Author: Ray Strode <rstrode redhat com>
Date: Wed Jan 9 16:52:05 2019 -0500
clutter-stage: add mechanism for peeking at queued events
We need to be able to see events when they're queued, not
when they're dispatched for updating idle time. This is
because events aren't dispatched when the frame clock is
frozen, and we don't unfreeze the frame clock until the
user idletime is updated.
This commit adds a mechanism for peeking at queued events.
A future commit will use that mechanism for fixing idletime
bookkeeping.
clutter/clutter/clutter-stage.c | 73 +++++++++++++++++++++++++++++++++++++++++
clutter/clutter/clutter-stage.h | 9 +++++
2 files changed, 82 insertions(+)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 9352f49e8..e01aa2adf 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -105,6 +105,11 @@ struct _ClutterStageQueueRedrawEntry
ClutterPaintVolume clip;
};
+typedef struct _ClutterStageEventFilter {
+ ClutterEventFilterFunc func;
+ gpointer user_data;
+} ClutterStageEventFilter;
+
struct _ClutterStagePrivate
{
/* the stage implementation */
@@ -149,6 +154,8 @@ struct _ClutterStagePrivate
gpointer paint_data;
GDestroyNotify paint_notify;
+ GList *event_filters;
+
guint relayout_pending : 1;
guint redraw_pending : 1;
guint is_fullscreen : 1;
@@ -204,6 +211,8 @@ static void clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage);
static void free_queue_redraw_entry (ClutterStageQueueRedrawEntry *entry);
static void clutter_container_iface_init (ClutterContainerIface *iface);
+static gboolean clutter_stage_process_filters (ClutterStage *stage,
+ ClutterEvent *event);
G_DEFINE_TYPE_WITH_CODE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP,
G_ADD_PRIVATE (ClutterStage)
@@ -919,6 +928,12 @@ _clutter_stage_queue_event (ClutterStage *stage,
_clutter_input_device_set_state (device, event_state);
_clutter_input_device_set_time (device, event_time);
}
+
+ if (clutter_stage_process_filters (stage, event) == CLUTTER_EVENT_STOP)
+ {
+ g_queue_pop_tail (priv->event_queue);
+ clutter_event_free (event);
+ }
}
gboolean
@@ -4903,3 +4918,61 @@ clutter_stage_capture_into (ClutterStage *stage,
view = get_view_at_rect (stage, rect);
capture_view_into (stage, paint, view, rect, data, rect->width * bpp);
}
+
+static gboolean
+clutter_stage_process_filters (ClutterStage *self,
+ ClutterEvent *event)
+{
+ GList *l, *next;
+ ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
+
+ /* Event filters are handled in order from least recently added to
+ * most recently added */
+
+ for (l = priv->event_filters; l; l = next)
+ {
+ ClutterStageEventFilter *event_filter = l->data;
+
+ next = l->next;
+
+ if (event_filter->func (event, event_filter->user_data) == CLUTTER_EVENT_STOP)
+ return CLUTTER_EVENT_STOP;
+ }
+
+ return CLUTTER_EVENT_PROPAGATE;
+}
+
+void
+clutter_stage_add_filter (ClutterStage *self,
+ ClutterEventFilterFunc func,
+ gpointer user_data)
+{
+ ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
+ ClutterStageEventFilter *event_filter = g_slice_new (ClutterStageEventFilter);
+ static guint event_filter_id = 0;
+
+ event_filter->func = func;
+ event_filter->user_data = user_data;
+
+ priv->event_filters = g_list_append (priv->event_filters, event_filter);
+}
+
+void
+clutter_stage_remove_filter (ClutterStage *self,
+ ClutterEventFilterFunc func,
+ gpointer user_data)
+{
+ ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
+ GList *l;
+
+ for (l = priv->event_filters; l; l = l->next)
+ {
+ ClutterStageEventFilter *event_filter = l->data;
+
+ if (event_filter->func == func && event_filter->user_data == user_data)
+ {
+ priv->event_filters = g_list_delete_link (priv->event_filters, l);
+ g_slice_free (ClutterStageEventFilter, event_filter);
+ }
+ }
+}
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
index e8fbda84c..5bc31cb1d 100644
--- a/clutter/clutter/clutter-stage.h
+++ b/clutter/clutter/clutter-stage.h
@@ -265,6 +265,15 @@ gboolean clutter_stage_capture (ClutterStage *stage,
ClutterCapture **captures,
int *n_captures);
+CLUTTER_AVAILABLE_IN_MUTTER
+void clutter_stage_add_filter (ClutterStage *self,
+ ClutterEventFilterFunc func,
+ gpointer user_data);
+CLUTTER_AVAILABLE_IN_MUTTER
+void clutter_stage_remove_filter (ClutterStage *self,
+ ClutterEventFilterFunc func,
+ gpointer user_data);
+
G_END_DECLS
#endif /* __CLUTTER_STAGE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]