clutter: Add docs and introspection annotations to grabs

Since we want these accessed from bindings this must be a boxed
type. This has the side effect of making ClutterGrab a refcounted
object, since we want to avoid JS from pointing to freed memory
and maybe causing crashes if misusing the object after dismiss.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
This commit is contained in:
Carlos Garnacho 2021-11-17 23:17:14 +01:00 committed by Marge Bot
parent ff98cbb19f
commit 3a79b7b066
3 changed files with 82 additions and 1 deletions

View File

@ -30,12 +30,22 @@
#include <glib-object.h>
#define CLUTTER_TYPE_GRAB (clutter_grab_get_type ())
typedef struct _ClutterGrab ClutterGrab;
CLUTTER_EXPORT
GType clutter_grab_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
void clutter_grab_dismiss (ClutterGrab *grab);
CLUTTER_EXPORT
ClutterGrabState clutter_grab_get_seat_state (ClutterGrab *grab);
CLUTTER_EXPORT
ClutterGrab * clutter_grab_ref (ClutterGrab *grab);
CLUTTER_EXPORT
void clutter_grab_unref (ClutterGrab *grab);
#endif /* CLUTTER_GRAB_H */

View File

@ -137,6 +137,7 @@ struct _ClutterStagePrivate
struct _ClutterGrab
{
grefcount ref_count;
ClutterStage *stage;
ClutterActor *actor;
ClutterGrab *prev;
@ -3750,6 +3751,37 @@ clutter_stage_notify_grab (ClutterStage *stage,
clutter_stage_notify_grab_on_key_focus (stage, cur_actor, old_actor);
}
ClutterGrab *
clutter_grab_ref (ClutterGrab *grab)
{
g_ref_count_inc (&grab->ref_count);
return grab;
}
void
clutter_grab_unref (ClutterGrab *grab)
{
if (g_ref_count_dec (&grab->ref_count))
{
clutter_grab_dismiss (grab);
g_free (grab);
}
}
G_DEFINE_BOXED_TYPE (ClutterGrab, clutter_grab,
clutter_grab_ref, clutter_grab_unref)
/**
* clutter_stage_grab:
* @stage: The #ClutterStage
* @actor: The actor grabbing input
*
* Grabs input onto a certain actor. Events will be propagated as
* usual inside its hierarchy.
*
* Returns: (transfer none): (nullable): an opaque #ClutterGrab handle, drop
* with clutter_grab_dismiss()
**/
ClutterGrab *
clutter_stage_grab (ClutterStage *stage,
ClutterActor *actor)
@ -3773,6 +3805,7 @@ clutter_stage_grab (ClutterStage *stage,
}
grab = g_new0 (ClutterGrab, 1);
g_ref_count_init (&grab->ref_count);
grab->stage = stage;
grab->actor = actor;
grab->prev = NULL;
@ -3833,15 +3866,31 @@ clutter_stage_unlink_grab (ClutterStage *stage,
grab->prev = NULL;
}
/**
* clutter_grab_dismiss:
* @grab: Grab to undo
*
* Removes a grab. If this grab is effective, crossing events
* will be generated to indicate the change in event redirection.
**/
void
clutter_grab_dismiss (ClutterGrab *grab)
{
g_return_if_fail (grab != NULL);
clutter_stage_unlink_grab (grab->stage, grab);
g_free (grab);
}
/**
* clutter_grab_get_seat_state:
* @grab: a Grab handle
*
* Returns the windowing-level state of the
* grab, the devices that are guaranteed to be
* grabbed.
*
* Returns: The state of the grab.
**/
ClutterGrabState
clutter_grab_get_seat_state (ClutterGrab *grab)
{
@ -3850,6 +3899,14 @@ clutter_grab_get_seat_state (ClutterGrab *grab)
return grab->stage->priv->grab_state;
}
/**
* clutter_stage_get_grab_actor:
* @stage: a #ClutterStage
*
* Gets the actor that currently holds a grab.
*
* Returns: (transfer none): The grabbing actor
**/
ClutterActor *
clutter_stage_get_grab_actor (ClutterStage *stage)
{

View File

@ -217,6 +217,7 @@ grab_under_pointer (void)
event_log_compare ((EventLog *) &grab_log, data.events);
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
event_log_compare ((EventLog *) &ungrab_log, data.events);
test_data_shutdown (&data);
@ -243,6 +244,7 @@ grab_under_pointers_parent (void)
event_log_compare ((EventLog *) &grab_log, data.events);
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
event_log_compare ((EventLog *) &ungrab_log, data.events);
test_data_shutdown (&data);
@ -273,6 +275,7 @@ grab_outside_pointer (void)
event_log_compare ((EventLog *) &grab_log, data.events);
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
event_log_compare ((EventLog *) &ungrab_log, data.events);
test_data_shutdown (&data);
@ -297,6 +300,7 @@ grab_stage (void)
event_log_compare ((EventLog *) &grab_log, data.events);
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
event_log_compare ((EventLog *) &ungrab_log, data.events);
test_data_shutdown (&data);
@ -340,9 +344,11 @@ grab_stack_1 (void)
/* Dismiss orderly */
clutter_grab_dismiss (grab2);
clutter_grab_unref (grab2);
event_log_compare ((EventLog *) &ungrab2_log, data.events);
clutter_grab_dismiss (grab1);
clutter_grab_unref (grab1);
event_log_compare ((EventLog *) &ungrab1_log, data.events);
test_data_shutdown (&data);
@ -388,9 +394,11 @@ grab_stack_2 (void)
/* Dismiss orderly */
clutter_grab_dismiss (grab2);
clutter_grab_unref (grab2);
event_log_compare ((EventLog *) &ungrab2_log, data.events);
clutter_grab_dismiss (grab1);
clutter_grab_unref (grab1);
event_log_compare ((EventLog *) &ungrab1_log, data.events);
test_data_shutdown (&data);
@ -434,9 +442,11 @@ grab_unordered_ungrab_1 (void)
/* Dismiss disorderly */
clutter_grab_dismiss (grab1);
clutter_grab_unref (grab1);
event_log_compare ((EventLog *) &ungrab1_log, data.events);
clutter_grab_dismiss (grab2);
clutter_grab_unref (grab2);
event_log_compare ((EventLog *) &ungrab2_log, data.events);
test_data_shutdown (&data);
@ -478,9 +488,11 @@ grab_unordered_ungrab_2 (void)
/* Dismiss disorderly */
clutter_grab_dismiss (grab1);
clutter_grab_unref (grab1);
event_log_compare ((EventLog *) &ungrab1_log, data.events);
clutter_grab_dismiss (grab2);
clutter_grab_unref (grab2);
event_log_compare ((EventLog *) &ungrab2_log, data.events);
test_data_shutdown (&data);
@ -501,6 +513,7 @@ grab_key_focus_in_grab (void)
g_assert_true (clutter_actor_has_key_focus (data.b));
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
g_assert_true (clutter_actor_has_key_focus (data.b));
test_data_shutdown (&data);
@ -521,6 +534,7 @@ grab_key_focus_outside_grab (void)
g_assert_false (clutter_actor_has_key_focus (data.b));
clutter_grab_dismiss (grab);
clutter_grab_unref (grab);
g_assert_true (clutter_actor_has_key_focus (data.b));
test_data_shutdown (&data);