Description
This is intended as a short informal overview of my current thinking on Druid, and my current plans. Right now I am mostly working on font compilation stuff, but I hope to shift focus more fully back to Druid around October. This was sitting as a draft in my gists, though, and this feels like a better place for it. 😅
Sometime soon I would like to do a rollup release (0.8
) of all the various work done since 0.7.
N.B: The primary goal of Druid is to allow me to build Runebender. This goal is what dictates the roadmap, and also explains certain omissions: there are various features that might be important to a general-purpose GUI framework that are not currently important to Runebender (such as protected text input) and which may be neglected for the time being.
I want to separately address druid and druid-shell, that is the high-level GUI API and the lower-level system-integrations. Very briefly, my main interest right now is in working on "finishing up" the lower level infrastructure.
the high level architecture
I continue to have some concerns about this. In particular, I find that once an application gets large, Data
becomes hard to reason about: anything can potentially change anywhere, and in any order, and this can make it easy to introduce difficult bugs.
I do not have a current plan to change this drastically, right now. There have been various musings and experiments over the past year, but nothing conclusive. Later this fall Raph and I are hoping to spend a week or two together in person hacking on this, and it's possible something will come of that, and it's also possible that it won't. My dream here remains to have something much closer to a truly declarative/reactive framework, but which also lets the user hand-write widgets in the current druid style as an "escape hatch". Making this work is a pain, though.
druid-shell
regardless of any changes we make at a high level, we are going to continue using druid-shell to interact with target platform. There are a bunch of long-standing issues with druid-shell, and so my focus right now is on resolving these. In particular:
- decoupling
piet
: currently druid-shell is tightly bound to piet. If you want to use druid-shell without piet, you are out of luck. This limitation seems arbitrary and unhelpful, and I would like to unwind it. it should be thedruid
crate that is responsible for setting up the graphics context. - explicit child/modal windows: There should be an explicit API for creating windows that are presented modally by a parent. This will be a building block for important features like combo boxes and alerts. The main feature of a modal window is that it steals focus until dismissed. In some cases they may be dismissed by simply clicking anywhere outside the modal (as with a drop-down list) and in some cases they can only be dismissed through some explicit interaction within the modal, as in the case of an alert message with "Ok" and "Cancel" buttons. This lends itself to a fairly simple API:
this is very much a sketch. In particular we may want to have a special case of modal for alert messages, we may want a different payload type, etc.
// to present a modal, attached to a given window: WindowHandle::show_modal(&self, window: WindowDesc) -> ModalToken // when that modal completes. // // The `payload` is dependent on the particular modal type. For an alert it // will indicate which option was selected, for a dropdown it will contain // the selected item, etc. WinHandler::modal_completed(&mut self, token: ModalToken, payload: Box<dyn Any>)
- extensibility/expose platform APIs: I would like to expose more platform-specific behaviour through extension traits. In addition, I would like to explore ways to allow additional integration with the platform, such as catching unhandled
WNDPROC
messages on windows, or overriding additional methods on key objects on mac; this is not a priority though. - have a clearer plan for linux I would like to have a clearly developed and communicated plan for how we want to work on linux. This means documenting our desire to move off of GTK, and figuring out what the story between wayland/x11 is going to be. To do this we'll also need to figure out how we're going to handle things like menus, which we'll have to implement ourselves. One complication here is that we will want to be able to use things at the druid level (like widgets) in order to implement menus, so we need to figure out if this is going to be handled in the shell at all on those platforms.
- break out components where reasonable: for instance, I would like to move the copy/paste handling code into its own crate.
- bundling assets: I would like to figure out how we're going to provide access to things like localization assets, custom fonts, etc.
- be less window centric: Currently the druid-shell interfaces operate mostly at the level of individual windows: for instance, each window has its own
WinHandler
. I would prefer to move to a model where we have a singleAppHandler
that receives all events for all windows, and then possibly only have aWinHandler
for the very specific case of VSTs, see: - investigate VST support: it would be nice if we could support the VST use case. From some preliminary digging it feels like this should not be hard, and given that I think it's worth doing, although I will probably only bother with this if somebody who is active in the rust-vst space is interested in collaborating on this. The key thing here is that in the VST case, we don't want to provide API that does not make sense (such as letting the user open new non-modal windows, or close the application).
- Rethink paint events: Currently painting works on a push model. I would like to move to a tick-based model, described in Changes to how paint and animation are handled in druid-shell #1944.
- Pointer events: I would like an API modeled on the web PointerEvent.