Monitor progression

Monitor progression

Ultra wide monitor

For years was using a 34” UWQHD monitor from LC-Power, LC-M34-UWQHD-100-C. It was a cheap monitor, but it worked, and it was very wide.
LC-M34-UWQHD-100-C

While really getting used to that horizontal space I also was not really happy with the overall quality (picture and build) so one day in 2021 I decided that I need to upgrade my monitor.

At that time I had my 13” MacBook Pro and while the resolution of the monitor was OK it was not really ideal for macOS. I had to use the 100% size mode which is a bit too tiny for my taste. But the next natively supported resolution was just way too big.
There were some tools out there that tricked macOS into rendering a too big picture and then scaling it down to the resolution of the monitor, but those tools need to create a separate virtual screen buffer consumed quite a big portion of my RAM, so I stayed with that 100% scaling.
I used a CalDigit docking station to only plug one cable into my MacBook and have all the periphery connected which I really got used to and didn’t want to miss in any new setup.

Then I discovered the Dell lineup of monitors and saw an Ultra Wide monitor exactly the size of the LC-Power (34”, same resolution, DELL U3421WE) but with much better picture and build quality.
DELL U3421WE
The monitor also said that it has a docking station built in meaning I could get rid of that CalDigit as well, so I ordered one to test.

Once it arrived, and I set it up I was really happy with the picture quality and the overall build quality. The main issue was that I had to decide - in the on-screen menu - if I want to have a higher resolution / refresh rate or higher USB-C speed 🙁
The second - much more critical - issue was that the built-in network adapter seemed to not be compatible with our network system (AmplifiHD at that time, but that’s another story) meaning the moment I plugged the network cable into the monitor the whole network stopped working a few minutes after. This has caused quite a few complaints from family members until I found the cause of this issue 😅.

via GIPHY

Given that I was really happy with the picture quality and because there were no real alternatives (higher DPI) I decided to keep it and live with using the CalDigit Docking station for now.

Read more...

PersonalDev Setup

dart_apitool updates

dart_apitool updates

Recently dart_apitool got 2 significant updates. Thanks to all the contributors that made that possible.

1. More robust preparation step

dart_apitool makes local copies of the packages it analyzes

When dart_apitool analyzes packages it has to do some preparation steps in order to make sure the analysis run doesn’t have any issues:

  1. it has to remove any analysis_options.yaml because this file can limit the scope of the analyzer.
    This is OK if you want to e.g. exclude files from linting but dart_apitool needs to see all of your files to create a complete model of your public API.
  2. it has to remove an example project as it needs to run pub get to get the dependencies prepared and up-to-date for a successful analysis run.
    Some packages have examples bundled with them that sometimes reach into packages via relative paths that live outside the package directory. Those paths are valid inside the package’s repository but are not valid outside of it. A dart_package bundles those examples which means they also live inside the downloaded package and might have invalid relative path dependencies.
    As dart_apitool is not interested in those examples it can just remove them from the package directory and run pub get to get the dependencies.

To not interfer with a local copy of the package (in the pub cache or on disk) dart_apitool makes a temporary copy of the package before manipulating it.

why this is complex and created an issue

This works really well. In the past there has been a special issue if a package was referenced on disk and contains relative path depdendencies. To solve that issue dart_apitool had a functionality to analyzse those path dependencies to determine the directory structure it needs to copy to the temporary directory making the relative path dependencies still work.

In the meantime dart (or better: pub) has a new feature: pubspec_overrides.yaml.
This is a separate file that can be used to override dependencies in a pubspec.yaml. As dart_apitool only looked into the pubspec.yaml it didn’t see those overrides and therefore didn’t know about the relative path dependencies that might be defined in there.
A potential solution to that would have been to also parse the pubspec_overrides.yaml file and take the dependencies defined in there into account.

Read more...

Software developmentFlutter

Minimalistic Text will be unavaible in the Google Play Store

Minimalistic Text will be unavailable in the Google Play Store

This is a short notice to inform you that Minimalistic Text will be unavailable in the Google Play Store from September 1st, 2023.
The reason for this is that Google will increase the target API level restrictions for already existing apps. Till now those restrictions only applied to new apps or app updates but beginning of September they will also apply to already existing apps.
In practice this means that apps will only be visible by devices that still use the Android version that matches the target SDK version of the app.
For Minimalistic Text this means that it will only be visible by devices that still use Android 9 or older even though it technically would work on newer Android versions.
As the amount of changes that I would have to do in order to comply with the newer API level requirements and the fact that the core rendering part of Minimalistic Text uses Android APIs that change behavior when switching the target API level, I decided to not update the app anymore.

To still provide a way for users to download the app I will provide the APK file on my website.

I’m sorry for the inconvenience this causes.

Dart_apitool updates

Dart_apitool got an update!

The recent weeks I was working a bit on dart_apitool.
The major topics were:

Missing export detection

The way Dart allows to define the public API of a package can lead to situations in which the consumer of the API is able to receive an instance of a certain Type but can’t refer to that type directly (e.g. to define a variable or a parameter of that Type).

Let’s imagine a very simple dart package:

- lib
    - some_package.dart
    - src 
        - some_interface.dart
        - some_interface_impl.dart
        - used_type.dart

some_package.dart

export 'src/some_interface.dart'
export 'src/some_interface_impl.dart'

some_interface.dart

#import 'used_type.dart'

abstract class SomeInterface {
    UsedType doSomethingAndReturnInstance();
}
Read more...

Software developmentFlutter

Struggles with the Dart type system

Struggles with the Dart type system

How it began: dart_apitool bug fix

It all started with a bug fix in dart_apitool.
The bug was that dart_apitool detected a breaking change on any parameter type change. Most of the time this is correct but consider this change:

/// version 1
void someMethod(String someParameter);

/// version 2a
void someMethod(String? someParameter);

/// version 2b
void someMethod(Object someParameter);

Here the type of the parameter gets changed but in a non-breaking way.
Any already existing call to someMethod will work with version 2a and version 2b.
The reason for this is that widening the type makes the old type part of the supported type space for that parameter.
Of course this is only valid for types passed in (which is the case for this bug as it describes method parameters).

So the goal was clear: dart_apitool has to check if the old type is assignable to the new type to decide if that change is a breaking change or not.

Read more...

Software developmentFlutter

dart_apitool goes bmw-tech

dart_apitool goes bmw-tech

Today I have some exciting news to share!

Dart_apitool has been transferred to bmw-tech. The repository as well as the package on pub.dev are now under control of the BMW open source organization.

“Why?” You may ask

There are two major reasons for that move:

1. The need arose at BMW

Dart_apitool has been born out of a need in the “My BMW” development organization. The need for a tool that automatically can check correct semantic versioning of packages to avoid creating a mess when modularizing the app.
Puzzled by the realization that no such tool existed I took this as a challenge and made the development of dart_apitool my evening pet project.

2. BMW is the only user that I’m aware of

Besides not getting much traction in the Flutter community dart_apitool is used internally at BMW and already got some contributions from BMW colleagues.

I’m not sure why there is a lack of community traction. I can imagine those reasons:

Read more...

Software developmentFlutter

dart_apitool improvements

dart_apitool improvements

There has been some new development in dart_apitool.

I got some feedback from our internal “My BMW” app teams and from the Flutter community so dart_apitool has received some extensions, improvements and fixes the last months:

Read more...

Software development

Warp terminal

Warp terminal

The Terminal app is the Software developers best friend. This is the most used tool followed by the IDE (ignoring the Browser of course).
As you can see in the blog posts I did I experiment(-ed, more on that later) with building my own Terminal application so that I can stuff in all the features that I want to have in the terminal I use.

Sometimes you are so used to the status quo that you are not able to imagine that the tool you use so frequently could be so much better. The same thing happened to me with Terminal apps. The core of every terminal application was basically the same. The way you enter commands, the way your input gets mirrored, the way the output of the command gets shown and so on.
There are a few options to tweak things and enrich the capabilities of this experience like oh-my-zsh or Oh My Posh to name a few.

But then came Warp.

Read more...

Software development

Antlion ModMic Wireless

Antlion ModMic Wireless

This is just a small post about a small gadget I bought recently: The Antlion ModMic Wireless.

Headset issues

Headsets were always a bit problematic for me. Already “in the office” but even more so in a Home Office or hybrid setting.
This issue might be home-grown, but I really hate wired headsets. The cable is always in the way and regardless of the side the cable is at it always interferes with me operating the computer.
So I needed something wireless.
I already have a couple of Bluetooth headsets, but they are not good for voice communication. They have to switch to “HFS/HFP” mode to use the microphone which totally kills the audio quality. Another issue with them is that the microphone quality is lacking, so this was not a good option.
For some time I used my Gaming headset for Teams meetings at the home office. This worked quite good, although the sound quality is nothing I want to listen to music with.
As the Gaming headset started to break I decided to look for another solution.

Gaming Headsets

The big advantage of that Gaming Headset is that it is wireless using a proprietary 2.4GHz protocol. This means that the headset is not dependent on Bluetooth and the audio quality is good even with activated microphone.
Looking at the current market for Gaming Headsets revealed a couple of good options that could replace my old one but still not being a good option for listening to music.
Gaming headsets - especially the good ones - also tend to show off that they are gaming headsets. Not that this would be a problem, but I don’t want flashing LEDs on my headset in a Teams video call 😁 (I know that this can be turned off for most of them, but you get the point).
There are some Bluetooth headsets out there that get quite good microphone reviews, but they lack in music playback quality.

Read more...

Gadgets

Some dart_apitool updates

Some dart_apitool updates

In the recent months I have been working on some updates for dart_apitool.
The main changes I did were:

Removal of using model files

After thinking more about the use cases for the option to store a public API model to a file in order to use it later to diff against a new version I came to the conclusion that this won’t be used in practice very often.
The amount of maintenance needed to support loading older versions of models and support comparing that with a new model based on the current code base was too high for that feature not being used by anyone.
So I decided to just remove that feature completely.

via GIPHY

Generalization of “classes”

Dart_apitool already supported the analysis of real “classes”. As interfaces in Dart are just abstract classes they were supported automatically.
But there are other concepts in Dart, that are quite similar to classes but not exactly the same. Things like Mixins for example.
So I decided to change the API used in dart_apitool to handle all those entities as “interfaces”.

Required interface support

We had a problem with the sqflite package at work. It published an update to an internal package that broke our build. Using that as perfect feature request and integration test for dart_apitool I analyzed what exactly caused the issue.
Dart_apitool would not have been able to detect that breaking change. The reason for that is that it was not aware of the difference between “required” and “provided” interfaces.

Read more...

Software developmentFlutter