mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
clutter: Carry accounting of grabs in the ClutterActors holding them
And make it required that actors must be mapped to hold a grab. These grabs will be automatically undone when the actor is unmapped. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
This commit is contained in:
parent
2e94efddc9
commit
1713f791cb
@ -23,6 +23,7 @@
|
||||
#define __CLUTTER_ACTOR_PRIVATE_H__
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
#include <clutter/clutter-grab.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -272,6 +273,11 @@ gboolean clutter_actor_get_redraw_clip (ClutterActor *self,
|
||||
ClutterPaintVolume *dst_old_pv,
|
||||
ClutterPaintVolume *dst_new_pv);
|
||||
|
||||
void clutter_actor_attach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
void clutter_actor_detach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||
|
@ -801,6 +801,7 @@ struct _ClutterActorPrivate
|
||||
gulong layout_changed_id;
|
||||
|
||||
GList *stage_views;
|
||||
GList *grabs;
|
||||
|
||||
/* bitfields: KEEP AT THE END */
|
||||
|
||||
@ -1633,6 +1634,25 @@ maybe_unset_key_focus (ClutterActor *self)
|
||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_clear_grabs (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterActor *stage;
|
||||
|
||||
if (!priv->grabs)
|
||||
return;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (self);
|
||||
g_assert (stage != NULL);
|
||||
|
||||
/* Undo every grab that the actor may hold, priv->grabs
|
||||
* will be updated internally in clutter_stage_unlink_grab().
|
||||
*/
|
||||
while (priv->grabs)
|
||||
clutter_stage_unlink_grab (CLUTTER_STAGE (stage), priv->grabs->data);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_real_unmap (ClutterActor *self)
|
||||
{
|
||||
@ -1678,6 +1698,8 @@ clutter_actor_real_unmap (ClutterActor *self)
|
||||
/* relinquish keyboard focus if we were unmapped while owning it */
|
||||
if (!CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||
maybe_unset_key_focus (self);
|
||||
|
||||
clutter_actor_clear_grabs (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5586,6 +5608,8 @@ clutter_actor_finalize (GObject *object)
|
||||
_clutter_actor_get_debug_name ((ClutterActor *) object),
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
|
||||
/* No new grabs should have happened after unmapping */
|
||||
g_assert (priv->grabs == NULL);
|
||||
g_free (priv->name);
|
||||
|
||||
g_free (priv->debug_name);
|
||||
@ -19684,3 +19708,21 @@ clutter_actor_get_redraw_clip (ClutterActor *self,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_attach_grab (ClutterActor *self,
|
||||
ClutterGrab *grab)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
priv->grabs = g_list_prepend (priv->grabs, grab);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_detach_grab (ClutterActor *self,
|
||||
ClutterGrab *grab)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
priv->grabs = g_list_remove (priv->grabs, grab);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#ifndef __CLUTTER_STAGE_PRIVATE_H__
|
||||
#define __CLUTTER_STAGE_PRIVATE_H__
|
||||
|
||||
#include <clutter/clutter-grab.h>
|
||||
#include <clutter/clutter-stage-window.h>
|
||||
#include <clutter/clutter-stage.h>
|
||||
#include <clutter/clutter-input-device.h>
|
||||
@ -149,6 +150,9 @@ ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *s
|
||||
graphene_point_t point,
|
||||
uint32_t time_ms);
|
||||
|
||||
void clutter_stage_unlink_grab (ClutterStage *self,
|
||||
ClutterGrab *grab);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||
|
@ -3873,20 +3873,23 @@ clutter_stage_grab (ClutterStage *stage,
|
||||
priv->topmost_grab->prev = grab;
|
||||
|
||||
priv->topmost_grab = grab;
|
||||
clutter_actor_attach_grab (actor, grab);
|
||||
clutter_stage_notify_grab (stage, grab, grab->next);
|
||||
|
||||
return grab;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_grab_dismiss (ClutterGrab *grab)
|
||||
clutter_stage_unlink_grab (ClutterStage *stage,
|
||||
ClutterGrab *grab)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterGrab *prev, *next;
|
||||
|
||||
g_return_if_fail (grab != NULL);
|
||||
/* This grab is already detached */
|
||||
if (!grab->prev && !grab->next && priv->topmost_grab != grab)
|
||||
return;
|
||||
|
||||
priv = grab->stage->priv;
|
||||
prev = grab->prev;
|
||||
next = grab->next;
|
||||
|
||||
@ -3903,6 +3906,18 @@ clutter_grab_dismiss (ClutterGrab *grab)
|
||||
clutter_stage_notify_grab (stage, next, grab);
|
||||
}
|
||||
|
||||
clutter_actor_detach_grab (grab->actor, grab);
|
||||
|
||||
grab->next = NULL;
|
||||
grab->prev = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_grab_dismiss (ClutterGrab *grab)
|
||||
{
|
||||
g_return_if_fail (grab != NULL);
|
||||
|
||||
clutter_stage_unlink_grab (grab->stage, grab);
|
||||
g_free (grab);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user