mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 12:52:14 +00:00
wayland/xdg-shell: Defer meta_wayland_xdg_positioner_to_placement call
From xdg_surface_constructor_get_popup / xdg_popup_reposition (called during Wayland protocol processing) to finish_popup_setup / meta_wayland_xdg_popup_apply_state (called when the popup state is applied). This makes sure that the parent window frame rectangle is up to date in meta_wayland_xdg_positioner_to_placement. v2: * Use meta_wayland_surface_state_new () in meta_wayland_transaction_add_xdg_popup_reposition. v3: * Move xdg_popup_repositioned handling to meta_wayland_xdg_popup_apply_state. v4: * Do not steal pending->xdg_positioner in meta_wayland_xdg_popup_apply_state, fixes leaking the corresponding memory. * Drop MetaWaylandSurfaceState::xdg_popup_repositioned, just use ::xdg_positioner. v5: * Reformat meta_wayland_xdg_positioner_to_placement calls to stay within 80 columns. (Jonas Ådahl) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
parent
6c3879766d
commit
b7599fb766
@ -502,6 +502,8 @@ meta_wayland_surface_state_set_default (MetaWaylandSurfaceState *state)
|
||||
state->subsurface_placement_ops = NULL;
|
||||
|
||||
wl_list_init (&state->presentation_feedback_list);
|
||||
|
||||
state->xdg_popup_reposition_token = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -527,6 +529,7 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
|
||||
g_clear_pointer (&state->buffer_damage, cairo_region_destroy);
|
||||
g_clear_pointer (&state->input_region, cairo_region_destroy);
|
||||
g_clear_pointer (&state->opaque_region, cairo_region_destroy);
|
||||
g_clear_pointer (&state->xdg_positioner, g_free);
|
||||
|
||||
if (state->buffer)
|
||||
g_clear_signal_handler (&state->buffer_destroy_handler_id, state->buffer);
|
||||
@ -675,6 +678,13 @@ meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
|
||||
wl_list_insert_list (&to->presentation_feedback_list,
|
||||
&from->presentation_feedback_list);
|
||||
wl_list_init (&from->presentation_feedback_list);
|
||||
|
||||
if (from->xdg_positioner)
|
||||
{
|
||||
g_clear_pointer (&to->xdg_positioner, g_free);
|
||||
to->xdg_positioner = g_steal_pointer (&from->xdg_positioner);
|
||||
to->xdg_popup_reposition_token = from->xdg_popup_reposition_token;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -133,6 +133,10 @@ struct _MetaWaylandSurfaceState
|
||||
struct {
|
||||
gboolean surface_size_changed;
|
||||
} derived;
|
||||
|
||||
/* xdg_popup */
|
||||
MetaWaylandXdgPositioner *xdg_positioner;
|
||||
uint32_t xdg_popup_reposition_token;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDragDestFuncs
|
||||
|
@ -386,6 +386,27 @@ meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transa
|
||||
entry->has_sub_pos = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_transaction_add_xdg_popup_reposition (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface,
|
||||
void *xdg_positioner,
|
||||
uint32_t token)
|
||||
{
|
||||
MetaWaylandTransactionEntry *entry;
|
||||
MetaWaylandSurfaceState *state;
|
||||
|
||||
entry = meta_wayland_transaction_ensure_entry (transaction, surface);
|
||||
|
||||
if (entry->state)
|
||||
g_clear_pointer (&entry->state->xdg_positioner, g_free);
|
||||
else
|
||||
entry->state = meta_wayland_surface_state_new ();
|
||||
|
||||
state = entry->state;
|
||||
state->xdg_positioner = xdg_positioner;
|
||||
state->xdg_popup_reposition_token = token;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_transaction_entry_merge_into (MetaWaylandTransactionEntry *from,
|
||||
MetaWaylandTransactionEntry *to)
|
||||
|
@ -37,6 +37,11 @@ void meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *t
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_wayland_transaction_add_xdg_popup_reposition (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface,
|
||||
void *xdg_positioner,
|
||||
uint32_t token);
|
||||
|
||||
void meta_wayland_transaction_merge_into (MetaWaylandTransaction *from,
|
||||
MetaWaylandTransaction *to);
|
||||
|
||||
|
@ -67,6 +67,8 @@ typedef struct _MetaWaylandActivation MetaWaylandActivation;
|
||||
|
||||
typedef struct _MetaWaylandDmaBufManager MetaWaylandDmaBufManager;
|
||||
|
||||
typedef struct _MetaWaylandXdgPositioner MetaWaylandXdgPositioner;
|
||||
|
||||
typedef struct _MetaXWaylandManager MetaXWaylandManager;
|
||||
|
||||
#endif
|
||||
|
@ -57,7 +57,7 @@ typedef struct _MetaWaylandXdgShellClient
|
||||
GList *surface_constructors;
|
||||
} MetaWaylandXdgShellClient;
|
||||
|
||||
typedef struct _MetaWaylandXdgPositioner
|
||||
struct _MetaWaylandXdgPositioner
|
||||
{
|
||||
MetaRectangle anchor_rect;
|
||||
int32_t width;
|
||||
@ -76,7 +76,7 @@ typedef struct _MetaWaylandXdgPositioner
|
||||
|
||||
gboolean acked_parent_configure;
|
||||
uint32_t parent_configure_serial;
|
||||
} MetaWaylandXdgPositioner;
|
||||
};
|
||||
|
||||
typedef struct _MetaWaylandXdgSurfaceConstructor
|
||||
{
|
||||
@ -130,11 +130,7 @@ struct _MetaWaylandXdgPopup
|
||||
struct {
|
||||
MetaWaylandSurface *parent_surface;
|
||||
|
||||
/*
|
||||
* The coordinates/dimensions in the placement rule are in logical pixel
|
||||
* coordinate space, i.e. not scaled given what monitor the popup is on.
|
||||
*/
|
||||
MetaPlacementRule placement_rule;
|
||||
MetaWaylandXdgPositioner xdg_positioner;
|
||||
|
||||
MetaWaylandSeat *grab_seat;
|
||||
uint32_t grab_serial;
|
||||
@ -623,27 +619,17 @@ xdg_popup_reposition (struct wl_client *client,
|
||||
META_WAYLAND_SURFACE_ROLE (xdg_popup);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaWindow *parent_window;
|
||||
MetaWaylandXdgPositioner *xdg_positioner;
|
||||
MetaPlacementRule placement_rule;
|
||||
MetaWaylandTransaction *transaction;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
xdg_positioner = g_memdup2 (wl_resource_get_user_data (positioner_resource),
|
||||
sizeof (MetaWaylandXdgPositioner));
|
||||
|
||||
parent_window = meta_wayland_surface_get_window (xdg_popup->parent_surface);
|
||||
|
||||
xdg_positioner = wl_resource_get_user_data (positioner_resource);
|
||||
placement_rule = meta_wayland_xdg_positioner_to_placement (xdg_positioner,
|
||||
parent_window);
|
||||
|
||||
xdg_popup->pending_reposition_token = token;
|
||||
xdg_popup->pending_repositioned = TRUE;
|
||||
|
||||
scale_placement_rule (&placement_rule, surface);
|
||||
|
||||
meta_window_update_placement_rule (window, &placement_rule);
|
||||
transaction = meta_wayland_transaction_new (surface->compositor);
|
||||
meta_wayland_transaction_add_xdg_popup_reposition (transaction, surface,
|
||||
xdg_positioner, token);
|
||||
meta_wayland_transaction_ensure_entry (transaction, xdg_popup->parent_surface);
|
||||
meta_wayland_transaction_commit (transaction);
|
||||
}
|
||||
|
||||
static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = {
|
||||
@ -1080,6 +1066,8 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
uint32_t serial;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaWindow *window;
|
||||
MetaWindow *parent_window;
|
||||
MetaPlacementRule placement_rule;
|
||||
|
||||
parent_surface = xdg_popup->setup.parent_surface;
|
||||
seat = xdg_popup->setup.grab_seat;
|
||||
@ -1124,7 +1112,11 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
window = meta_window_wayland_new (display, surface);
|
||||
meta_wayland_shell_surface_set_window (shell_surface, window);
|
||||
|
||||
meta_wayland_xdg_popup_place (xdg_popup, &xdg_popup->setup.placement_rule);
|
||||
parent_window = meta_wayland_surface_get_window (parent_surface);
|
||||
placement_rule =
|
||||
meta_wayland_xdg_positioner_to_placement (&xdg_popup->setup.xdg_positioner,
|
||||
parent_window);
|
||||
meta_wayland_xdg_popup_place (xdg_popup, &placement_rule);
|
||||
|
||||
if (seat)
|
||||
{
|
||||
@ -1219,6 +1211,25 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
if (xdg_popup->setup.parent_surface)
|
||||
finish_popup_setup (xdg_popup);
|
||||
|
||||
if (pending->xdg_positioner)
|
||||
{
|
||||
MetaWindow *window, *parent_window;
|
||||
MetaPlacementRule placement_rule;
|
||||
|
||||
parent_window = meta_wayland_surface_get_window (xdg_popup->parent_surface);
|
||||
placement_rule =
|
||||
meta_wayland_xdg_positioner_to_placement (pending->xdg_positioner,
|
||||
parent_window);
|
||||
|
||||
xdg_popup->pending_reposition_token = pending->xdg_popup_reposition_token;
|
||||
xdg_popup->pending_repositioned = TRUE;
|
||||
|
||||
scale_placement_rule (&placement_rule, surface);
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
meta_window_update_placement_rule (window, &placement_rule);
|
||||
}
|
||||
|
||||
if (!surface->buffer_ref->buffer && xdg_surface_priv->first_buffer_attached)
|
||||
{
|
||||
meta_wayland_xdg_surface_reset (xdg_surface);
|
||||
@ -2040,8 +2051,7 @@ xdg_surface_constructor_get_popup (struct wl_client *client,
|
||||
meta_wayland_xdg_surface_constructor_finalize (constructor, xdg_surface);
|
||||
|
||||
xdg_positioner = wl_resource_get_user_data (positioner_resource);
|
||||
xdg_popup->setup.placement_rule =
|
||||
meta_wayland_xdg_positioner_to_placement (xdg_positioner, parent_window);
|
||||
xdg_popup->setup.xdg_positioner = *xdg_positioner;
|
||||
xdg_popup->setup.parent_surface = parent_surface;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user