From bbc95c1688983f10781ac0b5c93d07479c84dbab Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 26 Oct 2021 11:59:31 +0200 Subject: [PATCH] clutter: Add yet another grab API Hopefully, the one to make them all converge. This new ClutterGrab represents a handle on a created grab. These are stacked, so grabs can be overridden and remain inactive until there is a time that they become active again, although undoing these early is optional. These grabs are global, they do apply to all pointer, touchpoint and keyboard foci. At the moment, only the API to create and stack those is added, the actual functionality is added in future commits. Part-of: --- clutter/clutter/clutter-grab.h | 38 ++++++++++++++++++++ clutter/clutter/clutter-stage.c | 62 +++++++++++++++++++++++++++++++++ clutter/clutter/clutter-stage.h | 5 +++ clutter/clutter/clutter.h | 1 + clutter/clutter/meson.build | 1 + 5 files changed, 107 insertions(+) create mode 100644 clutter/clutter/clutter-grab.h diff --git a/clutter/clutter/clutter-grab.h b/clutter/clutter/clutter-grab.h new file mode 100644 index 000000000..8c8704649 --- /dev/null +++ b/clutter/clutter/clutter-grab.h @@ -0,0 +1,38 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2021 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Carlos Garnacho + */ + +#ifndef CLUTTER_GRAB_H +#define CLUTTER_GRAB_H + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +typedef struct _ClutterGrab ClutterGrab; + +CLUTTER_EXPORT +void clutter_grab_dismiss (ClutterGrab *grab); + +#endif /* CLUTTER_GRAB_H */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 03a957065..e9354c488 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -52,6 +52,7 @@ #include "clutter-enum-types.h" #include "clutter-event-private.h" #include "clutter-frame-clock.h" +#include "clutter-grab.h" #include "clutter-id-pool.h" #include "clutter-input-device-private.h" #include "clutter-main.h" @@ -113,6 +114,8 @@ struct _ClutterStagePrivate gchar *title; ClutterActor *key_focused_actor; + ClutterGrab *topmost_grab; + GQueue *event_queue; GArray *paint_volume_stack; @@ -133,6 +136,14 @@ struct _ClutterStagePrivate guint actor_needs_immediate_relayout : 1; }; +struct _ClutterGrab +{ + ClutterStage *stage; + ClutterActor *actor; + ClutterGrab *prev; + ClutterGrab *next; +}; + enum { PROP_0, @@ -3625,3 +3636,54 @@ clutter_stage_pick_and_update_device (ClutterStage *stage, return new_actor; } + +ClutterGrab * +clutter_stage_grab (ClutterStage *stage, + ClutterActor *actor) +{ + ClutterStagePrivate *priv = stage->priv; + ClutterGrab *grab; + + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); + + grab = g_new0 (ClutterGrab, 1); + grab->stage = stage; + grab->actor = actor; + grab->prev = NULL; + grab->next = priv->topmost_grab; + + if (priv->topmost_grab) + priv->topmost_grab->prev = grab; + + priv->topmost_grab = grab; + + return grab; +} + +void +clutter_grab_dismiss (ClutterGrab *grab) +{ + ClutterStagePrivate *priv; + ClutterGrab *prev, *next; + + g_return_if_fail (grab != NULL); + + priv = grab->stage->priv; + prev = grab->prev; + next = grab->next; + + if (prev) + prev->next = next; + if (next) + next->prev = prev; + + if (priv->topmost_grab == grab) + { + /* This is the active grab */ + g_assert (prev == NULL); + priv->topmost_grab = next; + } + + g_free (grab); +} diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h index efb788e70..b45c50ccd 100644 --- a/clutter/clutter/clutter-stage.h +++ b/clutter/clutter/clutter-stage.h @@ -29,6 +29,7 @@ #endif #include +#include #include #include @@ -269,6 +270,10 @@ ClutterActor * clutter_stage_get_device_actor (ClutterStage *stage, ClutterInputDevice *device, ClutterEventSequence *sequence); +CLUTTER_EXPORT +ClutterGrab * clutter_stage_grab (ClutterStage *stage, + ClutterActor *actor); + G_END_DECLS #endif /* __CLUTTER_STAGE_H__ */ diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h index 8eefead61..be788b9e5 100644 --- a/clutter/clutter/clutter.h +++ b/clutter/clutter/clutter.h @@ -65,6 +65,7 @@ #include "clutter-frame-clock.h" #include "clutter-frame.h" #include "clutter-gesture-action.h" +#include "clutter-grab.h" #include "clutter-grid-layout.h" #include "clutter-image.h" #include "clutter-input-device.h" diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index cd2c897a7..2b8764a0f 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -39,6 +39,7 @@ clutter_headers = [ 'clutter-frame-clock.h', 'clutter-frame.h', 'clutter-gesture-action.h', + 'clutter-grab.h', 'clutter-grid-layout.h', 'clutter-image.h', 'clutter-input-device.h',