如何截取完全被遮挡的窗口的屏幕截图

mar*_*ara 7 x11 screenshot

我有一个在后台运行的游戏,但我想对不可见的窗口进行截图。似乎 X11 的所有屏幕截图实用程序都需要窗口可见。有没有办法做到这一点?

Gil*_*il' 6

这可能是游戏的错,而不是截图工具的错。X11 向应用程序发送VisibilityNotify事件以告诉他们他们的窗口是完全可见的、部分被遮挡的或完全被遮挡的。当窗口完全被遮挡时,大多数应用程序不会更新它们的显示,从而节省资源。换句话说,如果没有人在那里看到它,树就不会倒下。

我认为如果您向游戏窗口发送 VisibilityNotify 事件以假装它是可见的,那么您将获得屏幕截图。您需要在窗口变得模糊后发送事件,因为此时 X11 本身将发送其正常事件。是一个未经测试的脚本,它发送一个 VisibilityNotify 事件,用参数VisibilityPartiallyObscuredor调用它VisibilityUnobscured。我关注了一个MapNotify活动,不知道有没有用。你需要 Python 和 Python-xlib。

#! /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))
    window.send_event(Xlib.protocol.event.MapNotify(window=window,
                                                    event=window,
                                                    override=False))
    display.sync()

if __name__ == "__main__":
    display = Xlib.display.Display()
    send_event(display, parse_window(display, sys.argv[1]), parse_action(sys.argv[2]))
Run Code Online (Sandbox Code Playgroud)