Fix built-in resize with new frame clock logic

* compositor.h (struct _XdgRoleImplementationFuncs): Replace
`commit_inside_frame' with `after_commit'.
* xdg_surface.c (Commit): Call after_commit hook.
(NoteFrame): Stop calling commit_inside_frame.

* xdg_toplevel.c (CommitInsideFrame): Remove function.
(AfterCommit): New function.  Post pending resize here instead.
(XLGetXdgToplevel): Attach after_commit hook.
This commit is contained in:
hujianwei 2022-11-14 01:42:01 +00:00
parent ecac908923
commit a3e87a1f34
3 changed files with 47 additions and 34 deletions

View file

@ -1336,10 +1336,10 @@ struct _XdgRoleImplementationFuncs
void (*note_window_resized) (Role *, XdgRoleImplementation *, int, int); void (*note_window_resized) (Role *, XdgRoleImplementation *, int, int);
void (*handle_geometry_change) (Role *, XdgRoleImplementation *); void (*handle_geometry_change) (Role *, XdgRoleImplementation *);
void (*post_resize) (Role *, XdgRoleImplementation *, int, int, int, int); void (*post_resize) (Role *, XdgRoleImplementation *, int, int, int, int);
void (*commit_inside_frame) (Role *, XdgRoleImplementation *);
Bool (*is_window_mapped) (Role *, XdgRoleImplementation *); Bool (*is_window_mapped) (Role *, XdgRoleImplementation *);
void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode); void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode);
void (*outputs_changed) (Role *, XdgRoleImplementation *); void (*outputs_changed) (Role *, XdgRoleImplementation *);
void (*after_commit) (Role *, Surface *, XdgRoleImplementation *);
}; };
struct _XdgRoleImplementation struct _XdgRoleImplementation

View file

@ -665,7 +665,7 @@ Commit (Surface *surface, Role *role)
if (!CheckFrame (xdg_role)) if (!CheckFrame (xdg_role))
/* The frame cannot be drawn, because the compositor has not yet /* The frame cannot be drawn, because the compositor has not yet
drawn a previous frame. */ drawn a previous frame. */
return; goto after_commit;
/* The frame can be drawn, so update the window contents now. */ /* The frame can be drawn, so update the window contents now. */
SubcompositorUpdate (xdg_role->subcompositor); SubcompositorUpdate (xdg_role->subcompositor);
@ -673,6 +673,15 @@ Commit (Surface *surface, Role *role)
/* Do not end frames explicitly. Instead, wait for the /* Do not end frames explicitly. Instead, wait for the
NoteFrameCallback to end the frame. */ NoteFrameCallback to end the frame. */
after_commit:
/* Run the after_commit function of the role implementation, which
peforms actions such as posting pending configure events for
built-in resize. */
if (xdg_role->impl->funcs.after_commit)
xdg_role->impl->funcs.after_commit (role, surface,
xdg_role->impl);
return; return;
} }
@ -1183,10 +1192,6 @@ NoteFrame (FrameMode mode, uint64_t id, void *data)
role->state |= StateFrameStarted; role->state |= StateFrameStarted;
} }
/* Also run role "commit inside frame" hook. */
if (role->impl && role->impl->funcs.commit_inside_frame)
role->impl->funcs.commit_inside_frame (&role->role,
role->impl);
break; break;
case ModeNotifyDisablePresent: case ModeNotifyDisablePresent:

View file

@ -1241,6 +1241,9 @@ SendOutputBounds (XdgToplevel *toplevel)
y_max - y_min + 1); y_max - y_min + 1);
} }
/* Forward declaration. */
static void PostResize1 (XdgToplevel *, int, int, int, int);
static void static void
Commit (Role *role, Surface *surface, XdgRoleImplementation *impl) Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
{ {
@ -1318,6 +1321,38 @@ Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
} }
} }
static void
AfterCommit (Role *role, Surface *surface, XdgRoleImplementation *impl)
{
XdgToplevel *toplevel;
toplevel = ToplevelFromRoleImpl (impl);
/* Apply any pending movement if there is. This must come after
Commit is called: otherwise, any pending movement will cause any
future configure event to be called before NoteBounds, which
causes window resize to be constantly postponed. */
if (!toplevel->conf_reply
&& toplevel->state & StatePendingAckMovement)
{
XLXdgRoleMoveBy (role, toplevel->ack_west,
toplevel->ack_north);
toplevel->ack_west = 0;
toplevel->ack_north = 0;
toplevel->state &= ~StatePendingAckMovement;
/* This pending movement has completed. Apply postponed state,
if there is any. */
if (toplevel->state & StatePendingResize)
PostResize1 (toplevel, toplevel->resize_west,
toplevel->resize_north,
toplevel->resize_width,
toplevel->resize_height);
}
}
static void static void
PostResize1 (XdgToplevel *toplevel, int west_motion, int north_motion, PostResize1 (XdgToplevel *toplevel, int west_motion, int north_motion,
int new_width, int new_height) int new_width, int new_height)
@ -1379,33 +1414,6 @@ PostResize1 (XdgToplevel *toplevel, int west_motion, int north_motion,
} }
} }
static void
CommitInsideFrame (Role *role, XdgRoleImplementation *impl)
{
XdgToplevel *toplevel;
toplevel = ToplevelFromRoleImpl (impl);
if (!toplevel->conf_reply
&& toplevel->state & StatePendingAckMovement)
{
XLXdgRoleMoveBy (role, toplevel->ack_west,
toplevel->ack_north);
toplevel->ack_west = 0;
toplevel->ack_north = 0;
toplevel->state &= ~StatePendingAckMovement;
/* This pending movement has completed. Apply postponed state,
if there is any. */
if (toplevel->state & StatePendingResize)
PostResize1 (toplevel, toplevel->resize_west,
toplevel->resize_north,
toplevel->resize_width,
toplevel->resize_height);
}
}
static Bool static Bool
RestoreStateTo (XdgToplevel *toplevel, int width, int height) RestoreStateTo (XdgToplevel *toplevel, int width, int height)
{ {
@ -2308,9 +2316,9 @@ XLGetXdgToplevel (struct wl_client *client, struct wl_resource *resource,
toplevel->impl.funcs.note_window_pre_resize = NoteWindowPreResize; toplevel->impl.funcs.note_window_pre_resize = NoteWindowPreResize;
toplevel->impl.funcs.handle_geometry_change = HandleGeometryChange; toplevel->impl.funcs.handle_geometry_change = HandleGeometryChange;
toplevel->impl.funcs.post_resize = PostResize; toplevel->impl.funcs.post_resize = PostResize;
toplevel->impl.funcs.commit_inside_frame = CommitInsideFrame;
toplevel->impl.funcs.is_window_mapped = IsWindowMapped; toplevel->impl.funcs.is_window_mapped = IsWindowMapped;
toplevel->impl.funcs.outputs_changed = OutputsChanged; toplevel->impl.funcs.outputs_changed = OutputsChanged;
toplevel->impl.funcs.after_commit = AfterCommit;
if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED)) if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED))
/* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing /* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing