summaryrefslogtreecommitdiff
path: root/clutter/clutter/clutter-stage.c
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2016-11-11 20:26:54 +0100
committerCarlos Garnacho <carlosg@gnome.org>2017-05-23 16:37:53 +0200
commit4b23eb064c9c3a87cf07c39593dcff5c27a23bbd (patch)
treee3e948ac592c57cbc0a790127b776b371733aa37 /clutter/clutter/clutter-stage.c
parent498200776c57aa25b35deecd56f43f28f53959e1 (diff)
downloadmutter-4b23eb064c9c3a87cf07c39593dcff5c27a23bbd.tar.gz
clutter: Update pointer position on master clock's update stage
Ensure the pointer position is up-to-date for the pointers inside the clip area after the stage got actors relayout. https://bugzilla.gnome.org/show_bug.cgi?id=755164
Diffstat (limited to 'clutter/clutter/clutter-stage.c')
-rw-r--r--clutter/clutter/clutter-stage.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index c07d0399a..a3ee0010c 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -161,6 +161,7 @@ struct _ClutterStagePrivate
guint accept_focus : 1;
guint motion_events_enabled : 1;
guint has_custom_perspective : 1;
+ guint stage_was_relayout : 1;
};
enum
@@ -1059,6 +1060,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
{
priv->relayout_pending = FALSE;
+ priv->stage_was_relayout = TRUE;
CLUTTER_NOTE (ACTOR, "Recomputing layout");
@@ -1129,6 +1131,58 @@ clutter_stage_do_redraw (ClutterStage *stage)
stage);
}
+static GSList *
+_clutter_stage_check_updated_pointers (ClutterStage *stage)
+{
+ ClutterStagePrivate *priv = stage->priv;
+ ClutterDeviceManager *device_manager;
+ GSList *updating = NULL;
+ const GSList *devices;
+ cairo_rectangle_int_t clip;
+ ClutterPoint point;
+ gboolean has_clip;
+
+ has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip);
+
+ device_manager = clutter_device_manager_get_default ();
+ devices = clutter_device_manager_peek_devices (device_manager);
+
+ for (; devices != NULL; devices = devices->next)
+ {
+ ClutterInputDevice *dev = devices->data;
+
+ if (clutter_input_device_get_device_mode (dev) !=
+ CLUTTER_INPUT_MODE_MASTER)
+ continue;
+
+ switch (clutter_input_device_get_device_type (dev))
+ {
+ case CLUTTER_POINTER_DEVICE:
+ case CLUTTER_TABLET_DEVICE:
+ case CLUTTER_PEN_DEVICE:
+ case CLUTTER_ERASER_DEVICE:
+ case CLUTTER_CURSOR_DEVICE:
+ if (!clutter_input_device_get_coords (dev, NULL, &point))
+ continue;
+
+ if (!has_clip ||
+ (point.x >= clip.x && point.x < clip.x + clip.width &&
+ point.y >= clip.y && point.y < clip.y + clip.height))
+ updating = g_slist_prepend (updating, dev);
+ break;
+ default:
+ /* Any other devices don't need checking, either because they
+ * don't have x/y coordinates, or because they're implicitly
+ * grabbed on an actor by default as it's the case of
+ * touch(screens).
+ */
+ break;
+ }
+ }
+
+ return updating;
+}
+
/**
* _clutter_stage_do_update:
* @stage: A #ClutterStage
@@ -1141,6 +1195,10 @@ gboolean
_clutter_stage_do_update (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
+ gboolean stage_was_relayout = priv->stage_was_relayout;
+ GSList *pointers = NULL;
+
+ priv->stage_was_relayout = FALSE;
/* if the stage is being destroyed, or if the destruction already
* happened and we don't have an StageWindow any more, then we
@@ -1161,6 +1219,9 @@ _clutter_stage_do_update (ClutterStage *stage)
if (!priv->redraw_pending)
return FALSE;
+ if (stage_was_relayout)
+ pointers = _clutter_stage_check_updated_pointers (stage);
+
clutter_stage_maybe_finish_queue_redraws (stage);
clutter_stage_do_redraw (stage);
@@ -1178,6 +1239,12 @@ _clutter_stage_do_update (ClutterStage *stage)
}
#endif /* CLUTTER_ENABLE_DEBUG */
+ while (pointers)
+ {
+ _clutter_input_device_update (pointers->data, NULL, TRUE);
+ pointers = g_slist_delete_link (pointers, pointers);
+ }
+
return TRUE;
}