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
.