forked from 12to11/12to11
Fix problems seen with some programs in the wild
* subcompositor.c (ViewAttachBuffer): Correctly determine when to recompute view bounds. * subsurface.c (AfterParentCommit): Unskip view first, and commit pending state second. Explain why. * xdg_toplevel.c (Unmap, Map): Add new "initial configure" flag. (Commit): Use it instead of testing current_buffer. Explain why. (XLGetXdgToplevel): Set that flag by default.
This commit is contained in:
parent
0c3e5a0e7d
commit
da212fe729
3 changed files with 38 additions and 19 deletions
|
@ -1472,12 +1472,14 @@ ViewAttachBuffer (View *view, ExtBuffer *buffer)
|
||||||
if (!view->buffer && old && view->subcompositor)
|
if (!view->buffer && old && view->subcompositor)
|
||||||
/* The view needs a size update, as it is now 0 by 0. */
|
/* The view needs a size update, as it is now 0 by 0. */
|
||||||
ViewAfterSizeUpdate (view);
|
ViewAfterSizeUpdate (view);
|
||||||
else if (((buffer && !old)
|
else if ((buffer && !old)
|
||||||
|| (old && !buffer)
|
|| (old && !buffer)
|
||||||
|| (buffer && old
|
|| (buffer && old
|
||||||
&& (XLBufferWidth (buffer) != XLBufferWidth (old)
|
&& (XLBufferWidth (buffer) != XLBufferWidth (old)
|
||||||
|| XLBufferHeight (buffer) != XLBufferHeight (old))))
|
|| XLBufferHeight (buffer) != XLBufferHeight (old))
|
||||||
&& !IsViewported (view))
|
/* Buffer width and height changes don't matter if the
|
||||||
|
view has a viewport. */
|
||||||
|
&& !IsViewported (view)))
|
||||||
/* Recompute view and subcompositor bounds. */
|
/* Recompute view and subcompositor bounds. */
|
||||||
ViewAfterSizeUpdate (view);
|
ViewAfterSizeUpdate (view);
|
||||||
|
|
||||||
|
|
11
subsurface.c
11
subsurface.c
|
@ -600,6 +600,13 @@ AfterParentCommit (Surface *surface, void *data)
|
||||||
MoveFractional (subsurface);
|
MoveFractional (subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the subsurface as unskipped. (IOW, make it visible). This
|
||||||
|
must come before XLCommitSurface, as doing so will apply the
|
||||||
|
pending state, which will fail to update the subcompositor bounds
|
||||||
|
if the subsurface is skipped. */
|
||||||
|
ViewUnskip (subsurface->role.surface->view);
|
||||||
|
ViewUnskip (subsurface->role.surface->under);
|
||||||
|
|
||||||
/* And any cached surface state too. */
|
/* And any cached surface state too. */
|
||||||
if (subsurface->pending_commit)
|
if (subsurface->pending_commit)
|
||||||
{
|
{
|
||||||
|
@ -610,10 +617,6 @@ AfterParentCommit (Surface *surface, void *data)
|
||||||
MaybeUpdateOutputs (subsurface);
|
MaybeUpdateOutputs (subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the subsurface as unskipped. (IOW, make it visible). */
|
|
||||||
ViewUnskip (subsurface->role.surface->view);
|
|
||||||
ViewUnskip (subsurface->role.surface->under);
|
|
||||||
|
|
||||||
subsurface->pending_commit = False;
|
subsurface->pending_commit = False;
|
||||||
subsurface->pending_substate.flags = 0;
|
subsurface->pending_substate.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum
|
||||||
StateDecorationModeDirty = (1 << 7),
|
StateDecorationModeDirty = (1 << 7),
|
||||||
StateEverMapped = (1 << 8),
|
StateEverMapped = (1 << 8),
|
||||||
StateNeedDecorationConfigure = (1 << 9),
|
StateNeedDecorationConfigure = (1 << 9),
|
||||||
|
StateWaitingForInitialConfigure = (1 << 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -1164,7 +1165,7 @@ Unmap (XdgToplevel *toplevel)
|
||||||
|
|
||||||
/* Clear all the state. */
|
/* Clear all the state. */
|
||||||
|
|
||||||
toplevel->state = 0;
|
toplevel->state = StateWaitingForInitialConfigure;
|
||||||
toplevel->conf_reply = False;
|
toplevel->conf_reply = False;
|
||||||
toplevel->conf_serial = 0;
|
toplevel->conf_serial = 0;
|
||||||
toplevel->states.size = 0;
|
toplevel->states.size = 0;
|
||||||
|
@ -1204,6 +1205,7 @@ Map (XdgToplevel *toplevel)
|
||||||
SubcompositorGarbage (XLSubcompositorFromXdgRole (toplevel->role));
|
SubcompositorGarbage (XLSubcompositorFromXdgRole (toplevel->role));
|
||||||
|
|
||||||
toplevel->state |= StateIsMapped | StateEverMapped;
|
toplevel->state |= StateIsMapped | StateEverMapped;
|
||||||
|
toplevel->state &= ~StateWaitingForInitialConfigure;
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -1268,8 +1270,16 @@ Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
|
||||||
toplevel->state &= ~StatePendingMinSize;
|
toplevel->state &= ~StatePendingMinSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface->current_state.buffer)
|
if (!surface->current_state.buffer
|
||||||
|
/* Whenever any commit happens without the toplevel being
|
||||||
|
mapped, send the initial configure event. This is because
|
||||||
|
some clients attach an initial 1x1 buffer and expect the
|
||||||
|
compositor to do its thing. */
|
||||||
|
|| (toplevel->state & StateWaitingForInitialConfigure))
|
||||||
{
|
{
|
||||||
|
/* Stop waiting for initial configure. */
|
||||||
|
toplevel->state &= ~StateWaitingForInitialConfigure;
|
||||||
|
|
||||||
/* No buffer was attached, unmap the window and send an empty
|
/* No buffer was attached, unmap the window and send an empty
|
||||||
configure event. */
|
configure event. */
|
||||||
if (toplevel->state & StateIsMapped)
|
if (toplevel->state & StateIsMapped)
|
||||||
|
@ -2282,6 +2292,10 @@ XLGetXdgToplevel (struct wl_client *client, struct wl_resource *resource,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set this flag for some buggy clients. See the comment above the
|
||||||
|
part of Commit that checks this flag for more details. */
|
||||||
|
toplevel->state |= StateWaitingForInitialConfigure;
|
||||||
|
|
||||||
toplevel->impl.funcs.attach = Attach;
|
toplevel->impl.funcs.attach = Attach;
|
||||||
toplevel->impl.funcs.commit = Commit;
|
toplevel->impl.funcs.commit = Commit;
|
||||||
toplevel->impl.funcs.detach = Detach;
|
toplevel->impl.funcs.detach = Detach;
|
||||||
|
|
Loading…
Add table
Reference in a new issue