mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-14 19:27:09 -04:00
feat: log the window properties gamescope checks before counting a window as focusable
This commit is contained in:
1 parent
408233b8e5
commit
933ba953a8
1 file changed
+28
-4
@@ -2,7 +2,10 @@
|
||||
# The top-level windows of one Xwayland server, one line each, for the session log: what gamescope
|
||||
# had to pick focus from. Each line has the window, whether it is mapped, override-redirect, its
|
||||
# geometry, the app id it carries (STEAM_GAME, which gamescope focuses by), its WM_STATE, pid and
|
||||
# class. Windows that are neither mapped nor tagged with an app id are left out - wine keeps many
|
||||
# class. Then whatever is set of what else gamescope weighs before it counts a mapped window as
|
||||
# focusable: an InputOnly class, _NET_WM_WINDOW_OPACITY (0 is never focusable), STEAM_OVERLAY,
|
||||
# GAMESCOPE_EXTERNAL_OVERLAY, STEAM_INPUT_FOCUS and _NET_WM_STATE (skip taskbar and pager without
|
||||
# fullscreen is left out of the focusable list the client reads). Windows that are neither mapped nor tagged with an app id are left out - wine keeps many
|
||||
# hidden ones. The rootfs has xprop but no xwininfo, so this speaks the X protocol itself.
|
||||
#
|
||||
# droiddeck-xwindows :1
|
||||
@@ -65,7 +68,13 @@ class X:
|
||||
|
||||
def attributes(self, win):
|
||||
r = self.request(struct.pack("<BxHI", 3, 2, win))
|
||||
return (r[26], r[27]) if r else None
|
||||
return (r[26], r[27], struct.unpack_from("<H", r, 12)[0]) if r else None
|
||||
|
||||
def atom_name(self, atom):
|
||||
r = self.request(struct.pack("<BxHI", 17, 2, atom))
|
||||
if not r:
|
||||
return str(atom)
|
||||
return r[32:32 + struct.unpack_from("<H", r, 8)[0]].decode(errors="replace")
|
||||
|
||||
def geometry(self, win):
|
||||
r = self.request(struct.pack("<BxHI", 14, 2, win))
|
||||
@@ -91,7 +100,9 @@ def main():
|
||||
except OSError as e:
|
||||
print("== %s: %s" % (display, e))
|
||||
return
|
||||
atoms = {name: x.atom(name) for name in ("STEAM_GAME", "WM_STATE", "_NET_WM_PID", "WM_CLASS")}
|
||||
atoms = {name: x.atom(name) for name in (
|
||||
"STEAM_GAME", "WM_STATE", "_NET_WM_PID", "WM_CLASS", "_NET_WM_WINDOW_OPACITY", "STEAM_OVERLAY",
|
||||
"GAMESCOPE_EXTERNAL_OVERLAY", "STEAM_INPUT_FOCUS", "_NET_WM_STATE")}
|
||||
for win in x.children(x.root):
|
||||
attrs = x.attributes(win)
|
||||
if not attrs:
|
||||
@@ -103,6 +114,19 @@ def main():
|
||||
state = x.prop(win, atoms["WM_STATE"])
|
||||
pid = x.prop(win, atoms["_NET_WM_PID"])
|
||||
cls = x.prop(win, atoms["WM_CLASS"])
|
||||
extra = []
|
||||
if attrs[2] == 2:
|
||||
extra.append("InputOnly")
|
||||
for label, name in (("opacity", "_NET_WM_WINDOW_OPACITY"), ("overlay", "STEAM_OVERLAY"),
|
||||
("external-overlay", "GAMESCOPE_EXTERNAL_OVERLAY"),
|
||||
("input-focus", "STEAM_INPUT_FOCUS")):
|
||||
value = x.prop(win, atoms[name])
|
||||
if value:
|
||||
extra.append("%s 0x%x" % (label, value[0]) if label == "opacity" else "%s %d" % (label, value[0]))
|
||||
net_state = x.prop(win, atoms["_NET_WM_STATE"])
|
||||
if net_state:
|
||||
extra.append("net-state " + ",".join(
|
||||
x.atom_name(a).replace("_NET_WM_STATE_", "") for a in net_state))
|
||||
print("== %s window 0x%x: %s%s %s app %s state %s pid %s class %s" % (
|
||||
display, win, MAP_STATE[attrs[0]] if attrs[0] < 3 else attrs[0],
|
||||
" override-redirect" if attrs[1] else "",
|
||||
@@ -111,7 +135,7 @@ def main():
|
||||
WM_STATES.get(state[0], state[0]) if state else "-",
|
||||
pid[0] if pid else "-",
|
||||
cls.split(b"\0")[-2].decode(errors="replace") if cls and b"\0" in cls else "-",
|
||||
))
|
||||
) + "".join(" " + e for e in extra))
|
||||
|
||||
|
||||
main()
|
||||
Reference in new issue
Block a user