It would be nice to just inherit form the OptionList messages, but the
naming of the properties wouldn't quite make sense, and there's also the
generic typing issue too. So here I start to spin up my own messages down
here.
Also, as an initial use of this, grab the OptionList highlight message and
turn it onto one of out own.
Mostly I feel it makes sense to have the value first, and the actual prompt
second (based on no reason at all); but given that Select does it prompt
then value, this should conform to the same approach.
Now that I'm no longer having to dodge issues with getting component classes
before the DOM has spun up, I can go back to the simpler method of setting
up the selections.
This also means I can drop Mount handling.
More experimenting with overriding OptionList, and rather than trying to
swap out and around the prompt under the hood, I got to thinking that it
made more sense to perhaps override render_line.
So far so good...
I think I'm going to give up on basing this off OptionList. It's close
enough that inheriting from it and doing more makes some sense, but it's
also just far enough away that it's starting to feel like it's more work
that is worthwhile and it'll be easier to hand-roll something fresh.
Normally it's not a great idea to eat and hide exceptions within library
code; but I think it makes sense to make an exception here. This is a UI
element that lets the user navigate about a filesystem. If there is
something they don't have permission for, that should not cause an
exception, it should just give up with the best possible outcome.
If actually doing something with the exception is important, the developer
using this could use the filter to do tests and act accordingly.
See #2564.
Plan C; or is it plan D? Something like that. Anyway... in this approach we
keep a single "forever" async task worker per directory tree, which in turn
looks at the async Queue, and when a new node appears on it it starts a
short-lived thread to load the directory data.
This seems to be working fine on macOS. Next up is testing on Windows.
Turns out, there's a maximum number of threads you can have going in the
underlying pool, that's tied to the number of CPUs. As such, there was a
limit on how many directory trees you could have up and running before it
would start to block all sorts of operations in the surrounding
application (in Parallels on macOS, with the Windows VM appearing to have
just the one CPU, it would give up after 8 directory trees).
So here we move to a slightly different approach: have the main loader still
run "forever", but be an async task; it then in turn farms the loading out
to threads which close once the loading is done.
So far tested on macOS and behaves as expected. Next to test on Windows.
When the default screen is first created it was not getting the event ScreenResume. All other screens receive a ScreenResume when first created and _all_ screens (the default one and custom screens) receive this event when they become the active screen again, so this was kind of an edge case that needed the event to be posted by hand.
Related comments: https://github.com/Textualize/textual/pull/2581\#issuecomment-1550231559