`love.textinput` is fragile on iOS. Various things can cause an app to
stop receiving textinput events. Resizing the window is one reliable
way, but there's also another ghost, something that's triggering on
every frame of LÖVE.
Fortunately, it looks like `love.keyboard.setTextInput(true)` reliably
resubscribes the app to textinput events, regardless of their cause.
https://github.com/love2d/love/issues/1959
The one remaining open question here is why the call in
`App.keychord_press` (equivalent to `love.keypressed`) doesn't fix the
breakage caused by the initial window resize (that happens before any
keys are pressed). I've confirmed that `keypressed` comes before
`textinput` on iOS just like everywhere else.
Changes inside on.initialize are minefields. Until now, if you made a
mistake when modifying on.initialize, you could end up in a situation
where the app would fail irrecoverably on the next startup. You'd have
to go dig up a text editor to fix it.
After this commit, errors in on.initialize wait for commands from
driver.love just like any other error.
Recovering from errors during initialization is a little different than
normal. I don't know how much of initialization completed successfully,
so I redo all of it.
I think this should be safe; the sorts of things we want to do on
startup tend to be idempotent just like the sorts of things we do within
an event loop with our existing error handling.
Things are still not ideal. Initialization by definition happens only
when the app starts up. When you make changes to it, you won't find out
about errors until you restart the app[1], which can be much later and a
big context switch. But at least you'll be able to fix it in the usual
way. Slightly more seamless[2].
One glitch to note: at least on Linux, an app with an initialization
error feels "sticky". I can't seem to switch focus away from it using
Alt-tab. Hitting F4 on the driver also jarringly brings the client app
back in focus when there was an initialization error. But the mouse does
work consistently. This feels similar to the issues I find when an app
goes unresponsive sometimes. The window manager really wants me to
respond to the dialog that it's unresponsive.
Still, feels like an improvement.
[1] I really need to provide that driver command to restart the app! But
there's no room in the menus! I really need a first-class command
palette like pensieve.love has!
[2] https://lobste.rs/s/idi1wt/open_source_vs_ux
To do this I need some support for multiple versions. And I need an
'error' mode to go with existing 'run' and 'source' modes
(`Current_app`). Most errors will automatically transition to 'source'
editor mode, but some errors aren't really actionable in the editor. For
those we'll use 'error' mode.
The app doesn't yet work with LÖVE v12. There are some unit tests failing
because of differences in font rendering.
Error_message is a special global. It's set when the app (Current_app = 'run')
encounters an error and switches to the source editor, and cleared when
switching from source editor back to the app.
Bug was introduced in commit a2451aa26 32 hours ago, because I didn't go
over the manual tests for the error-handling protocol after modifying
the error-handling protocol. (I only tested them in template-live.)
- I often find that opening up driver.love and sending any message gets
my app unwedged. Retrying should be easy. Just press a key.
- There's really no reason for the app to become unresponsive while
waiting for code changes.
This approach tries to address both. Press any key to retry, or show the
error right on the window while I whip out driver.love. You can also
copy the message to the clipboard by hitting 'c'.
Drawbacks of this approach:
- nobody's going to read the message. I myself didn't notice the
default support for copying the error message for _months_.
- more complexity for anyone reading the code to parse. More stuff
that can go wrong. Any errors within the handler will crash the app
hard. (Though now there's less code in the handler, so maybe this is
an improvement on that score.)
The best plan is still to not rely on this too much. Don't ship bugs.
This repo does not support freewheeling modification. It's a primitive
to enable freewheeling modification in downstream forks.
The source editor is a convenience, but it's a sharp tool and can easily
leave the app in a broken state that requires dropping down to external
tools (editor, file manager) to fix.