80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
"""Steam-shaped X11 browser and popup fixture for a private X server."""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
from Xlib import X, Xatom, XK, display
|
|
from Xlib.xobject.drawable import Window
|
|
|
|
|
|
def main() -> None:
|
|
connection = display.Display()
|
|
root = connection.screen().root
|
|
activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW")
|
|
pidAtom = connection.intern_atom("_NET_WM_PID")
|
|
|
|
def make_window(parent: Window, width: int, height: int) -> Window:
|
|
window = parent.create_window(0, 0, width, height, 0,
|
|
connection.screen().root_depth,
|
|
event_mask=X.KeyPressMask | X.KeyReleaseMask)
|
|
window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()])
|
|
window.map()
|
|
return window
|
|
|
|
steam = make_window(root, 800, 600)
|
|
steam.set_wm_class("steamwebhelper", "steam")
|
|
mainHost = make_window(steam, 800, 600)
|
|
browser = make_window(mainHost, 800, 600)
|
|
popupHost = make_window(steam, 300, 600)
|
|
popup = make_window(popupHost, 300, 600)
|
|
other = make_window(root, 800, 600)
|
|
other.set_wm_class("example", "Example")
|
|
otherChild = make_window(other, 800, 600)
|
|
windows = dict(steam=steam, browser=browser, popup=popup,
|
|
popupHost=popupHost, other=other, otherChild=otherChild)
|
|
root.change_property(activeAtom, Xatom.WINDOW, 32, [steam.id])
|
|
browser.set_input_focus(X.RevertToParent, X.CurrentTime)
|
|
connection.sync()
|
|
print(json.dumps({name: window.id for name, window in windows.items()}), flush=True)
|
|
for line in sys.stdin:
|
|
command = json.loads(line)
|
|
action = command["action"]
|
|
window = windows[command.get("window", "steam")]
|
|
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 == "unmap":
|
|
window.unmap()
|
|
elif action == "map":
|
|
window.map()
|
|
elif action == "destroy":
|
|
window.destroy()
|
|
elif action == "class":
|
|
window.set_wm_class("example", "Example")
|
|
elif action == "xterm":
|
|
window.set_wm_class("xterm", "XTerm")
|
|
elif action == "unknown":
|
|
root.delete_property(activeAtom)
|
|
elif action == "pid":
|
|
window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid() + 1])
|
|
elif action == "events":
|
|
connection.sync()
|
|
events = []
|
|
while connection.pending_events():
|
|
event = connection.next_event()
|
|
if event.type in (X.KeyPress, X.KeyRelease):
|
|
events.append({"window": event.window.id, "pressed": event.type == X.KeyPress,
|
|
"escape": event.detail == connection.keysym_to_keycode(XK.string_to_keysym("Escape"))})
|
|
print(json.dumps(events), flush=True)
|
|
continue
|
|
connection.sync()
|
|
print("ready", flush=True)
|
|
connection.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|