qtile/qtile — pull request #489 by flacjacket (2014-08-30 23:03:43+00:00)
Title: Asyncio-based event loop

Copied from tych0/qtile#17 see initial discussion there.

# Major obstacles

- [ ] Fix `cmd_spawn`

Currently, processes spawned with `cmd_spawn()` will zombie when qtile is restarted. This needs a robust replacement.

# Copied from tych0/qtile#17

The move to a fully pip-installable Qtile! (once cairocffi merges XCB support...)

One thing is I've decided to support the asyncio module where available (in the standard library [asyncio module](https://docs.python.org/3/library/asyncio.html) for >=3.4 and [Tulip](https://code.google.com/p/tulip/) for 3.3), falling back on [trollius](http://trollius.readthedocs.org/) for 2 and <=3.3. We obviously couldn't do `yield from ...`, which is only valid syntax >=3.3, but we also can't use the trollius style `yield From(...)`. We could make everyone install trollius, which would let us do this, but I'm not sure it lets us do much more. We might consider this if we find a case where it's too hard to support both.

This will probably need people to just play around to try to work out any kinks. In particular, I stopped `conn.flush()` from running at every step of the event loop, since there isn't really a comparable function to `context.iteration()`, and moved it to `._loop()`. This is run on startup, after `._xpoll()`, and after `draw`'s in drawer.py. We will probably have to play around with this to get it called when we need it.

I've implemented a new IPC protocol based on [asyncio transports and protocols](https://docs.python.org/3/library/asyncio-protocol.html). This seemed to occasionally hang on Travis waiting for the server, particularly on 3.3 (maybe it's something with Tulip?), so I set large timeouts (5 s) on the client waiting for reply. I can't pin down the problems here, since they always work fine for me, hopefully debugging can work this out. Also, there is probably more that can be done here to use more asyncio stuff.