Fix xdg-positioner implementation

* compositor.h (struct _Positioner): New struct.
* positioner.c (struct _Positioner): Move to compositor.h.
(RetainPositioner, ReleasePositioner): Remove functions.
(HandleResourceDestroy): Destroy positioner instead.
(XLCreateXdgPositioner): Remove reference-counting logic.
(XLRetainPositioner, XLReleasePositioner): Delete functions.
(XLPositionerIsReactive): Delete function.
* xdg_popup.c (struct _XdgPopup): Make positioner a struct
instead of a pointer.
(DestroyBacking, InternalReposition, Reposition)
(HandleParentConfigure, HandleParentResize, XLGetXdgPopup): Copy
positioner instead of taking a reference.
This commit is contained in:
hujianwei 2022-11-14 10:26:58 +00:00
parent d32e9cbf8a
commit 7919b65eca
3 changed files with 48 additions and 75 deletions

View file

@ -1395,13 +1395,31 @@ extern void XLXdgRoleReplyPing (Role *);
typedef struct _Positioner Positioner;
/* This structure is public because positioners must be copied into
xdg_popups. */
struct _Positioner
{
/* The fields below mean what they do in the xdg_shell protocol
spec. */
int width, height;
int anchor_x, anchor_y;
int anchor_width, anchor_height;
unsigned int anchor, gravity, constraint;
int offset_x, offset_y;
Bool reactive;
int parent_width, parent_height;
uint32_t constraint_adjustment;
/* The wl_resource corresponding to this positioner. Not valid when
embedded in i.e. an xdg_popup. */
struct wl_resource *resource;
};
extern void XLCreateXdgPositioner (struct wl_client *, struct wl_resource *,
uint32_t);
extern void XLPositionerCalculateGeometry (Positioner *, Role *, int *, int *,
int *, int *);
extern void XLRetainPositioner (Positioner *);
extern void XLReleasePositioner (Positioner *);
extern Bool XLPositionerIsReactive (Positioner *);
extern void XLCheckPositionerComplete (Positioner *);
/* Defined in xdg_toplevel.c. */

View file

@ -61,26 +61,6 @@ enum _AnchorGravity
AnchorGravityBottomRight,
};
struct _Positioner
{
/* The fields below mean what they do in the xdg_shell protocol
spec. */
int width, height;
int anchor_x, anchor_y;
int anchor_width, anchor_height;
unsigned int anchor, gravity, constraint;
int offset_x, offset_y;
Bool reactive;
int parent_width, parent_height;
uint32_t constraint_adjustment;
/* The wl_resource corresponding to this positioner. */
struct wl_resource *resource;
/* The number of references to this positioner. */
int refcount;
};
/* Surface used to handle scaling during constraint adjustment
calculation. */
static double scale_adjustment_factor;
@ -226,28 +206,13 @@ static const struct xdg_positioner_interface xdg_positioner_impl =
.set_parent_configure = SetParentConfigure,
};
static void
RetainPositioner (Positioner *positioner)
{
positioner->refcount++;
}
static void
ReleasePositioner (Positioner *positioner)
{
if (--positioner->refcount)
return;
XLFree (positioner);
}
static void
HandleResourceDestroy (struct wl_resource *resource)
{
Positioner *positioner;
positioner = wl_resource_get_user_data (resource);
ReleasePositioner (positioner);
XLFree (positioner);
}
static void
@ -920,25 +885,6 @@ XLCreateXdgPositioner (struct wl_client *client, struct wl_resource *resource,
&xdg_positioner_impl,
positioner,
HandleResourceDestroy);
RetainPositioner (positioner);
}
void
XLRetainPositioner (Positioner *positioner)
{
RetainPositioner (positioner);
}
void
XLReleasePositioner (Positioner *positioner)
{
ReleasePositioner (positioner);
}
Bool
XLPositionerIsReactive (Positioner *positioner)
{
return positioner->reactive;
}
void

View file

@ -77,7 +77,7 @@ struct _XdgPopup
uint32_t conf_serial, position_serial;
/* The associated positioner. */
Positioner *positioner;
Positioner positioner;
/* Any pending seat on which a grab should be asserted. */
Seat *pending_grab_seat;
@ -138,8 +138,7 @@ DestroyBacking (XdgPopup *popup)
if (popup->pending_callback_key)
XLSeatCancelDestroyListener (popup->pending_callback_key);
/* Release the positioner and free the popup. */
XLReleasePositioner (popup->positioner);
/* Free the popup. */
XLFree (popup);
}
@ -449,7 +448,7 @@ InternalReposition (XdgPopup *popup)
if (!popup->role || !popup->parent)
return;
XLPositionerCalculateGeometry (popup->positioner,
XLPositionerCalculateGeometry (&popup->positioner,
popup->parent, &x, &y,
&width, &height);
@ -664,16 +663,17 @@ Reposition (struct wl_client *client, struct wl_resource *resource,
struct wl_resource *positioner_resource, uint32_t token)
{
XdgPopup *popup;
Positioner *positioner;
popup = wl_resource_get_user_data (resource);
XLReleasePositioner (popup->positioner);
popup->positioner
= wl_resource_get_user_data (positioner_resource);
XLRetainPositioner (popup->positioner);
/* Make sure that the positioner is complete. */
XLCheckPositionerComplete (popup->positioner);
positioner = wl_resource_get_user_data (positioner_resource);
XLCheckPositionerComplete (positioner);
/* Copy the positioner to the popup. */
popup->positioner = *positioner;
popup->positioner.resource = NULL;
xdg_popup_send_repositioned (resource, token);
InternalReposition (popup);
@ -750,7 +750,7 @@ HandleParentConfigure (void *data, XEvent *xevent)
popup = data;
if (XLPositionerIsReactive (popup->positioner))
if (popup->positioner.reactive)
InternalReposition (popup);
}
@ -761,7 +761,7 @@ HandleParentResize (void *data)
popup = data;
if (XLPositionerIsReactive (popup->positioner))
if (popup->positioner.reactive)
InternalReposition (popup);
}
@ -784,11 +784,12 @@ static const struct xdg_popup_interface xdg_popup_impl =
void
XLGetXdgPopup (struct wl_client *client, struct wl_resource *resource,
uint32_t id, struct wl_resource *parent_resource,
struct wl_resource *positioner)
struct wl_resource *positioner_resource)
{
XdgPopup *popup;
Role *role, *parent;
void *key;
Positioner *positioner;
popup = XLSafeMalloc (sizeof *popup);
role = wl_resource_get_user_data (resource);
@ -831,11 +832,19 @@ XLGetXdgPopup (struct wl_client *client, struct wl_resource *resource,
popup->reconstrain_callback_key = key;
}
popup->positioner = wl_resource_get_user_data (positioner);
XLRetainPositioner (popup->positioner);
/* Make sure that the positioner is complete. */
XLCheckPositionerComplete (popup->positioner);
positioner = wl_resource_get_user_data (positioner_resource);
XLCheckPositionerComplete (positioner);
/* Save the positioner into the popup. The spec says:
At the time of the request, the compositor makes a copy of the
rules specified by the xdg_positioner. Thus, after the request
is complete the xdg_positioner object can be destroyed or
reused; further changes to the object will have no effect on
previous usages. */
popup->positioner = *positioner;
popup->positioner.resource = NULL;
wl_resource_set_implementation (popup->resource, &xdg_popup_impl,
popup, HandleResourceDestroy);