Fix sending state events while resize is in progress

* xdg_surface.c (SetWindowGeometry, NoteBounds): Allow window
geometry changes even if window didn't resize.
* xdg_toplevel.c (NoteConfigureTime, SendStates): Always use
current toplevel width and height to compute desired window
geometry.
(Map): Remove unused flag.
This commit is contained in:
hujianwei 2022-10-20 10:42:43 +00:00
parent 8d310f9ab3
commit e0e1a6ecb1
2 changed files with 42 additions and 40 deletions

View file

@ -540,6 +540,14 @@ SetWindowGeometry (struct wl_client *client, struct wl_resource *resource,
role->pending_state.window_geometry_y = y; role->pending_state.window_geometry_y = y;
role->pending_state.window_geometry_width = width; role->pending_state.window_geometry_width = width;
role->pending_state.window_geometry_height = height; role->pending_state.window_geometry_height = height;
#ifdef DEBUG_GEOMETRY_CALCULATION
fprintf (stderr, "Client requested geometry: [%d %d %d %d]\n",
role->pending_state.window_geometry_x,
role->pending_state.window_geometry_y,
role->pending_state.window_geometry_width,
role->pending_state.window_geometry_height);
#endif
} }
static void static void
@ -1111,18 +1119,6 @@ NoteBounds (void *data, int min_x, int min_y,
bounds_width, bounds_width,
bounds_height); bounds_height);
if (role->state & StateDirtyFrameExtents)
{
/* Only handle window geometry changes once a commit happens
and the window is really resized. */
if (role->impl->funcs.handle_geometry_change)
role->impl->funcs.handle_geometry_change (&role->role,
role->impl);
role->state &= ~StateDirtyFrameExtents;
}
XResizeWindow (compositor.display, role->window, XResizeWindow (compositor.display, role->window,
bounds_width, bounds_height); bounds_width, bounds_height);
run_reconstrain_callbacks = True; run_reconstrain_callbacks = True;
@ -1134,6 +1130,18 @@ NoteBounds (void *data, int min_x, int min_y,
bounds_height); bounds_height);
} }
if (role->state & StateDirtyFrameExtents)
{
/* Only handle window geometry changes once a commit happens and
the window is really resized. */
if (role->impl->funcs.handle_geometry_change)
role->impl->funcs.handle_geometry_change (&role->role,
role->impl);
role->state &= ~StateDirtyFrameExtents;
}
/* Now, make sure the window stays at the same position relative to /* Now, make sure the window stays at the same position relative to
the origin of the view. */ the origin of the view. */

View file

@ -45,16 +45,15 @@ typedef enum _DecorationMode DecorationMode;
enum enum
{ {
StateIsMapped = 1, StateIsMapped = 1,
StateMissingState = (1 << 1), StatePendingMaxSize = (1 << 1),
StatePendingMaxSize = (1 << 2), StatePendingMinSize = (1 << 2),
StatePendingMinSize = (1 << 3), StatePendingAckMovement = (1 << 3),
StatePendingAckMovement = (1 << 4), StatePendingResize = (1 << 4),
StatePendingResize = (1 << 5), StatePendingConfigureSize = (1 << 5),
StatePendingConfigureSize = (1 << 6), StatePendingConfigureStates = (1 << 6),
StatePendingConfigureStates = (1 << 7), StateDecorationModeDirty = (1 << 7),
StateDecorationModeDirty = (1 << 8), StateEverMapped = (1 << 8),
StateEverMapped = (1 << 9), StateNeedDecorationConfigure = (1 << 9),
StateNeedDecorationConfigure = (1 << 10),
}; };
enum enum
@ -484,12 +483,6 @@ NoteConfigureTime (Timer *timer, void *data, struct timespec time)
/* Send the configure event. */ /* Send the configure event. */
SendConfigure (toplevel, width, height); SendConfigure (toplevel, width, height);
/* Mark the state has having been calculated if some state
transition has occured. */
if (toplevel->toplevel_state.fullscreen
|| toplevel->toplevel_state.maximized)
toplevel->state &= ~StateMissingState;
} }
/* Clear the pending size and state flags. */ /* Clear the pending size and state flags. */
@ -574,20 +567,21 @@ WriteStates (XdgToplevel *toplevel)
static void static void
SendStates (XdgToplevel *toplevel) SendStates (XdgToplevel *toplevel)
{ {
int width, height;
WriteStates (toplevel); WriteStates (toplevel);
/* When SendStates is called, it means the width and height of the /* Adjust the width and height we're sending by the window geometry.
surface did not change. weston-terminal and some other clients toplevel->role->surface should not be NULL here. */
that implement resize increments themselves will keep growing
their toplevels if width and height are specified here, so simply
send 0, 0 to make those clients decide their own size. */
SendConfigure (toplevel, 0, 0);
/* Mark the state has having been calculated if some state TruncateScaleToSurface (toplevel->role->surface,
transition has occured. */ toplevel->width, toplevel->height,
if (toplevel->toplevel_state.fullscreen &width, &height);
|| toplevel->toplevel_state.maximized)
toplevel->state &= ~StateMissingState; XLXdgRoleCalcNewWindowSize (toplevel->role, width,
height, &width, &height);
SendConfigure (toplevel, width, height);
} }
static void static void
@ -1190,7 +1184,7 @@ Map (XdgToplevel *toplevel)
at this point. */ at this point. */
SubcompositorGarbage (XLSubcompositorFromXdgRole (toplevel->role)); SubcompositorGarbage (XLSubcompositorFromXdgRole (toplevel->role));
toplevel->state |= StateIsMapped | StateMissingState | StateEverMapped; toplevel->state |= StateIsMapped | StateEverMapped;
/* Update the width and height from the xdg_surface bounds. */ /* Update the width and height from the xdg_surface bounds. */
toplevel->width = XLXdgRoleGetWidth (toplevel->role); toplevel->width = XLXdgRoleGetWidth (toplevel->role);