"""Window-group and transient-popup fixtures for private X11 focus tests.""" import json import os import sys from Xlib import X, Xatom, display connection = display.Display() root = connection.screen().root leaderAtom = connection.intern_atom("WM_CLIENT_LEADER") pidAtom = connection.intern_atom("_NET_WM_PID") typeAtom = connection.intern_atom("_NET_WM_WINDOW_TYPE") activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") def make_window(parent, x, y, width, height, inputOnly=False, override=False): window = parent.create_window( x, y, width, height, 0, 0 if inputOnly else connection.screen().root_depth, X.InputOnly if inputOnly else X.InputOutput, X.CopyFromParent, override_redirect=override, ) window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) return window leader = make_window(root, 0, 0, 1, 1, inputOnly=True) owner = make_window(root, 20, 30, 600, 400) grab = make_window(root, -100, -100, 10, 10, inputOnly=True, override=True) popup = make_window(root, 40, 60, 200, 80, override=True) other = make_window(root, 700, 30, 100, 100) for window in [owner, grab, popup]: window.change_property(leaderAtom, Xatom.WINDOW, 32, [leader.id]) owner.map() other.map() def configure(action): root.delete_property(activeAtom) popup.change_property(leaderAtom, Xatom.WINDOW, 32, [leader.id]) popup.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) popup.change_property(typeAtom, Xatom.ATOM, 32, [connection.intern_atom("_NET_WM_WINDOW_TYPE_COMBO")]) popup.set_wm_transient_for(owner) popup.map() grab.map() focus = grab if action == "hidden": popup.unmap() elif action == "other-group": popup.change_property(leaderAtom, Xatom.WINDOW, 32, [other.id]) elif action == "other-pid": popup.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid() + 1]) elif action == "ordinary-window": popup.change_property(typeAtom, Xatom.ATOM, 32, [connection.intern_atom("_NET_WM_WINDOW_TYPE_NORMAL")]) elif action == "no-owner": popup.delete_property(connection.intern_atom("WM_TRANSIENT_FOR")) elif action == "foreign-owner": popup.set_wm_transient_for(other) elif action == "input-output-focus": focus = other elif action == "ewmh": root.change_property(activeAtom, Xatom.WINDOW, 32, [other.id]) focus.set_input_focus(X.RevertToParent, X.CurrentTime) connection.sync() configure("popup") print(json.dumps(dict(owner=owner.id, grab=grab.id, other=other.id)), flush=True) for line in sys.stdin: configure(line.strip()) print("ready", flush=True) connection.close()