This means that we shouldn't raise an exception, but rather fail
outright. The background being black means that things *failed
successfully*, as expected.
This allows keyboard input to be sent to it, thus supporting passphrase
input using a physical keyboard.
Additionally, don't show the focus ring on the only element.
First, right now we're putting the full error message front and center,
rather than the sad phone.
We're keeping the sad face though, but only as an accent icon.
Finally, not part of this PR, we'll add actions to abort a total crash.
The way we're handling them is to have a global timer that is reset at
any point a task is ran.
This gives a maximum amount of chances to any task to have its
dependencies resolve.
A minimum of 60s is given, but in reality the chances are the conditions
for trying to resolve were already present before the timeout started
counting towards that particular dependency.
Note that a long running task, when successfully ran, does not cause the
timeout to be reached.
E.g. at 10s of timeout a task is started, the loop is not executed until
the task exits. When it exits the branch followed is for a task that
ran, which means that even if the task took 70s total (which gives us 80
seconds) a timeout of 60s wouldn't apply here.
Though, please, don't make your tasks take that much time to run!
They will, at some point, be promoted into LVGUI. For the time being
they are local as they have only been verified to work in a useful
manner for this limited use case.
The splash is now an application that should be started and forked from.
Once started, it will listen for messages on a ZeroMQ socket reporting
progress.
The current protocol is extremely simple, reporting (optional) label,
and reporting a progress amount.
Additionally, it responds to a string commant ("quit") to quit as
needed.
The applet is specifically written to show what we call the "recovery
menu". Yes, it's also the boot selection, but it will get confusing with
the upcoming boot tracking splash UI that's upcoming.
This is to ensure "UX-friendly" tasks gets run ASAP.
Quickly explained, this makes sure that the top tasks (e.g. Splash) gets
ran as soon as possible.
Given the list:
- Splash
- Graphics
- AAA
- BBB
- CCC
If `Graphics` ends up running, and AAA, BBB and CCC can too, Splash will
have to wait until all those tasks got ran once!
Not ideal for UX, if e.g. BBB takes time to *run* and we can't show the
progress to users!
The added cost of restarting the queue is minimal with tests I ran. It
was not more than a tenth of a second, and could even be rounding
errors.