The problem
The monitor-lock.py
script in my previous blog post
uses python-xlib
, which currently mainly relies on
manually porting Xlib functions to Python. This is why it is missing
the barrier-related functions I needed in that post. There is
work on automating this process,
but it appears to be abandoned. I started trying to pick up where they
had left off before finding the python-xcffib
project which
provides auto-generated bindings for libxcb
and therefore gives
full support for interacting with X at a low level from Python.
python-xcffib
(named after the cffi
library it uses for
binding to the C XCB library) gives a slightly lower-level API than
python-xlib
, but they are both fairly thin wrappers over the X
protocol, so the differences are minor. It was fairly straightforward
to port my script from the previous post to use python-xcffib
,
available as monitor-lock-xcb.py
.
Unfortunately, I ran into a bug in python-xcffib
:
Traceback (most recent call last):
...
File "./monitor-lock-xcb.py", line 38, in main
devices = conn.xinput.XIQueryDevice(xcffib.xinput.Device.AllMaster).reply().infos
...
File "/usr/lib/python3/dist-packages/xcffib/__init__.py", line 139, in _resize
assert self.size + increment <= self.known_max
AssertionError
The solution
I've submitted the fix upstream, so most likely you will not encounter this error. Updating to the latest version (after v0.8.1) should be sufficient to fix the problem.
The fix I applied was to modify the module's __init__.py
(the
location, which may be different on your machine, is in the stack
trace). Specifically, on line 108 in the function Unpacker.unpack()
,
in the call to struct.calcsize()
,
change fmt
to "=" + fmt
.