diary @ telent

Moon on a stick#

Tue Dec 18 21:31:25 2018

Latest in my ever-expanding series of diversions from NixWRT is this foolish attempt to write a Wayland compositor using a language I don't actually understand. I'd add: not for the first time , except that now I check the link I see that was going to be a text editor not a compositor.

This time it's a Wayland compositor, using the wlroots library (described by its author as "about 50,000 lines of code you were going to write anyway") and written in Lua. Mostly because when I get a bit further along with it I'm going to integrate Fennel into it, and then with a bit of luck will have a respectable replacement for the once-brilliant but now rather long in the tooth Sawfish . I say "when" but we all know I really mean "if".

At the time of writing it works to the extent that I have a Lua script that can set up the display appropriately then allow me to display a Konsole window into which I can type, and it renders a pointer which moves around in expected and unsurprising ways when I stroke my touchpad. It has no knowledge, though, of window decorations or of stacking order or even of focus or the channeling of pointer button/movement events onto a client.

(Decorations? Yes, I'm with the KDE guys on this one. Requiring clients to render their own window borders and resize themselves on the screen is like a bank requiring customers to track their own account balances and know which market funds their deposits were invested in: how can you ever be sure the app you thought was "Password Wallet Master Key Entry" was actually that and not, I dunno, "I'd like to add you to my professional Botnet" if you don't have some kind of trustable fence around the rectangle it's permitted to draw into. Honour system?)

!>/static/images/fenestra.png!

Some brief notes on how I'm doing it, for the benefit of future-me and potential benefit of present-other. I'm using LuaJIT: not for speed but because the FFI can parse (most) C header files and there's a lot of FFI in this project. So far I have made a fairly literal transcription of the code in Drew DeVault's blog posts parts I-III, and then a rather sketchier interpretation of the code in Input handling in wlroots

Some stuff has changed since the blog posts were written. Here are the differences and/or relevant gotchas that I noted or can remember

  • @wlr_renderer_begin@ now takes int width, int height as second and third params instead of needing a wlr_output

  • @wlr_compositor.surfaces@ is probably the old name for what is now wlr_compositor.surface_resources

  • @wlr_render_with_matrix@ has become wlr_render_texture_with_matrix

  • without an xkb keymap set (wlr_keyboard_set_keymap) you won't get any key events. You might think there's no need for keymaps if all you want is to look at the raw codes, but nope, it doesn't work.

  • @wlr_seat_set_capabilities@ is not mentioned in the blog, but you need it set right according to the inputs available at your "seat"

  • to render the mouse pointer when you're running wayland-under-X (for development, before the server is ready for dogfooding) you need to call wlr_output_render_software_cursors(output, nil) while rendering output. So you don't leave a ghost trail of former pointer positions whenever the mouse is moved, you probably also want to call wlr_renderer_clear as the first thing after wlr_renderer_begin

  • there's a bit more to wlr_xcursor than it explains, and TBH I'm just going to point you to my diff instead of trying to explain it here. Because while as a general rule I would never claim that "life's too short" for doing fun things, I must concede that the remaining available time for sleeping before my alarm goes off tomorrow morning is rapidly getting that way.