Cristian Adam

WSLg and Qt Creator

For the CMake presets feature presentation in Qt Creator 9 I needed a cross platform Windows and Linux screencast.

My Windows Arm64 laptop was the perfect platform for the use case of registering a CMake preset with a self built Qt.

Quickly I found out that I only had one option to run Qt Creator as a Linux application, and that’s via Ubuntu 22.04 running under Windows Subsystem For Linux GUI (WSLg).

That’s because there is no Virtual Box or VMware Player running on Windows Arm64.

Also I’ve tried using Hyper-V, which WSLg under the hood uses, but the Ubuntu 22.04 image wouldn’t boot.

WSL2 and WSLg was the way to go! I’ve installed Qt Creator via sudo apt install qtcreator and then started Qt Creator via the Windows shortcut named Qt Creator (Ubuntu-22.04)! This is a short cut for C:\Windows\System32\wslg.exe ~ -d Ubuntu-22.04 qtcreator

Qt Creator would look like this:

It’s very hard not to notice that the windows title bar looks a bit weird. The generic window icon, the mouse cursor that does strange theme changes, and the bit fat window borders!

My goal was to have Qt Creator 9 look similar on Windows 11 as a native Windows Arm64 application and as native Ubuntu 22.04 Linux application running with WSLg.

Windows native look

On Windows 11 I am using a 125% font scaling and having “Storm” (some sort of dark gray #4C4A48) as a Windows color with Show accent color on title bars and windows borders enabled.

This is how it looks below:

WSLg with Wayland

I’ve build Qt 6.4.0 and Qt Creator 9.0.1 myself. I decided to build the QtWayland module so that I can have my own compositor, with the hope that I could get the chance of fixing some of the issues that I mentioned above.

Which looks like this:

This doesn’t look necessarily better. The application icon is there, but there are no window borders, no resize cursors (not seen in the screencast), and no window shadows. The last part is not that important, I can’t live without, but the rest. Auch.

Improving the Wayland experience

I took a shot at hacking the qtwayland/src/plugins/decorations/bradient default Wayland decoration plugin to match my Windows 11 setup.

I was pretty happy with how it looks now heart

In order to achieve the Windows 11 look I had to change three things:

  1. fonts
  2. cursor theme
  3. Wayland “bradient” theme configuration

Fonts

Since I was running an Ubuntu Linux virtual machine on Windows and my goal was to have a similar look & feel as the Windows application, why not use the Windows fonts?

First I tried removing the Linux fonts. If you uninstall one font package Ubuntu Linux will install a fallback font package. So I had to issue multiple font removal commands:

sudo apt purge fonts-dejavu-core
sudo apt purge fonts-dejavu-core ttf-bitstream-vera
sudo apt purge fonts-dejavu-core ttf-bitstream-vera fonts-liberation
sudo apt purge fonts-dejavu-core ttf-bitstream-vera fonts-liberation fonts-liberation2 fonts-croscore
sudo apt purge fonts-dejavu-core ttf-bitstream-vera fonts-liberation fonts-liberation2 fonts-croscore fonts-freefont-otf
sudo apt purge fonts-dejavu-core ttf-bitstream-vera fonts-liberation fonts-liberation2 fonts-croscore fonts-freefont-otf fonts-freefont-ttf
sudo apt purge fonts-dejavu-core ttf-bitstream-vera fonts-liberation fonts-liberation2 fonts-croscore fonts-freefont-otf fonts-freefont-ttf fonts-urw-base35

Then I edited the /etc/fonts/local.conf file with the content:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <dir>/mnt/c/Windows/Fonts</dir>

    <match target="font" >
        <edit mode="assign" name="lcdfilter" >
            <const>lcddefault</const>
        </edit>
        <edit mode="assign" name="hinting" >
            <bool>true</bool>
        </edit>
        <edit mode="assign" name="hintstyle" >
            <const>hintslight</const>
        </edit>
        <edit mode="assign" name="rgba" >
            <const>rgb</const>
        </edit>
        <edit mode="assign" name="antialias">
            <bool>true</bool>
        </edit>
    </match>

    <alias>
        <family>sans-serif</family>
        <prefer>
            <family>Segoe UI</family>
        </prefer>
    </alias>

    <match target="pattern">
        <test qual="any" name="family"><string>monospace</string></test>
        <edit name="family" mode="assign" binding="same"><string>Courier New</string></edit>
    </match>
    <match target="pattern">
        <test qual="any" name="family"><string>DejaVu LGC Sans</string></test>
        <edit name="family" mode="assign" binding="same"><string>Segoe UI</string></edit>
    </match>

</fontconfig>

And finally I’ve updated the font database sudo fc-cache -f -v. This was my best attempt at having a Windows like font rendering with the Windows fonts and some fonts substitutions for Qt Creator.

In order to have a bigger font in Qt Creator I had to have the following environment variable set:

QT_WAYLAND_FORCE_DPI=120

Funnily enough 125 was bigger than what Windows would set for 125%.

Cursor theme

Ubuntu 22.04 comes with a basic X11 font theme. I’ve installed one from KDE which had more cursors and looked nicer:

sudo apt install breeze-cursor-theme

Quickly I noticed that the mouse cursors are HUGE, in order to have them at proper size, I needed to have the following environment variable set:

XCURSOR_SIZE=16

Wayland “bradient” theme

First I hacked Qt Wayland’s qtwayland/src/plugins/decorations/bradient plugin with this qtwayland-6.4.0-bradient-windows11.patch. This was my first time trying to hack a theme plugin. It’s not perfect, but it’s good enough for me.

Now the plugin looks after a few environment variables in order to configure the window titlebar colors, the border colors, the alignment of the window title, and so on.

As it turns out the Windows 11 shortcut dialog has a limit on the edit line for the executable, and I was not able to pass all the parameters to the shortcut.

I had to use a WScript script to achieve this:

function wslgLink() {
  var commandArguments = "";
  for (var i = 0; i < arguments.length; ++i) {
    commandArguments += arguments[i] + " ";
  }

  var shell = new ActiveXObject("WScript.Shell");

  var strStartMenu = shell.SpecialFolders("StartMenu")
  var shortcut = shell.CreateShortcut(strStartMenu + "\\Programs\\Qt Creator Linux.lnk")
  shortcut.WindowStyle = 4;
  shortcut.IconLocation = "%userProfile%\\wsl\\qtcreator.ico";
  shortcut.TargetPath = "c:\\windows\\system32\\wslg.exe"
  shortcut.Arguments = commandArguments;
  shortcut.WorkingDirectory = "c:\\windows\\system32";
  shortcut.Save()
}

wslgLink(
  "-d Ubuntu-22.04",
  "QT_WAYLAND_FORCE_DPI=120",
  "XCURSOR_SIZE=16",
  "QT_WAYLAND_DECORATION_FG_COLOR=#ffffff",
  "QT_WAYLAND_DECORATION_FG_INACTIVE_COLOR=#919191",
  "QT_WAYLAND_DECORATION_BG_COLOR=#4c4a48",
  "QT_WAYLAND_DECORATION_BG_INACTIVE_COLOR=#f3f3f3",
  "QT_WAYLAND_DECORATION_BORDER_COLOR=#4c4a48",
  "QT_WAYLAND_DECORATION_BORDER_INACTIVE_COLOR=#b3b3b3",
  "QT_WAYLAND_BUTTONS_HOVER_BG_COLOR=#575553",
  "QT_WAYLAND_CLOSE_BUTTON_HOVER_BG_COLOR=#C42B1C",
  "QT_WAYLAND_DECORATION_LEFT_WINDOW_TEXT=1",
  "~/Qt/qtcreator/bin/qtcreator"
);

For a dark Windows theme the following values work better:

  "QT_WAYLAND_DECORATION_BG_INACTIVE_COLOR=#202020",
  "QT_WAYLAND_DECORATION_BORDER_INACTIVE_COLOR=#2F3039",

You can get the Qt Creator icon with a Linux overlay from here.

Conclusion

I was able to run Qt Creator 9.0.1 both for Windows 11 arm64 natively and Ubuntu 22.04 having a consistent Windows 11 look and feel! metal

Oh, one more thing. My Ubuntu 22.04 WSL2 installation got only 1GB of swap, which is not enough to compile LLVM / Clang for example. I had to edit the Windows %userprofile%\.wslconfig ini file with the following content:

[wsl2]
swap=16GB
swapFile=%USERPROFILE%\wsl2swap.vhdx

Comments