Avoid MacOS accent menu

Avoid MacOS accent popup menu

For the Flutter based Terminal application I wanted to deactivate the MacOS behaviour that shows an accent selection popup when a key gets pressed long (instead of repeating the pressed character).

MacOS accent menu

This is actually a feature in MacOS and can be disabled by tweaking some MacOS settings via terminal commands.
I wanted to do that programatically as this behaviour doesn’t make much sense for Terminal applications.

Finding information about this topic is really challanging even if the solution isn’t that complicated so I decided to leave that piece of information here so that someone else might stumble upon it.

Overriding MacOS default settings

The key to the desired behaviour is to override the ApplePressAndHoldEnabled setting for our application. This can be done by tweaking the integration layer of the Flutter app (the MacOs project).

Just extend the AppDelegate located in AppDelegate.swift by adding the following method:

override func applicationDidFinishLaunching(_ notification: Notification) {
    UserDefaults.standard.set(false, forKey: "ApplePressAndHoldEnabled");
}

That’s all. Now your application doesn’t trigger the accent popup any more.

Read more...

Software development

Enums in Dart are worth an extension

Enums in Dart are worth an extension

Dart is a relatively simple programming language.
In general this is a good thing as the number of possibilities and patterns you have to know in order to develop something with it or when reading code is lower.
On the other hand you will miss certain features that other programming languages have that can lead to quite elegant solutions for certain problems.

Enums int Dart are such a case.

Enums are very simple in Dart. In general they are classes / objects like everything else but you can’t do neat tricks with them like for example with C#.

Lets assume we have a byte value and want to read some bits of it. Those bits should have names (mapped to an enum) for better understandability.

Enums in C#

In C# there is a language feature for exactly that. You can use any enum to represent bits in a bitfield.

[Flags]
public enum FlagValues : byte
{
    None    = 0x00,
    Flag1 = 0x01 << 0,
    Flag2 = 0x01 << 1,
    Flag3 = 0x01 << 2,
    Flag4 = 0x01 << 3,
    Option4 = 0x01 << 4,
    All = 0xFF
};

// later in the code

byte val = 0x05; //00000101

var flags = (FlagValues) val;
flags.HasFlag(FlagValues.Flag1); // true
flags.HasFlag(FlagValues.Flag2); // false
flags.HasFlag(FlagValues.Flag3); // true
flags.HasFlag(FlagValues.Flag4); // false

You can even do bitwise operations directly with the enum like

FlagValues flags = FlagValues.Flag2;
flags |= FlagValues.Flag4;
Read more...

Software developmentProjects

Dart Isolates and huge amounts of data

Dart Isolates and huge amounts of data

Why?

I’m currently experimenting with Dart and Flutter to take another shot at the terminal emulation application. This time not using C# but something completely new.
For this I decided to take a look at Flutter and Dart and try to implement the terminal application using that technology.
Gladly there is already a person in the internet that is working on implementing the xterm protocol for Dart and also has a working Flutter UI that renders the terminal.
https://github.com/TerminalStudio/xterm.dart
This implementation is not yet finished and has a couple of problems but is a really good starting point to dig into a Dart and Flutter based development of a terminal application.
One “problem” of the solution is that the whole terminal logic happens in the UI thread. So I wanted to move that logic into a separate thread and only copy the UI state to the UI thread for the UI to show it.
I did this for the C# based approaches and it speeded up the performance (especially reflow) a lot.

Dart and threads

Dart has a very special way of handling threads. The designers have chosen to use an approach that rules out any race condition by design.

For this they decided that in Dart threads don’t have shared memory and they have to define so called ports for explicit data exchange (the data gets copied).
This is called an Isolate in Dart. So you can create and spawn a new Isolate, specify its “main” method and define the port to communicate with it.

Dart makes sure that the data that is sent to a port is serialized and deserialized on the other end. This way two Isolates never work on the same place in memory. By design.

Then comes the terminal

I tried this with the terminal logic and it worked but the performance gain from moving the xterm logic to a separate thread was completely eaten up by the overhead of copying the whole UI state for each change in the terminal state.

Read more...

Software developmentProjects

Current state (of the Terminal application)

Current state

I know, I know. I planned to do this much more frequently as it then happened. I will do my best to keep you updated with anything of interest here.
There has not been so much going on in terms of development or side projects mostly because the Terminal application project got stale and there no all-focus new side project yet.

I started reviewing my small Smart Home setup I have here and see where I can improve things. When this gets more concrete it might also be worth on or two blog posts.

Current state of the Terminal application

The Terminal application got a bit stale due to several reasons.
Starting point of all that was me starting to think about the UI for the additional features. Things like managing different profiles as a starting point.
I played around with a couple of ideas and did some prototypes and I didn’t like anyone of them. Not so much because of the UX they used but the design.
I basically faced the standard problem of cross platform UI development. Qt can have styles - yes - but you will never reach a state where the application feels “natural” on any platform. I think this is especially visible on MacOS as a MacOS user is not very used to seeing all different kind of visual approaches between different applications.
This topic blocked me from continuing because I can not see how I will end up with a Qt/Qml based solution that looks like a nice MacOS application. Even small things like using some blur effect that modern MacOs apps have would be a pain if at all possible.

So I decided to got some steps back, make a fork and try a completely different approach.
I wanted to use Xamarin Forms as it is cross platform as Qt but allows full control over the native experience where needed.
It also uses the native controls in the back so for the OS it is not only a Canvas where the application draws something. This means easier integration in things like accessibility and uses the look&feel of the underlying OS (which is a good thing)

Using Xamarin.Forms also allows to remove that Console Host layer completely because Qt has been the only reason to do this (some weird C++ library in .Net issue that leads to a crash when using forkpty). So I got another step back and reworked the complete backend.

I ported the frontend part to Xamarin.Forms (with some problems like input handling) and got it working. I basically used SkiaSharp to draw the terminal content and Xamarin.Forms to host it.

This took some evenings to finally work on MacOS and Linux and then I started thinking about “how to create a package?”.

Read more...

Software developmentProjects

At some point in time you have to let it go

At some point in time you have to let it go

Minimalistic Text is almost 10 years old. The first commit to the repository happened on 7th of November 2010.

How it began

I did not expect to create something that will reach the number of people Minimalistic Text did. It was basically just a try to create something for my new Smartphone (a Samsung Galaxy S). I was inspired by an application that already existed and was able to show the time as spoken text as a widget.

Recreating that widget and extending it by a first level of customization was basically the starting point. I started a thread over at Xda-Developers and immediately received great feedback. That encouraged me to extend the app step by step till it was a really feature packed text widget creator.

Generating income

At some point users wanted to know how they can contribute and donate some money for the app they use to make their homescreen look nice so I decided to create a donation system (separate app and in-app purchases) and to give the donators some benefit made new features available for the donators first. I also added Google Ads that were not shown for donators.
This generated some income that allowed me to buy a bunch of equipment like laptops or new smartphones. I had to test my app on the latest and greatest phones out there, right? ;)
It was not to a level that I get rich or could quit my day job but it allowed me to have some extra cash that could be invested in tech stuff.

AppStore feature

One day in January 2013 I received an email from Google that they consider featuring my app in the PlayStore. They had some requirements though (only the major ones listed here):

Read more...

Software developmentProjects

Creating a terminal application - frontend 2

Creating a terminal application - Frontend take 2

Recap

We remember that the current state of building the terminal application was creating the user interface. I tried to use HTML to do the formatting of the text which turned out to be way too slow.

So I had to find a different approach as I wanted to stick with QML and .Net (for the already mentioned reasons)

QML alternatives

In QML there are a few alternatives for getting a formatted text to the screen. We already had a look at the HTML approach.
Another approach is to create a QQuickPaintedItem. You can imagine that control to be a drawing surface inside your QML layout that then can use a QPainter and its drawing API to draw whatever it wants.

This works by deriving a class from QQuickPaintedItem, implement the paint method and use the passed QPainter instance to draw.
The paint method is called whenever the content has to be redrawn.
This new class then has to be registered as a QuickItem with the QmlEngine and can then be used like any other QuickItem in your layout.

The problem

Using .Net code and Qml.Net for bridging both worlds it is not possible to derive from a C++ class and register that with QML without changing the C++ part of Qml.Net.

Read more...

Software developmentProjects

Creating a terminal application - 3 - Frontend take 1

Creating a terminal application - Frontend take 1

Intro

The last post has been a while back. Sorry for that. I was busy with daily business and also the implementation of the terminal got a bit stuck. Now I’m back on track and can feed you with the latest development news.

The backend is only half way towards a complete terminal application. In fact it’s more 1/5 of the way.
The reason to use a terminal application other than the built in one is only its user interface. At least for normal operating systems where the built in terminal works as expected.

So it’s all about user interface and functionality.

As already mentioned I want to take the C# + QML route as it is a good way to dog food Qml.Net and also gain some more QML / Qt insights that help me with my day job. Win-Win :)

QML might not be the first choice when you need a UI that basically renders its main content all the time and also needs to be fairly fast in doing so. We don’t want to hold back the process we control with having it waiting for our UI to render.

Options

During the backend development I used a very simple QML UI. Basically a Label that got the whole text set whenever the terminal content updated. Performance was OK.
The problem starts with formatting the text. Terminals can have colors, text ranges can be bold or italic.
In any UI devkit I came across (Ok, leave out some of the embedded UI kits) there was a way to define text format for a subset of a string in a Label.
The MacTerminal that is part of the XtermSharp project also uses this feature of Cocoa.
QML also has something for this: HTML and CSS. Yes, you are still on a blog post that describes the UI for a terminal application.
So QML uses its already built in web capabilities to provide rich text formatting.

Read more...

Software developmentProjects

Creating a terminal application - 2 - Backend

Creating a terminal application - Backend

How Terminals work

Maybe not all of you know what goes on behind the scenes when you launch your Terminal.
The term “terminal” is from the 1970s (or even earlier) Wikipedia: Computer terminal. At this time you had a real terminal device that was built in a way so that the input/output part was separated from the computing part. There were different protocols used for those two parts to talk to each other.
A well known terminal has been the VT100 that introduces special escape codes to control e.g. the cursor or status lights.
The protocol used there is still what drives the Terminal of your operating system (at least the Unix based ones).

So given the history a terminal application today is still controlled using the same protocol by the process it talks to.
The terminal application is “only” handling user input and output. It connects to the underlying process (most of the time the default shell of your OS) via special pseudo terminal connections where it sends the user input to the shell process and receives the UI data from the shell process (using the protocol from the old days).

Hosting a shell process with DotNet

The first step in my endeavor to create a terminal application is to host the shell process. This has to be done in a special way to get a proper pseudo terminal connection.
It seems that DotNet has some problems on that end. There is something special in the dotnet process that makes the default fork mechanism that yields the pty (pseudoterminal) endpoints not working.
In a C++ program you would simply call forkpty (see man page) that does a unix style fork and returns the process id of the process launched and a file descriptor for the pty socket.
When you do that in a DotNet application it just doesn’t work.
This is why Miguel had to create a native library that executes the forkpty function to work around that problem. Source code

Of course this is not really nice as it means I have to compile platform specific code in order to make the process start work.
In one of the issues a maintainer of AvalonStudio (that also includes a Terminal component) mentioned another approach to launch the shell process that doesn’t involve native code Github issue.
This approach basically launches the running application again with a special argument that leads to an immediate (before anything else happens) fork. They have to do some special magic with the pty file descriptors so that the terminal application can communicate with the process.

So I had two options: Use Miguels approach to have classical fork but with native code or use the rather hacky approach of AvalonStudio to avoid native code.

I decided to use the AvalonStudio approach.

Read more...

Software developmentProjects

Creating a terminal application - 1 - Intro

Creating a terminal application - Intro

History

From time to time I have to maintain servers, connect to Raspberries or access my Synology Diskstation. All this is done via SSH connections.
On Windows I loved to use an app called MobaXTerm for this. It has some really convenient features. From getting a glimpse into the system parameters of the remote machine (CPU load, RAM, storage, …) to having a X Server running and getting the SSH connection configured so that X-forwarding works flawlessly.
But the best feature is getting a parallel SCP connection that can follow your current directory and provides the possibility to edit files using local applications by managing copying it locally and re-uploading it after it changed under the hood.

MacOS situation

For MacOS I can’t find a terminal client that provides the same functionality. Of course, there are plenty of terminal applications and there are also programs that allow SCP connections but not everything in one package. Not the all in one SSH toolbox.

Incident

I stumbled across a project from Miguel de Icaza (Mono founder) called XTermSharp. This is basically the terminal business logic that allows plugging the shell process underneath and an UI on top.
So I thought why not use QML.NET to build a UI for XTermSharp and build a terminal application I need myself? I’m a software developer after all.

Project start

So I decided to build my own terminal application.
I will update you with the current state of the terminal application and all the things I encounter along the way. Not sure about the frequency (this depends on the progress I make with the terminal application)

Read more...

Software developmentProjects

Why even consider switching from C++ for embedded UI SW development?

Why even consider switching from C++ for embedded UI SW development?

History

In the past, when the hardware was much more limited than today, the software for that hardware was a monolithic binary containing everything. The (embedded) OS, the drivers and the application itself.
The embedded operating systems evolved and introduced things like multi threading or something in the middle of threads and processes.
At that stage hardware resources were the biggest constraint so that switching from C to C++ was considered a crazy step. All those virtual tables that eat up RAM and ROM!
At that time the applications were rather simple. No complex UI flows or things like content that can be downloaded by the user.

Today

Fast forward to today.

We now have Linux as an operating system.
We have multiple processes running on that hardware.
We have downloadable content.
We have OTA updates.
We have much more complex UI software (Features, UX, Animations, states)

Of course we have much more resources than in the old days.

The switch to Linux is key here. This - at least in theory - allows us to use all kinds of technologies because Linux is a common target that is supported by a very high number of technology stacks.

The software got much more complex over the years. The requirements what a UI software in an household appliance should look like and what features it has to support raised dramatically.

Read more...

Software developmentMeta