Simpledisplay additions, minigui event changes

Posted 2021-05-03

I added a list font method to OperatingSystemFont and alpha blending support to the Sprite class in simpledisplay, and I did something I've been meaning to do for a while: start to redesign minigui's event system.

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on


I received a request last month for a function to list available fonts in a format that OperatingSystemFont can use.

I'm not quite happy with the result, but it works and it might be good enough for an initial release right now. OperatingSystemFont.listFonts is what I added - it just passes strings to a callback of font names. It was a bit of a pain even to implement this: I had to load the fontconfig library on Linux too, blargh. It lazy loads though so you won't see any difference if you don't use it.

Adding alpha blending to the Sprite class has been on my list for quite some time and I finally got around to it a couple weeks ago too.

I put that off for a LONG time, in part because I don't care for the documentation of XRender (or most other X extensions to be frank), but now that I've dove in and figured it out, this task wasn't as hard as I thought it was. It actually went pretty quickly after I realized you can just make a 32 bit pixmap in X and bitmap in Windows and it basically just works. Though I still haven't figured out the xrender gradient functions... oh well.


Please note: the stuff described here is not yet pushed online and it may change before I do.

Someone recently asked me what specifically I would change in minigui if I could it all over again. This isn't stuff in the works that are incomplete, but rather bad designs in the past that would be difficult to fix now. Among my regrets:

  • The event model is even weaker than Javascript's, while fixing none of its problems
  • The widget hierarchy conflates multiple concepts and thus breaks the substitution principle and exposes too many implementation details
  • Theme delegation is non-existent outside of Windows, and on Windows, it is only delegated to the system. Modifying placement attributes is difficult.
  • It would be really cool if you could paint on console targets too

As I was writing up the details on what specifically I didn't like in the event system, I realized it isn't actually that impossible to draw up a transition path. Indeed, I started to think I could do it without a major breaking change. Yes, I would have to at least deprecate some of the old accessors - there presence is part of the regret - but I wouldn't have to actually break them nor force all user code to change too much, but they would want to move away from the deprecated properties.

The basic idea is to move specific properties to Event subclasses, then let you register an event listener that takes a subclass instead of just the generic base type. I can add this without actually changing most the stuff! Really just the deprecation of the specific properties, not of the whole coding model.

I implemented it in a couple hours and adjusted all my usage code (most of which is inside the lib itself) in a matter of minutes. It was a really easy transition and now I'm a lot happier with it. Now I might add a few other conveniences (like some kind of specific property change notifications that uses the same mechanism but is easier to code and use) and more documentation and dynamic hook potential, but I'm pretty happy with most the change.

Here's the work-in-progress documentation page:

Again, this is pre-release experimentation documentation of the change, but it gives you a good idea of where I'm going.

This may force me to tag a major release, despite the breakage being mostly isolated to internal components that I'd be surprised if anyone is actually using outside my standard widgets. The breaks on the outside have deprecation warnings on compatibility shims with a simple migration path, which can be handled with a minor version bump. (I will probably never remove these shims fyi.)

Thoughts on deprecations

I mostly like the D deprecated keyword. It is a nice way to inform people of things they could do better as they need that information. But it doesn't interact terribly well with reflection - reflecting over a deprecated member triggers the warning.

__traits(isDeprecated) was added in dmd 2.077, released in November 2017, so you can address this in the library, but your only real option is to skip the deprecated members. It would be nice if I could simply silence the warning in my reflection loop while still letting it in, or silence it in the D compiler while noting the deprecation if it is used at runtime (e.g. in my script language or when parsing a config file).

I can live without it, but it would be nice if there was some other solution.

other ideas in the future

I'm still tempted to add some kind of base module for a few little helper things like exceptions and some base interfaces. A shared event loop would also probably be nice - I keep slowly working on improving interop and I've made a lot of progress, but it would be nice to just have the interface working. I might just do that some day in a breaking change release. But I've spent a lot of years saying certain modules are standalone and this is breaking that so... idk I keep thinking about it but may not ever actually do it.

While I do think I will tag 10.0 once this new minigui event system is stabilized, but these other things probably won't be in it. Perhaps 11.0? We'll see.