Comment 7 for bug 74008

Revision history for this message
In , Davidr-novell (davidr-novell) wrote :

(In reply to comment #3)
> from the bug on bugzilla.g.o:
>
> gnome-screenshot does not assume anything: the window border are included only
> if the "include-border" GConf key is set to TRUE, or command line argument is
> given.
>
> the problem is that the common path used by the include-border option doesn't
> seem to work with compiz, so "include-border" is not honoured.
>
> gnome-screenshot tries to find the current window using the _NET_ACTIVE_WINDOW
> X property and then, if 'include-border' is set to TRUE, it walks back the
> window chain until it finds the window frame.
>
> I don't know why compiz doesn't do the reparenting, and neither understand why
> it can't behave like every other window manager; if compiz authors wish to
> share how gnome-screenshot should fix this misbehaviour, I'm all ears.

The most important reason for why we don't do reparenting is that we don't
necessarily want to use the same visual for the decorations as the client
window. We want to always have an alpha channel present in our decorations but
most client windows use visuals without and alpha channel. If you reparent a
window using a non-ARGB visual into one using an ARGB visual when using the
composite extension to redirect top-level windows, an automatic redirect is
required on the server side to ensure that the alpha bits are correct. This
automatic redirect requires huge memory resources and adds a significant
performance impact. There's some other reasons too, like that it allows us to
compress decorations and save some additional video memory, reparenting also
make the WM code more complex, no reason to do it on a composited desktop so
it's nice to avoid it...

One way to grab a window including the decorations is to look at the
_NET_FRAME_EXTENTS property on the client window. Fetch the client window
geometry, add the frame extents from the _NET_FRAME_EXTENTS property and grab
the root window rectangle that you get from that.

This should work with any EWMH compliant window manager. It wont work with other
window managers that don't support the _NET_FRAME_EXTENTS property so keep the
old frame grabbing code for those cases.

Some additions to the EWMH spec is required if you want to be able to grab the
full contents of a partially covered window. I think it makes a lot of sense to
be able to do this so I could start by implementing a proposed mechanism in
compiz for this. Something like this would work:

- screenshot client sends a client message to wm, telling it that it likes to
acquire a pixmap containing the specific window.
- wm allocates a pixmap of appropriate size and render the window including it's
decorations to it.
- wm sends a client message back to the screenshot client, telling it about the
pixmap which now contains the window.

This mechanism would even be able to capture possible transformations and other
modifications done by the compositing manager to windows.