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__
|
#define __CLUTTER_ACTOR_PRIVATE_H__
|
||||||
|
|
||||||
#include <clutter/clutter-actor.h>
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-grab.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -272,6 +273,11 @@ gboolean clutter_actor_get_redraw_clip (ClutterActor *self,
|
|||||||
ClutterPaintVolume *dst_old_pv,
|
ClutterPaintVolume *dst_old_pv,
|
||||||
ClutterPaintVolume *dst_new_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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||||
|
@ -801,6 +801,7 @@ struct _ClutterActorPrivate
|
|||||||
gulong layout_changed_id;
|
gulong layout_changed_id;
|
||||||
|
|
||||||
GList *stage_views;
|
GList *stage_views;
|
||||||
|
GList *grabs;
|
||||||
|
|
||||||
/* bitfields: KEEP AT THE END */
|
/* bitfields: KEEP AT THE END */
|
||||||
|
|
||||||
@ -1633,6 +1634,25 @@ maybe_unset_key_focus (ClutterActor *self)
|
|||||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL);
|
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
|
static void
|
||||||
clutter_actor_real_unmap (ClutterActor *self)
|
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 */
|
/* relinquish keyboard focus if we were unmapped while owning it */
|
||||||
if (!CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
if (!CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||||
maybe_unset_key_focus (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),
|
_clutter_actor_get_debug_name ((ClutterActor *) object),
|
||||||
g_type_name (G_OBJECT_TYPE (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->name);
|
||||||
|
|
||||||
g_free (priv->debug_name);
|
g_free (priv->debug_name);
|
||||||
@ -19684,3 +19708,21 @@ clutter_actor_get_redraw_clip (ClutterActor *self,
|
|||||||
|
|
||||||
return TRUE;
|
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__
|
#ifndef __CLUTTER_STAGE_PRIVATE_H__
|
||||||
#define __CLUTTER_STAGE_PRIVATE_H__
|
#define __CLUTTER_STAGE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-grab.h>
|
||||||
#include <clutter/clutter-stage-window.h>
|
#include <clutter/clutter-stage-window.h>
|
||||||
#include <clutter/clutter-stage.h>
|
#include <clutter/clutter-stage.h>
|
||||||
#include <clutter/clutter-input-device.h>
|
#include <clutter/clutter-input-device.h>
|
||||||
@ -149,6 +150,9 @@ ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *s
|
|||||||
graphene_point_t point,
|
graphene_point_t point,
|
||||||
uint32_t time_ms);
|
uint32_t time_ms);
|
||||||
|
|
||||||
|
void clutter_stage_unlink_grab (ClutterStage *self,
|
||||||
|
ClutterGrab *grab);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||||
|
@ -3873,20 +3873,23 @@ clutter_stage_grab (ClutterStage *stage,
|
|||||||
priv->topmost_grab->prev = grab;
|
priv->topmost_grab->prev = grab;
|
||||||
|
|
||||||
priv->topmost_grab = grab;
|
priv->topmost_grab = grab;
|
||||||
|
clutter_actor_attach_grab (actor, grab);
|
||||||
clutter_stage_notify_grab (stage, grab, grab->next);
|
clutter_stage_notify_grab (stage, grab, grab->next);
|
||||||
|
|
||||||
return grab;
|
return grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clutter_grab_dismiss (ClutterGrab *grab)
|
clutter_stage_unlink_grab (ClutterStage *stage,
|
||||||
|
ClutterGrab *grab)
|
||||||
{
|
{
|
||||||
ClutterStagePrivate *priv;
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
ClutterGrab *prev, *next;
|
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;
|
prev = grab->prev;
|
||||||
next = grab->next;
|
next = grab->next;
|
||||||
|
|
||||||
@ -3903,6 +3906,18 @@ clutter_grab_dismiss (ClutterGrab *grab)
|
|||||||
clutter_stage_notify_grab (stage, next, 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);
|
g_free (grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user