mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 05:00:08 +02:00
Notice a mouse or keyboard that reconnects between device scans
The relay scanned /dev/input once a second and only probed paths it hadn't seen. A Bluetooth mouse that disconnects and reconnects within that second often gets the same event numbers back, so the relay never grabbed it again and the mouse stopped working. Nodes are now tracked by inode, so a re-created node is probed even in a known place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
54b1e5cd4b
commit
fb2d62e1da
1 file changed
+21
-6
+21
-6
@@ -466,7 +466,10 @@ def main():
|
||||
except OSError:
|
||||
pass # ft-screens not running
|
||||
nodes = {} # fd -> Node
|
||||
seen = set() # paths already probed (rejected or open)
|
||||
# Nodes already probed (rejected or open): path -> inode. A device that disconnects and
|
||||
# reconnects between two scans often gets the same event numbers back, so the path alone
|
||||
# would hide it; the re-created node has a new inode.
|
||||
seen = {}
|
||||
next_scan = 0.0
|
||||
|
||||
def role_of(node):
|
||||
@@ -503,7 +506,7 @@ def main():
|
||||
release_held(node)
|
||||
os.close(node.fd)
|
||||
del nodes[node.fd]
|
||||
seen.discard(node.path)
|
||||
seen.pop(node.path, None)
|
||||
log(f"released {node.name} ({node.path}): {reason}")
|
||||
|
||||
def reply(addr, obj):
|
||||
@@ -557,11 +560,23 @@ def main():
|
||||
pointer = state["pointer"]
|
||||
if now >= next_scan:
|
||||
next_scan = now + 1.0
|
||||
paths = {f"/dev/input/{n}" for n in os.listdir("/dev/input") if n.startswith("event")}
|
||||
seen &= paths | {n.path for n in nodes.values()}
|
||||
current = {}
|
||||
for name in os.listdir("/dev/input"):
|
||||
if name.startswith("event"):
|
||||
try:
|
||||
current[f"/dev/input/{name}"] = os.stat(f"/dev/input/{name}").st_ino
|
||||
except OSError:
|
||||
pass
|
||||
for path in [p for p in seen if p not in current]:
|
||||
del seen[path]
|
||||
added = False
|
||||
for path in sorted(paths - seen):
|
||||
seen.add(path)
|
||||
for path, ino in sorted(current.items()):
|
||||
if seen.get(path) == ino:
|
||||
continue
|
||||
# New here: a new device, or one that came back in the same place.
|
||||
for old in [n for n in nodes.values() if n.path == path]:
|
||||
drop(old, "replaced by a new device node")
|
||||
seen[path] = ino
|
||||
node = probe(path)
|
||||
if node:
|
||||
nodes[node.fd] = node
|
||||
|
||||
Reference in new issue
Block a user