Window stacking / raising design
ppaalanen at gmail.com
Wed Jan 18 01:50:59 PST 2012
On Tue, 17 Jan 2012 10:36:03 -0800
Bill Spitzak <spitzak at gmail.com> wrote:
> On 01/17/2012 02:32 AM, Pekka Paalanen wrote:
> > I think we already have the unmapped feature. In Wayland terms:
> > 1. A client creates a surface.
> > The surface is initially unmapped, and not visible.
> > 2. The client sets the window type (role) of the surface.
> > Still nothing visible happens.
> > 3. The client creates a buffer in certain size.
> > This is the pixel storage, for now unrelated to the surface.
> > 4. The client renders into the buffer.
> > 5. The client attaches the buffer into the surface.
> > This step is where all the work in the compositor happens. If
> > the surface was unmapped, it becomes mapped. The buffer size
> > sets the surface size (possible scalings taken into account),
> > and the surface becomes visible.
> > This is an example, you could do 3,4 first, then 1,2, then 5.
> > The raise could happen between 2 and 5.
> The problem I am trying to solve is where there already is a window W on
> the screen, and raising it also has to map a dialog box B that should be
> above it.
> If the portion of W that will be obscured by B is currently obscured by
> some other window, then the user will see a "flash" of that window when
> it is raised before B is mapped. This is IMHO unacceptable for Wayland.
Are you making some assumptions on the compositing behaviour here,
since I do not really understand the problem?
Unmapped surfaces never occlude anything, since they are invisible. In
your case, if you first raise W, then map B, you might see a full W,
and then B appearing on top of it. No any other surface content can
flash inside W. Is the temporary showing of full W before B appears
on top a problem?
Since we do not have a separate 'map' request, we do not have the "a
window with no content" problem of X, either. There is no way to make a
surface visible without the full contents given by a client first. The
contents are also stored on server side, until new contents arrive, or
the surface (and the buffer) are destroyed. Therefore we can always
draw the full surface, if we wish, without client cooperation.
Also for now, occlusions and damage regions are a purely server internal
optimization. Clients are always required to attach fully rendered
buffers, even if the change is only a tiny part. Clients can tell the
server which parts of the new buffer are different to the old one, but
that is only advisory.
> I agree that the current Wayland idea of equating "a buffer is attached"
> with "mapped" is really nice, which is why I don't like adding a mapped
> state to windows. But your idea means that it may not be necessary:
> > Maybe we could use this scheme in a wider sense: all changes to window
> > state are cached in the compositor, and applied on the next buffer
> > attach. That is what I already proposed for the fullscreen case. I'm not
> > sure how it would fit with your multi-surface raise request, though.
> That would work. If a raise names an unattached window, the raise is
> deferred until that window is attached to a buffer.
Sounds doable. Btw. what you call a window, we call a surface.
> This would actually make your fullscreen results better, for windows
> with dialog boxes, and remove the need for my idea of putting panels
> below normal windows:
> 1. Client sends request for fullsize for window W
> 2. Compositor sends configure notify for fullscreen window size
> 3. Client makes new buffer and draws it for this full size
> 4. Client sends raise request for W and dialog box B. But this is
> deferred due to the outstanding configure notify. (If the client does
> not send a raise, the compositor can pretend it sent one only for the
> fullscreen window W)
I would say "deferred by waiting for a buffer attach to W". We cannot
explicitly depend on configure notifys, since a client is allowed to
ignore all configure notifys except "the last one".
> 5. Client attaches W. At this point, atomically, W is raised above the
> panel and other windows and resized and B is put atop it.
I wonder, how does it work, if a client has several mapped surfaces,
and wants to rearrange them all by raise. On which buffer attach would
we execute the raise?
> I now think unmapping is not a problem so it would not have to be part
> of the raise command. Instead the client just does not put the unmapped
> windows in the raise command, and it unmaps the windows *after* the
> raise command is completed. This will not cause any "blink" because no
> portion of these windows that is unexposed will become exposed (to be
> really perfect the client needs to unmap them in back to front order)
Currently, unmapping is done by destroying the surface, since we have
no protocol to hide a surface. Hmm, to think of it, I'm not sure what
happens, if you try to attach a NULL buffer to a surface, maybe we just
don't handle that.
I agree on back-to-front, if we have no guarantees on request
More information about the wayland-devel