New selective mouse input in terminal stack, Xft used in simpledisplay to improve TrueType font support

Posted 2020-11-16

New selective mouse input in terminal stack, Xft used in simpledisplay to improve TrueType font support

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on

Terminal mouse feature

My terminal api along with my terminal emulator now support a new feature: a selective mouse reporting mode.

Normal terminals have two major mouse modes: application mouse, where the terminal emulator program forwards mouse events to the application (and there's a few different ways they can do that), and default processing, which is usually selecting text and copying it to the clipboard.

With normal terminals, if you enable application processing, the program gets all events and there's no way for it to ask for default behavior. The user can hold shift to bypass the application, but they must do that themselves.

Normally, I'm pretty ok with that: holding shift gives me, as the user, some control. But lately, with the baby, I've been trying to use my applications one-handed, and believe me, clicking while holding in shift is not easy to do without a second hand on the keyboard!

Moreover, I also put mouse events in Terminal.getline, so you can click in the line to move the cursor. But this is painful everywhere else - this little nicety on the input line breaks simple (unshifted) selection of output text.

That led me to this new feature: it asks the terminal emulator to send events... but only if they occur on the line with the cursor for any application, or on the top line of the window or a mouse wheel event anywhere in a full-screen application. The line of the cursor lets my input convenience work. The full-screen exceptions let me keep clicking on tabs and scrolling content in my IRC client. Selfish, I know, but a lot of applications give special case to those similar cases, so I think it is fairly reasonable.

Of course, this only works if you use my terminal emulator (including the nested emulator version). For other emulators, it falls back to just normal default processing with no mouse events to the application at all.

This lets me progressively enhance with my own code stack without really hurting people on other terminals and I'm pretty happy with it so far.

ttf in simpledisplay

A user of my embedded terminal enjoyed using custom fonts on Windows and was disappointed to find it didn't work as well on Linux. Part of this was a simple null pointer bug I overlooked, but the bigger problem was why it was null in the first place: it only looked at X Core Fonts, which work pretty differently than Windows.

I like the core fonts personally, they look good and work fast, even on a remote connection. But if you are used to other fonts and/or need different size scaling, they indeed break down. If they scale at all, they do so without antialiasing and tend to look less than ideal. Moreover, you have to specify the names differently than most applications, using a different naming scheme.

So, I finally implemented an alternative. There's lots of font libs on Linux, but in my desire to keep it simple, I went with Xft, which is part of a typical X installation and interfaces with the freetype lib and XRender extension for antialiasing, so it has the features people want and its api is very similar to the core fonts so its implementation was easier to write than this blog post.

I did make one change in the process though: the OperatingSystemFont class, which loads these, will still return to the core protocol if you put core: in the font name. For example, core:fixed will load the font "fixed" through the core mechanism, whereas arial will go through xft. This is arguably a breaking change and I may bump the major version number because of it. But since OperatingSystemFont was previously underspecified and odds are nobody but me was using it the way it was before... I could perhaps get away with it. I'll decide later.

To use this, use:

auto font = new OperatingSystemFont("some name known to the OS", size);

auto painter = window.draw();
// tbh I don't recall which one affects fonts
// so I just set both.
painter.outlineColor = /* some color */;
painter.fillColor = /* some color */;

// load our font in the painter
painter.setFont(font);

// and use it
painter.drawText(Point(0, 0), "hello");

partial nogc png

I added a handful of nogc tags to png.d, but it is far from complete. nogc is awkward to use - it is so strict, especially when exceptions work best when GC allocated.

You can use exceptions without them, but it is hard to do for a general-purpose library since nobody expects to have to free what they catch. Moreover, qualifiers like immutable are completely broken in the exception mechanism, so you can't use that either. And it is legal for people to store exception objects they catch! Leaves few options, unless you control all the user code (then it is fairly easy to just call a method).

Since my API is already established, such breaking changes are not reasonable, but some of the helper functions can be safely changed and I can perhaps provide alternate implementations with more options.

There is the -dip1008 switch that seems to solve this though. I wonder when/if that will be generally used.