I found sway 1.10 and wlroots 0.18.2 will occasionally generate
wl_keyboard::keymap events with an empty keymap. I do not have
a reliable reproduction for this, but it seems to occur when
switching back and forth between workspaces with the keyboard.
This also fixes the issue where devdraw can go into a busy loop if
the compositor goes away and wl_display_dispatch() returns -1.
I tried running the wayland devdraw implementation on Sway 1.10,
wlroots 0.18 and encountered the error:
xdg_surface#13: error 3: xdg_surface has never been configured
According to https://wayland.app/protocols/xdg-shell#xdg_surface ,
a client must commit a surface without a buffer, *wait* for the first
configure request from the compositor, ack it, and *only then* can
it proceed to attach a buffer to the surface and tell wayland to display it.
This was caused by the following sequence of events:
1. devdraw starts, enters gfx_main
2. `gfx_main` calls `gfx_started`, which spawns the `serveproc` thread
3. `gfx_main` enters `wl_display_dispatch`, flushing any buffered requests to
the compositor, and enters `wl_display_poll()` to wait for incoming messages
4. `serveproc` calls `rpc_attach`, sets up the surface, and buffers a commit.
The race is between #3 and #4. If #3 happens first, the buffered commit
just sits there until `rpc_flush` is called, which calls `wl_display_flush()`,
but at that point a buffer is attached too quickly for the configure to happen.
This commit fixes the race by adding a `configured` field to the WaylandClient
and using it to guard `rpc_flush`.
In addition, I found that mouse warping, at least in sway, would move
the cursor but future mouse presses would register at the old location
until I moved the mouse. So I added a call to gfx_mousetrack to the end
of `rpc_setmouse`.