"""X11 title fixtures for an isolated Xvfb session; no accessible toolkit.""" import json import sys from Xlib import X, Xatom, display def main(): connection = display.Display() root = connection.screen().root utf8 = connection.intern_atom("UTF8_STRING") nameAtom = connection.intern_atom("_NET_WM_NAME") activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") def make_window(parent, title, application="example"): window = parent.create_window(0, 0, 250, 150, 0, connection.screen().root_depth, X.InputOutput, X.CopyFromParent) if title: window.set_wm_name(title) window.change_property(nameAtom, utf8, 8, title.encode("utf-8")) window.set_wm_class(application, application) window.map() return window normal = make_window(root, "Example title") desktop = make_window(root, "Wine Desktop") helper = make_window(desktop, "NVDA", "wine-access.exe") oldHelper = make_window(desktop, "NVDA", "cthulhu-wine-access.exe") ime = make_window(desktop, "Default IME") hidden = make_window(desktop, "Hidden game", "hidden.exe") hidden.unmap() game = make_window(desktop, "Wine game", "game.exe") control = make_window(game, "") second = make_window(desktop, "Wine dialog", "game.exe") unrelated = make_window(root, "Unrelated title") windows = dict(normal=normal, desktop=desktop, helper=helper, oldHelper=oldHelper, ime=ime, hidden=hidden, game=game, control=control, second=second, unrelated=unrelated) root.change_property(activeAtom, Xatom.WINDOW, 32, [normal.id]) normal.set_input_focus(X.RevertToParent, X.CurrentTime) connection.sync() print(json.dumps({key: window.id for key, window in windows.items()}), flush=True) for line in sys.stdin: command = json.loads(line) window = windows[command["window"]] action = command["action"] if action == "activate": root.change_property(activeAtom, Xatom.WINDOW, 32, [window.id]) window.set_input_focus(X.RevertToParent, X.CurrentTime) elif action == "focus": window.set_input_focus(X.RevertToParent, X.CurrentTime) elif action == "title": window.change_property(nameAtom, utf8, 8, command["title"].encode("utf-8")) elif action == "legacy": window.delete_property(nameAtom) window.set_wm_name(command["title"]) elif action == "class": window.set_wm_class(command["instance"], command["class"]) elif action == "hide": window.unmap() elif action == "destroy": window.destroy() connection.sync() print("ready", flush=True) connection.close() if __name__ == "__main__": main()