I have a game running in the background, but I would like to take screenshots of the window which is not visible. Seems like all the screenshot utilities for X11 need the window to be visible. Is there a way to do this?
How to take a screenshot of an totally obscured window
screenshotx11
Related Solutions
To elaborate a bit on previous answers and comments, the ability to capture a screenshot of a non active window (as in fully or partially hidden) seems to depend on the window manager.
Using the following (already given) command :
import -window <windowid> image.png
or
xwd -id <windowid> | convert xwd:- image.png
(the -
of convert
is for using standard input from the pipe, xwd:
tells the format of the input) one seems to be able under Enlightenment (e17, tested with Fedora 19) to capture a screenshot of :
- fully or partially hidden windows ;
- minimized windows ;
- windows on other workspaces.
I checked with Openbox (same configuration) and KDE (with an old Scientific Linux 4.8 and latest version of ImageMagick
(yes, incredibly it compiled…)) and in both cases screenshots show only what is on top of the display layers — that is, only what is already visible on screen.
The point is that the import
command checks for the map_state
field returned by XGetWindowAttributes
to be IsViewable
, and if not it returns an error. One can check map_state
e.g. using :
xwininfo -id <windowid> | grep 'Map State'
It seems to be always IsViewable
under e17, while it's IsUnMapped
under openbox and KDE as soon as the window is minimized or whatever.
Not sure though why the screenshot is always clean with e17 while it's mixed with other windows when the window is partially recovered with other WMs, but obviously it also has to do with the way the WM handles the display.
Anyway, clearly it's a matter of WM. It would be nice to have a list of WMs able vs unable to do screenshots of hidden windows — I'm not doing it.
As far as I know (but I'm no X expert), visibility is only tracked through VisibilityNotify
events, it isn't a state that you can query like IsViewable
. You'd need to get KDE to spit it out, I don't know if it can do that.
You may be solve your problem by sending the window a VisibilityNotify(state=VisibilityUnobscured)
event. I don't know if that's enough, you may also need to send a MapNotify
event. Here's some untested Python code to send a VisibilityNotify
event.
#! /usr/bin/env python
import re, sys, time
import Xlib.X, Xlib.XK, Xlib.display, Xlib.protocol
def parse_action(string):
state = {
'0': 0,
'1': 1,
'2': 2,
'unobscured': 0,
'partiallyobscured': 1,
'fullyobscured': 2,
'visibilityunobscured': 0,
'visibilitypartiallyobscured': 1,
'visibilityfullyobscured': 2,
}[string.lower()]
return state
def parse_window(display, arg):
wid = int(arg, 0)
return display.create_resource_object('window', wid)
def send_event(display, window, state):
window.send_event(Xlib.protocol.event.VisibilityNotify(window=window,
state=state))
display.sync()
if __name__ == "__main__":
display = Xlib.display.Display()
send_event(display, parse_window(display, sys.argv[1]), parse_action(sys.argv[2]))
Best Answer
It's probably the fault of the game, not the fault of the screenshot utility. X11 sends applications a VisibilityNotify event to tell them that their window is fully visible, partially obscured or totally obscured. When the window is totally obscured, most applications don't bother updating their display, which saves resources. In other words, if nobody is there to see it, the tree doesn't fall.
I think that if you send the game window a VisibilityNotify event to pretend that it's visible, then you'll get your screenshot. You'll need to send the event after the window becomes obscured, since X11 itself will send its normal event at that time. Here's an untested script that sends a VisibilityNotify event, call it with the argument
VisibilityPartiallyObscured
orVisibilityUnobscured
. I follow with aMapNotify
event, I don't know if it's useful. You need Python and Python-xlib.