diff --git a/compositor.h b/compositor.h index 507e675..bc4340f 100644 --- a/compositor.h +++ b/compositor.h @@ -1336,10 +1336,10 @@ struct _XdgRoleImplementationFuncs void (*note_window_resized) (Role *, XdgRoleImplementation *, int, int); void (*handle_geometry_change) (Role *, XdgRoleImplementation *); void (*post_resize) (Role *, XdgRoleImplementation *, int, int, int, int); - void (*commit_inside_frame) (Role *, XdgRoleImplementation *); Bool (*is_window_mapped) (Role *, XdgRoleImplementation *); void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode); void (*outputs_changed) (Role *, XdgRoleImplementation *); + void (*after_commit) (Role *, Surface *, XdgRoleImplementation *); }; struct _XdgRoleImplementation diff --git a/xdg_surface.c b/xdg_surface.c index 7717778..ca22c22 100644 --- a/xdg_surface.c +++ b/xdg_surface.c @@ -665,7 +665,7 @@ Commit (Surface *surface, Role *role) if (!CheckFrame (xdg_role)) /* The frame cannot be drawn, because the compositor has not yet drawn a previous frame. */ - return; + goto after_commit; /* The frame can be drawn, so update the window contents now. */ SubcompositorUpdate (xdg_role->subcompositor); @@ -673,6 +673,15 @@ Commit (Surface *surface, Role *role) /* Do not end frames explicitly. Instead, wait for the 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; } @@ -1183,10 +1192,6 @@ NoteFrame (FrameMode mode, uint64_t id, void *data) 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; case ModeNotifyDisablePresent: diff --git a/xdg_toplevel.c b/xdg_toplevel.c index 54351b4..fc9a1a1 100644 --- a/xdg_toplevel.c +++ b/xdg_toplevel.c @@ -1241,6 +1241,9 @@ SendOutputBounds (XdgToplevel *toplevel) y_max - y_min + 1); } +/* Forward declaration. */ +static void PostResize1 (XdgToplevel *, int, int, int, int); + static void 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 PostResize1 (XdgToplevel *toplevel, int west_motion, int north_motion, 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 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.handle_geometry_change = HandleGeometryChange; toplevel->impl.funcs.post_resize = PostResize; - toplevel->impl.funcs.commit_inside_frame = CommitInsideFrame; toplevel->impl.funcs.is_window_mapped = IsWindowMapped; toplevel->impl.funcs.outputs_changed = OutputsChanged; + toplevel->impl.funcs.after_commit = AfterCommit; if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED)) /* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing