<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Software on dev@iostream.pl</title><link>https://lvajxi03.github.io/categories/software/</link><description>Recent content in Software on dev@iostream.pl</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 05 Oct 2026 15:05:00 +0200</lastBuildDate><atom:link href="https://lvajxi03.github.io/categories/software/index.xml" rel="self" type="application/rss+xml"/><item><title>Escape from the Tropics</title><link>https://lvajxi03.github.io/posts/2026-10-05/</link><pubDate>Mon, 05 Oct 2026 15:05:00 +0200</pubDate><guid>https://lvajxi03.github.io/posts/2026-10-05/</guid><description>&lt;p&gt;&lt;strong&gt;KDE Plasma&lt;/strong&gt; is a remarkably pleasant environment for work — and for pretty much everything else — so there is very little to complain about.&lt;/p&gt;
&lt;p&gt;However, since I have already taken the first steps toward moving completely to &lt;strong&gt;FVWM3&lt;/strong&gt;, a little consistency seems appropriate.&lt;/p&gt;
&lt;p&gt;It is time to start replacing some of the applications from the KDE ecosystem as well.&lt;/p&gt;
&lt;p&gt;Not all at once.&lt;/p&gt;
&lt;p&gt;No need to panic.&lt;/p&gt;
&lt;p&gt;First, we need a survival kit.&lt;/p&gt;
&lt;h1 id="minimal-version"&gt;Minimal Version
&lt;/h1&gt;&lt;p&gt;The absolute minimum I would find difficult to live without is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;another terminal → &lt;strong&gt;Alacritty&lt;/strong&gt;, because why not,&lt;/li&gt;
&lt;li&gt;another file manager → &lt;strong&gt;PCManFM-Qt&lt;/strong&gt; — I used its GTK ancestor about twenty years ago, so now the Qt version gets a chance,&lt;/li&gt;
&lt;li&gt;Qt appearance configuration → &lt;strong&gt;qt6ct&lt;/strong&gt; — without it, surprises await,&lt;/li&gt;
&lt;li&gt;somewhat more deliberate wallpaper handling → &lt;strong&gt;feh&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a launcher slightly more sophisticated than &lt;code&gt;dmenu&lt;/code&gt; → &lt;strong&gt;rofi&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;display configuration management → &lt;strong&gt;autorandr&lt;/strong&gt; and &lt;strong&gt;arandr&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is one additional detail with &lt;code&gt;qt6ct&lt;/code&gt;: Qt applications need to know that they are supposed to use it.&lt;/p&gt;
&lt;p&gt;An FVWM session will therefore eventually need something along the lines of:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export QT_QPA_PLATFORMTHEME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;qt6ct
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Simply installing &lt;code&gt;qt6ct&lt;/code&gt; does not magically make it take control of every Qt application.&lt;/p&gt;
&lt;p&gt;Unfortunately.&lt;/p&gt;
&lt;p&gt;The magic comes later.&lt;/p&gt;
&lt;h1 id="standard-version"&gt;Standard Version
&lt;/h1&gt;&lt;p&gt;The standard version contains everything from the minimal one, plus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bluetooth device management → &lt;strong&gt;blueman&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;display brightness control → &lt;strong&gt;brightnessctl&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;notifications → &lt;strong&gt;dunst&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a PolicyKit authentication agent → &lt;strong&gt;lxqt-policykit&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;screenshots → &lt;strong&gt;flameshot&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;NetworkManager connection management → &lt;strong&gt;network-manager-applet&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;an audio mixer → &lt;strong&gt;pavucontrol&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;an X11 compositor → &lt;strong&gt;picom&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;media-player control → &lt;strong&gt;playerctl&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;automatic removable-media mounting through UDisks → &lt;strong&gt;udiskie&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a volume-control applet → &lt;strong&gt;volumeicon&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a second terminal, for variety → &lt;strong&gt;qterminal&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a system tray → &lt;strong&gt;stalonetray&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, an innocent little window manager starts looking suspiciously like a desktop environment.&lt;/p&gt;
&lt;p&gt;But that is fine.&lt;/p&gt;
&lt;p&gt;We still know exactly what it consists of.&lt;/p&gt;
&lt;h1 id="full-version"&gt;Full Version
&lt;/h1&gt;&lt;p&gt;Naturally, the &lt;em&gt;full&lt;/em&gt; version requires the standard version and all of its dependencies, and adds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;yet another terminal, just to prevent boredom → &lt;strong&gt;kitty&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;another file manager → &lt;strong&gt;Thunar&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Three terminals may sound excessive.&lt;/p&gt;
&lt;p&gt;They are not.&lt;/p&gt;
&lt;h1 id="rpm-packages"&gt;RPM Packages
&lt;/h1&gt;&lt;p&gt;Since &lt;strong&gt;Fedora&lt;/strong&gt; is now my main operating system, there is an obvious next step:&lt;/p&gt;
&lt;p&gt;package all of this as RPMs.&lt;/p&gt;
&lt;p&gt;Right?&lt;/p&gt;
&lt;p&gt;Right.&lt;/p&gt;
&lt;p&gt;The packages do not even need to contain any programs or configuration files of their own.&lt;/p&gt;
&lt;p&gt;What we need are &lt;strong&gt;metapackages&lt;/strong&gt; — almost empty RPM packages whose main purpose is to depend on other packages.&lt;/p&gt;
&lt;p&gt;Instead of remembering fifteen package names, I should eventually be able to type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install kde-refugee-pack-standard
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and be done with it.&lt;/p&gt;
&lt;h2 id="tools"&gt;Tools
&lt;/h2&gt;&lt;p&gt;First, install the basic RPM-building tools:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install rpm-build rpmdevtools rpmlint
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the standard build tree:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpmdev-setuptree
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and generate a fresh spec template:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpmdev-newspec my-package.spec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A typical spec template contains fields such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Name&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Version&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Release&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Summary&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;License&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;URL&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Source&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BuildRequires&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Requires&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also contains sections such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%description&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%prep&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%build&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%install&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%files&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%changelog&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a package consisting entirely of dependencies, most of these are unnecessary.&lt;/p&gt;
&lt;p&gt;There are no sources.&lt;/p&gt;
&lt;p&gt;There is nothing to compile.&lt;/p&gt;
&lt;p&gt;There is not even anything to install into the filesystem.&lt;/p&gt;
&lt;h2 id="minimal"&gt;Minimal
&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;kde-refugee-pack-minimal.spec&lt;/code&gt; file can therefore look like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-rpm" data-lang="rpm"&gt;Name: kde-refugee-pack-minimal
Version: 0.0.1
Release: 1%{?dist}
Summary: KDE refugee pack, minimal version

License: MIT
BuildArch: noarch

Requires: alacritty
Requires: qt6ct
Requires: pcmanfm-qt
Requires: feh
Requires: rofi
Requires: autorandr
Requires: arandr

%description
Mandatory metapackage for everyone who leaves KDE for fvwm3
(minimal version)

%files

%changelog
* Sat Oct 03 2026 Marcin Bielewicz &amp;lt;marcin.bielewicz@gmail.com&amp;gt;
- initial version
&lt;/code&gt;&lt;/pre&gt;
 &lt;blockquote&gt;
 &lt;p&gt;Important: keep the empty &lt;code&gt;%files&lt;/code&gt; section.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;The package does not contain any files, but we still want &lt;code&gt;rpmbuild&lt;/code&gt; to produce a binary RPM.&lt;/p&gt;
&lt;p&gt;That is its entire purpose:&lt;/p&gt;
&lt;p&gt;to exist and require other packages.&lt;/p&gt;
&lt;h2 id="standard"&gt;Standard
&lt;/h2&gt;&lt;p&gt;The next level depends on the first one:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-rpm" data-lang="rpm"&gt;Name: kde-refugee-pack-standard
Version: 0.0.1
Release: 1%{?dist}
Summary: KDE refugee pack, standard version

License: MIT
BuildArch: noarch

Requires: kde-refugee-pack-minimal = %{version}
Requires: blueman
Requires: brightnessctl
Requires: dunst
Requires: flameshot
Requires: lxqt-policykit
Requires: network-manager-applet
Requires: pavucontrol
Requires: picom
Requires: playerctl
Requires: udiskie
Requires: volumeicon
Requires: qterminal
Requires: stalonetray

%description
Mandatory metapackage for everyone who leaves KDE for fvwm3
(standard version)

%files

%changelog
* Sat Oct 03 2026 Marcin Bielewicz &amp;lt;marcin.bielewicz@gmail.com&amp;gt;
- initial version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The important line is:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-rpm" data-lang="rpm"&gt;Requires: kde-refugee-pack-minimal = %{version}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which means:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;I require &lt;code&gt;kde-refugee-pack-minimal&lt;/code&gt; in the same version as this package.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Of course, this could be written explicitly:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-rpm" data-lang="rpm"&gt;Requires: kde-refugee-pack-minimal = 0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but &lt;code&gt;%{version}&lt;/code&gt; saves us from having to remember to change it in the next release.&lt;/p&gt;
&lt;p&gt;Laziness.&lt;/p&gt;
&lt;p&gt;Once again, the driving force behind computer science.&lt;/p&gt;
&lt;h2 id="full"&gt;Full
&lt;/h2&gt;&lt;p&gt;The final level:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-rpm" data-lang="rpm"&gt;Name: kde-refugee-pack-full
Version: 0.0.1
Release: 1%{?dist}
Summary: KDE refugee pack, full version

License: MIT
BuildArch: noarch

Requires: kde-refugee-pack-standard = %{version}
Requires: kitty
Requires: Thunar

%description
Mandatory metapackage for everyone who leaves KDE for fvwm3
(full version)

%files

%changelog
* Sat Oct 03 2026 Marcin Bielewicz &amp;lt;marcin.bielewicz@gmail.com&amp;gt;
- initial version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This gives us a dependency chain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;full
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── standard
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── minimal
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;with each level adding its own collection of tools.&lt;/p&gt;
&lt;h1 id="building-the-packages"&gt;Building the Packages
&lt;/h1&gt;&lt;p&gt;A binary RPM can be built with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpmbuild -bb package.spec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The result will normally appear under:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;~/rpmbuild/RPMS/noarch/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;-bb&lt;/code&gt; option builds the binary package only.&lt;/p&gt;
&lt;p&gt;If we also want an SRPM:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpmbuild -ba package.spec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is what I will use in CI.&lt;/p&gt;
&lt;p&gt;If the computer is doing the work anyway, there is little reason to stop it.&lt;/p&gt;
&lt;h1 id="installing-the-packages"&gt;Installing the Packages
&lt;/h1&gt;&lt;p&gt;A local RPM can be installed through DNF:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install ./package.rpm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;./&lt;/code&gt; matters: it tells DNF that this is a local file rather than a package name to search for in configured repositories.&lt;/p&gt;
&lt;p&gt;DNF then resolves and installs the dependencies.&lt;/p&gt;
&lt;p&gt;Which was the whole point of this exercise.&lt;/p&gt;
&lt;h1 id="github-actions"&gt;GitHub Actions
&lt;/h1&gt;&lt;p&gt;Once the spec files live in a repository, rebuilding them manually every time starts looking suspiciously like a task that could be automated.&lt;/p&gt;
&lt;p&gt;Tasks like that are dangerous.&lt;/p&gt;
&lt;p&gt;They tend to produce CI pipelines.&lt;/p&gt;
&lt;p&gt;The workflow can look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Build RPM packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;specs/**&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;.github/workflows/rpm.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;pull_request&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;specs/**&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;.github/workflows/rpm.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;permissions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;contents&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Build ${{ matrix.package }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;strategy&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;fail-fast&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;matrix&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;package&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-minimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-standard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-full&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;fedora:44&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Install build tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dnf install -y \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; findutils \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpm-build \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpmdevtools \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpmlint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Checkout repository&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Prepare rpmbuild tree&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;rpmdev-setuptree&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Copy spec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; cp specs/${{ matrix.package }}.spec ~/rpmbuild/SPECS/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Lint spec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpmlint specs/${{ matrix.package }}.spec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Build RPM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpmbuild -ba ~/rpmbuild/SPECS/${{ matrix.package }}.spec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Show result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; find ~/rpmbuild/RPMS ~/rpmbuild/SRPMS -type f -print&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Collect build artifacts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; mkdir -p artifacts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; cp ~/rpmbuild/RPMS/noarch/*.rpm artifacts/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; cp ~/rpmbuild/SRPMS/*.src.rpm artifacts/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Upload build bundle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/upload-artifact@v7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bundle-${{ matrix.package }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;artifacts/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Upload binary RPM directly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/upload-artifact@v7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;~/rpmbuild/RPMS/noarch/${{ matrix.package }}-*.noarch.rpm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;archive&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;install-test&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Test package installation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;needs&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;fedora:44&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Download kde-refugee-pack-minimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/download-artifact@v8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bundle-kde-refugee-pack-minimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;rpms/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Download kde-refugee-pack-standard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/download-artifact@v8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bundle-kde-refugee-pack-standard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;rpms/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Download kde-refugee-pack-full&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/download-artifact@v8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bundle-kde-refugee-pack-full&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;rpms/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Install refugee pack&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dnf install -y \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpms/kde-refugee-pack-minimal-*.noarch.rpm \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpms/kde-refugee-pack-standard-*.noarch.rpm \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rpms/kde-refugee-pack-full-*.noarch.rpm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At first glance, this line may look odd:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We are building Fedora packages, after all.&lt;/p&gt;
&lt;p&gt;A few lines later, however:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;container&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;fedora:44&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GitHub provides the runner, while the job itself executes in a Fedora 44 environment.&lt;/p&gt;
&lt;p&gt;There is no need for a separate Fedora runner.&lt;/p&gt;
&lt;p&gt;The matrix:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;matrix&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;package&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-minimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-standard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;kde-refugee-pack-full&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;creates three independent builds.&lt;/p&gt;
&lt;p&gt;Each spec file is checked with &lt;code&gt;rpmlint&lt;/code&gt;, built, and stored as an artifact.&lt;/p&gt;
&lt;p&gt;And this is where things become pleasantly convenient.&lt;/p&gt;
&lt;p&gt;A normal artifact upload creates an archive containing the RPM and SRPM.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;actions/upload-artifact@v7&lt;/code&gt; also supports:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;archive&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;for a single file.&lt;/p&gt;
&lt;p&gt;So every binary RPM is additionally available directly as an &lt;code&gt;.rpm&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;No ZIP extraction required.&lt;/p&gt;
&lt;p&gt;Like civilized people.&lt;/p&gt;
&lt;p&gt;The second job downloads all three build bundles and tries to install the packages on a fresh Fedora environment.&lt;/p&gt;
&lt;p&gt;The workflow therefore verifies more than:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;the RPM builds.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;It also verifies:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;DNF can resolve the dependency chain and install all three levels.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;And because the workflow itself lives at:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.github/workflows/rpm.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;while the path filter contains:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;specs/**&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;.github/workflows/rpm.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;changing the workflow itself triggers another run.&lt;/p&gt;
&lt;p&gt;The pipeline therefore tests, among other things, itself.&lt;/p&gt;
&lt;h1 id="summary"&gt;Summary
&lt;/h1&gt;&lt;p&gt;A small joke of a task somehow grew into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a list of programs I will actually use,&lt;/li&gt;
&lt;li&gt;three levels of a KDE survival kit,&lt;/li&gt;
&lt;li&gt;three RPM metapackages,&lt;/li&gt;
&lt;li&gt;automated linting,&lt;/li&gt;
&lt;li&gt;automated builds,&lt;/li&gt;
&lt;li&gt;an installation test,&lt;/li&gt;
&lt;li&gt;artifacts available both as bundles and directly as RPM files,&lt;/li&gt;
&lt;li&gt;and a GitHub repository: &lt;a class="link" href="https://github.com/lvajxi03/specfiles/" target="_blank" rel="noopener"
 &gt;specfiles&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All because I did not want to type a dozen package names by hand.&lt;/p&gt;
&lt;p&gt;It was laziness, Your Honor.&lt;/p&gt;</description></item><item><title>A Window Manager Unlike Any Other</title><link>https://lvajxi03.github.io/posts/2026-09-28/</link><pubDate>Mon, 28 Sep 2026 19:10:00 +0200</pubDate><guid>https://lvajxi03.github.io/posts/2026-09-28/</guid><description>&lt;p&gt;Thirty-three years is a very long time in software.&lt;/p&gt;
&lt;p&gt;Trends change.&lt;/p&gt;
&lt;p&gt;Architectures come and go.&lt;/p&gt;
&lt;p&gt;Companies collapse, occasionally taking genuinely excellent projects to the grave with them.&lt;/p&gt;
&lt;p&gt;It is long enough that, back in 1993, I was considering moving from a Commodore 64 to an Amiga 500 — which never actually happened — while in 2026 I find myself interested in software from that same era which somehow still exists.&lt;/p&gt;
&lt;p&gt;And not merely exists.&lt;/p&gt;
&lt;p&gt;Some of it is doing remarkably well.&lt;/p&gt;
&lt;p&gt;In 1993, engineer &lt;strong&gt;Robert Nation&lt;/strong&gt; needed a lightweight window manager for a 33 MHz 486 laptop with just 4 MB of RAM.&lt;/p&gt;
&lt;p&gt;At the same time, his work involved analyzing enormous spectrograms, and he needed a virtual desktop larger than a single physical screen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TWM&lt;/strong&gt; worked, but it consumed more memory than he liked and did not provide everything he needed.&lt;/p&gt;
&lt;p&gt;So he did what any reasonable programmer dissatisfied with an existing tool would do:&lt;/p&gt;
&lt;p&gt;he started taking it apart.&lt;/p&gt;
&lt;p&gt;The result was &lt;strong&gt;FVWM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Its first public version was bundled with an &lt;code&gt;rxvt&lt;/code&gt; release on June 1, 1993. Soon afterward FVWM became an independent project, and it is still with us today.&lt;/p&gt;
&lt;p&gt;Despite more than three decades of development, it has retained much of its original character:&lt;/p&gt;
&lt;p&gt;it is lightweight, modular, extraordinarily configurable, and assumes that the user may actually know how their own desktop should behave.&lt;/p&gt;
&lt;h1 id="f-vwm"&gt;F? VWM
&lt;/h1&gt;&lt;p&gt;So what does the name mean?&lt;/p&gt;
&lt;p&gt;Today the official project calls it:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;F? Virtual Window Manager&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;where &lt;code&gt;F?&lt;/code&gt; can be expanded into almost anything beginning with the letter F.&lt;/p&gt;
&lt;p&gt;Preferably something printable.&lt;/p&gt;
&lt;p&gt;Originally, however, the &lt;code&gt;F&lt;/code&gt; had a very specific meaning:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Feeble Virtual Window Manager&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Robert Nation himself confirmed this, explaining that the earliest versions offered very few user-selectable features, so &lt;em&gt;feeble&lt;/em&gt; was a fairly accurate description.&lt;/p&gt;
&lt;p&gt;The software eventually stopped being feeble in any meaningful sense, while the interpretation of the letter F drifted into folklore.&lt;/p&gt;
&lt;p&gt;The modern project page suggests words such as:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;fantastic, fabulous, famous, flexible&amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;and wisely leaves the rest to the user&amp;rsquo;s imagination.&lt;/p&gt;
&lt;h2 id="what-exactly-is-a-window-manager"&gt;What Exactly Is a Window Manager?
&lt;/h2&gt;&lt;p&gt;That is a reasonable question.&lt;/p&gt;
&lt;p&gt;What sort of software is this?&lt;/p&gt;
&lt;p&gt;And why should anyone care?&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;window manager&lt;/strong&gt; manages application windows within a graphical session.&lt;/p&gt;
&lt;p&gt;In the X11 world it is responsible for things such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;window placement,&lt;/li&gt;
&lt;li&gt;size,&lt;/li&gt;
&lt;li&gt;stacking order,&lt;/li&gt;
&lt;li&gt;focus,&lt;/li&gt;
&lt;li&gt;decorations,&lt;/li&gt;
&lt;li&gt;minimization,&lt;/li&gt;
&lt;li&gt;maximization,&lt;/li&gt;
&lt;li&gt;switching between windows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An application creates a window.&lt;/p&gt;
&lt;p&gt;The window manager decides what happens to it next.&lt;/p&gt;
&lt;p&gt;And that is all?&lt;/p&gt;
&lt;p&gt;More or less.&lt;/p&gt;
&lt;p&gt;Which is exactly what makes the idea interesting.&lt;/p&gt;
&lt;p&gt;GNOME, KDE Plasma, Xfce, and LXQt are complete &lt;strong&gt;desktop environments&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;They are collections of cooperating components that usually provide things such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;panels,&lt;/li&gt;
&lt;li&gt;menus,&lt;/li&gt;
&lt;li&gt;session management,&lt;/li&gt;
&lt;li&gt;display configuration,&lt;/li&gt;
&lt;li&gt;settings tools,&lt;/li&gt;
&lt;li&gt;notifications,&lt;/li&gt;
&lt;li&gt;desktop icons,&lt;/li&gt;
&lt;li&gt;wallpapers,&lt;/li&gt;
&lt;li&gt;device integration,&lt;/li&gt;
&lt;li&gt;often an entire set of applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A window manager is only one part of that puzzle.&lt;/p&gt;
&lt;p&gt;In the old days, an X11 desktop was often assembled gradually.&lt;/p&gt;
&lt;p&gt;Need a panel?&lt;/p&gt;
&lt;p&gt;Install one.&lt;/p&gt;
&lt;p&gt;Need a menu?&lt;/p&gt;
&lt;p&gt;Add one.&lt;/p&gt;
&lt;p&gt;Want a wallpaper?&lt;/p&gt;
&lt;p&gt;Run a wallpaper setter.&lt;/p&gt;
&lt;p&gt;Need desktop icons, a notification area, media controls, or animated penguins wandering around the screen?&lt;/p&gt;
&lt;p&gt;No problem.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xpenguins&lt;/code&gt; is waiting.&lt;/p&gt;
&lt;p&gt;Today, we are much more likely to install an entire desktop environment and accept whatever came from the factory.&lt;/p&gt;
&lt;p&gt;And the factory keeps providing more.&lt;/p&gt;
&lt;p&gt;Increasingly tightly integrated.&lt;/p&gt;
&lt;p&gt;Eleven out of ten users never even change the wallpaper.&lt;/p&gt;
&lt;h2 id="what-does-fvwm-provide"&gt;What Does FVWM Provide?
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;FVWM&lt;/strong&gt; is a classic window manager in exactly that older tradition.&lt;/p&gt;
&lt;p&gt;Its primary concern is windows and how they behave.&lt;/p&gt;
&lt;p&gt;Want a panel?&lt;/p&gt;
&lt;p&gt;You can have one.&lt;/p&gt;
&lt;p&gt;Menus?&lt;/p&gt;
&lt;p&gt;Of course.&lt;/p&gt;
&lt;p&gt;A pager?&lt;/p&gt;
&lt;p&gt;Certainly.&lt;/p&gt;
&lt;p&gt;A window list?&lt;/p&gt;
&lt;p&gt;Also available.&lt;/p&gt;
&lt;p&gt;But FVWM does not assume that its developers know better than you how all of those things should look or behave.&lt;/p&gt;
&lt;p&gt;The default configuration provides enough to get started and then seems to say:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Run me.&lt;br&gt;
Use me.&lt;br&gt;
Decide what is missing.&lt;br&gt;
Then configure it yourself.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;That is what its extensive configuration system is for.&lt;/p&gt;
&lt;p&gt;The official project describes FVWM3 as a lightweight floating window manager for X11 that can be configured as anything from a small minimal setup to something resembling a complete desktop environment.&lt;/p&gt;
&lt;h1 id="installation"&gt;Installation
&lt;/h1&gt;&lt;p&gt;I assume you already have &lt;em&gt;some&lt;/em&gt; graphical environment installed.&lt;/p&gt;
&lt;p&gt;Modern Linux distributions usually come with KDE, GNOME, Xfce, LXQt, or something similar.&lt;/p&gt;
&lt;p&gt;You therefore probably also have a display manager.&lt;/p&gt;
&lt;p&gt;In my case, this is &lt;strong&gt;Fedora with KDE Plasma and SDDM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Installation is straightforward:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install fvwm3 dmenu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first package contains &lt;strong&gt;FVWM3&lt;/strong&gt; itself.&lt;/p&gt;
&lt;p&gt;The second provides &lt;code&gt;dmenu&lt;/code&gt;, which the default FVWM configuration uses as a simple application launcher.&lt;/p&gt;
&lt;p&gt;It is worth checking that the package installed an X session definition:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpm -ql fvwm3 | grep xsessions
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On my system:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/share/xsessions/fvwm3.desktop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Excellent.&lt;/p&gt;
&lt;p&gt;Log out.&lt;/p&gt;
&lt;p&gt;Select &lt;strong&gt;FVWM3&lt;/strong&gt; on the login screen.&lt;/p&gt;
&lt;p&gt;Enter the password.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And&amp;hellip;&lt;/p&gt;
&lt;h1 id="hello-darkness"&gt;Hello Darkness
&lt;/h1&gt;&lt;p&gt;&amp;hellip;enjoy the majestic sight of absolutely nothing.&lt;/p&gt;
&lt;p&gt;The session did not start.&lt;/p&gt;
&lt;p&gt;The reason turned out to be simple:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FVWM3 is an X11 window manager&lt;/strong&gt;, while my Fedora installation only had Wayland available.&lt;/p&gt;
&lt;p&gt;FVWM3 is still primarily built around Xlib and the X Window System.&lt;/p&gt;
&lt;p&gt;So Xorg needs to be installed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install xorg-x11-server-Xorg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fedora 44 still ships Xorg separately for X11 sessions and software that depends on it.&lt;/p&gt;
&lt;p&gt;Log in once more.&lt;/p&gt;
&lt;p&gt;Ah.&lt;/p&gt;
&lt;p&gt;Much better.&lt;/p&gt;
&lt;h2 id="configuring-x11"&gt;Configuring X11
&lt;/h2&gt;&lt;p&gt;The biggest surprise after all these years is that X11 no longer needs to be configured.&lt;/p&gt;
&lt;p&gt;It simply starts.&lt;/p&gt;
&lt;p&gt;And works.&lt;/p&gt;
&lt;p&gt;There is no need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;select graphics drivers manually,&lt;/li&gt;
&lt;li&gt;describe the monitor,&lt;/li&gt;
&lt;li&gt;write &lt;code&gt;Modeline&lt;/code&gt; entries,&lt;/li&gt;
&lt;li&gt;configure the mouse,&lt;/li&gt;
&lt;li&gt;configure the keyboard,&lt;/li&gt;
&lt;li&gt;specify font directories.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I remember a time when starting X11 and getting a black screen instead of smoke already counted as progress.&lt;/p&gt;
&lt;p&gt;Today it simply works.&lt;/p&gt;
&lt;p&gt;Thank you, 2026.&lt;/p&gt;
&lt;h1 id="first-start"&gt;First Start
&lt;/h1&gt;&lt;p&gt;The default &lt;strong&gt;FVWM3&lt;/strong&gt; session looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Default session" class="gallery-image" data-flex-basis="426px" data-flex-grow="177" height="1080" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-1.png" srcset="https://lvajxi03.github.io/posts/2026-09-28/fvwm-1_hu_ccb8a2f3b24802da.png 800w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-1_hu_1d0e9028cb527683.png 1600w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-1.png 1920w" width="1920"&gt;&lt;/p&gt;
&lt;p&gt;What exactly are we looking at?&lt;/p&gt;
&lt;p&gt;On the right is a panel constructed with the &lt;code&gt;FvwmButtons&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;It contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the FVWM logo — still maintaining the cat theme,&lt;/li&gt;
&lt;li&gt;desktop buttons &lt;code&gt;0–3&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;a pager,&lt;/li&gt;
&lt;li&gt;an area for open windows managed by &lt;code&gt;FvwmIconMan&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;a clock and date display.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is essentially what the current upstream default configuration defines.&lt;/p&gt;
&lt;p&gt;As applications are opened, the panel gradually fills up:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Top of the default panel" class="gallery-image" data-flex-basis="159px" data-flex-grow="66" height="197" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-1a.png" width="131"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="The panel filling up" class="gallery-image" data-flex-basis="135px" data-flex-grow="56" height="230" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-1b.png" width="130"&gt;&lt;/p&gt;
&lt;p&gt;That is already quite a lot.&lt;/p&gt;
&lt;p&gt;We can even launch something.&lt;/p&gt;
&lt;p&gt;Press:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Alt+Space
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and &lt;code&gt;dmenu_run&lt;/code&gt; appears.&lt;/p&gt;
&lt;p&gt;The current default FVWM configuration binds exactly that command to &lt;code&gt;Alt+Space&lt;/code&gt;, provided &lt;code&gt;dmenu&lt;/code&gt; is installed.&lt;/p&gt;
&lt;p&gt;It displays executables found through &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Which means:&lt;/p&gt;
&lt;p&gt;a lot of things.&lt;/p&gt;
&lt;p&gt;Far too many things.&lt;/p&gt;
&lt;p&gt;Fortunately, the list is filtered as you type.&lt;/p&gt;
&lt;p&gt;&lt;img alt="dmenu" class="gallery-image" data-flex-basis="8276px" data-flex-grow="3448" height="35" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-7.png" srcset="https://lvajxi03.github.io/posts/2026-09-28/fvwm-7_hu_74944ae8d7d63df.png 800w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-7.png 1207w" width="1207"&gt;&lt;/p&gt;
&lt;h2 id="windows"&gt;Windows
&lt;/h2&gt;&lt;p&gt;The first application window looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="First window" class="gallery-image" data-flex-basis="426px" data-flex-grow="177" height="1080" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-2.png" srcset="https://lvajxi03.github.io/posts/2026-09-28/fvwm-2_hu_b33654003e070d1b.png 800w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-2_hu_1138e42d428c8304.png 1600w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-2.png 1920w" width="1920"&gt;&lt;/p&gt;
&lt;p&gt;There is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a title bar,&lt;/li&gt;
&lt;li&gt;buttons on both sides,&lt;/li&gt;
&lt;li&gt;a frame,&lt;/li&gt;
&lt;li&gt;borders,&lt;/li&gt;
&lt;li&gt;corners.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Window buttons" class="gallery-image" data-flex-basis="463px" data-flex-grow="193" height="268" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-2a.png" width="518"&gt;&lt;/p&gt;
&lt;p&gt;The button on the left opens the window operations menu.&lt;/p&gt;
&lt;p&gt;The ones on the right perform more obvious jobs such as closing, maximizing, and minimizing.&lt;/p&gt;
&lt;p&gt;Drag the title bar to move the window.&lt;/p&gt;
&lt;p&gt;Drag an edge to resize it.&lt;/p&gt;
&lt;p&gt;Drag a corner to resize it in two directions at once.&lt;/p&gt;
&lt;p&gt;The technology is clearly almost ready for worldwide adoption.&lt;/p&gt;
&lt;p&gt;Click the &lt;strong&gt;left mouse button&lt;/strong&gt; on the root window and the main FVWM menu appears:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Default menu" class="gallery-image" data-flex-basis="148px" data-flex-grow="62" height="261" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-3.png" width="162"&gt;&lt;/p&gt;
&lt;p&gt;Not bad.&lt;/p&gt;
&lt;p&gt;The important commands are already present.&lt;/p&gt;
&lt;p&gt;Including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Restart&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Quit&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Restart&lt;/code&gt; will become extremely useful in future episodes.&lt;/p&gt;
&lt;p&gt;Trust me.&lt;/p&gt;
&lt;h2 id="desks-and-pages"&gt;Desks and Pages
&lt;/h2&gt;&lt;p&gt;One of FVWM&amp;rsquo;s more interesting features is its enormous virtual workspace.&lt;/p&gt;
&lt;p&gt;The default configuration provides four &lt;strong&gt;desks&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 1 2 3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each desk can itself contain multiple &lt;strong&gt;pages&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;FVWM therefore distinguishes between two concepts:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Desk&lt;/strong&gt; — a separate desktop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Page&lt;/strong&gt; — a position within the larger virtual space of that desktop.&lt;/p&gt;
&lt;p&gt;With the normal global multi-monitor configuration, all connected displays together form the visible area of one page.&lt;/p&gt;
&lt;p&gt;This means the virtual desktop can extend beyond the complete physical monitor arrangement.&lt;/p&gt;
&lt;p&gt;Then you can have several such virtual spaces.&lt;/p&gt;
&lt;p&gt;And several desks containing those.&lt;/p&gt;
&lt;p&gt;Sounds excessive?&lt;/p&gt;
&lt;p&gt;Give it a few days.&lt;/p&gt;
&lt;p&gt;You will run out of room.&lt;/p&gt;
&lt;p&gt;This becomes especially useful when many windows are open and you want to group them by purpose.&lt;/p&gt;
&lt;p&gt;One desk for code.&lt;/p&gt;
&lt;p&gt;One for documentation.&lt;/p&gt;
&lt;p&gt;One for communication.&lt;/p&gt;
&lt;p&gt;One for terminals that have been open for so long that nobody dares close them anymore.&lt;/p&gt;
&lt;p&gt;Open a window and try dragging it beyond the current visible workspace.&lt;/p&gt;
&lt;p&gt;Near the edge, you will feel a slight resistance.&lt;/p&gt;
&lt;p&gt;Keep going.&lt;/p&gt;
&lt;p&gt;The window crosses onto the neighboring page.&lt;/p&gt;
&lt;p&gt;At that moment the physical screen stops feeling like the desktop itself.&lt;/p&gt;
&lt;p&gt;It becomes merely a viewport onto something much larger.&lt;/p&gt;
&lt;h2 id="menus-and-window-information"&gt;Menus and Window Information
&lt;/h2&gt;&lt;p&gt;Clicking the &lt;strong&gt;right mouse button&lt;/strong&gt; on the root window opens the window operations menu.&lt;/p&gt;
&lt;p&gt;At this point no particular window has been selected.&lt;/p&gt;
&lt;p&gt;First choose the operation.&lt;/p&gt;
&lt;p&gt;Then choose the target window.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Window operations menu" class="gallery-image" data-flex-basis="161px" data-flex-grow="67" height="350" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-5.png" width="236"&gt;&lt;/p&gt;
&lt;p&gt;For example, choose:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Identify&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;and then:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GNU Emacs&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;FvwmIdent&lt;/code&gt; appears:&lt;/p&gt;
&lt;p&gt;&lt;img alt="FvwmIdent" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="fwvm-11.png"&gt;&lt;/p&gt;
&lt;p&gt;At first it looks like a collection of obscure X11 properties.&lt;/p&gt;
&lt;p&gt;Later, these values become extremely useful when writing configuration rules.&lt;/p&gt;
&lt;p&gt;That is precisely what &lt;code&gt;FvwmIdent&lt;/code&gt; is intended for: among other things, identifying a window&amp;rsquo;s name, resource, and class.&lt;/p&gt;
&lt;p&gt;Clicking the &lt;strong&gt;middle mouse button&lt;/strong&gt; on the root window displays a window list, including geometry information.&lt;/p&gt;
&lt;p&gt;Its main purpose is to activate another window quickly.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Alt+Tab&lt;/code&gt; produces a simpler window list without geometry.&lt;/p&gt;
&lt;p&gt;The default configuration binds this directly to FVWM&amp;rsquo;s &lt;code&gt;WindowList&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Clicking the &lt;strong&gt;right mouse button on a title bar&lt;/strong&gt; opens the current window&amp;rsquo;s operations menu:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Window menu" class="gallery-image" data-flex-basis="146px" data-flex-grow="61" height="190" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-4.png" width="116"&gt;&lt;/p&gt;
&lt;p&gt;Among the more interesting entries are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stick / Unstick&lt;/strong&gt; — make the window appear across desks, or return it to normal behavior,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shade / Unshade&lt;/strong&gt; — collapse the window until only the title bar remains, then restore it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Shade" class="gallery-image" data-flex-basis="3328px" data-flex-grow="1386" height="69" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-6a.png" srcset="https://lvajxi03.github.io/posts/2026-09-28/fvwm-6a_hu_2dc9349d2e1dbe36.png 800w, https://lvajxi03.github.io/posts/2026-09-28/fvwm-6a.png 957w" width="957"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Stick" class="gallery-image" data-flex-basis="2172px" data-flex-grow="905" height="75" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://lvajxi03.github.io/posts/2026-09-28/fvwm-6b.png" width="679"&gt;&lt;/p&gt;
&lt;p&gt;And that is enough for the first encounter.&lt;/p&gt;
&lt;p&gt;Spend a while moving windows around, switching desks, exploring pages, and generally discovering how much space FVWM is prepared to give you.&lt;/p&gt;
&lt;p&gt;Then choose &lt;strong&gt;Quit&lt;/strong&gt; from the main menu.&lt;/p&gt;
&lt;p&gt;In the next episode, we will log in again.&lt;/p&gt;
&lt;p&gt;But this time, into &lt;strong&gt;our&lt;/strong&gt; FVWM.&lt;/p&gt;</description></item><item><title>Cutting, Bending, Soldering</title><link>https://lvajxi03.github.io/posts/2026-08-25/</link><pubDate>Tue, 25 Aug 2026 23:00:00 +0200</pubDate><guid>https://lvajxi03.github.io/posts/2026-08-25/</guid><description>&lt;h1 id="introduction"&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Three years ago, I bought a computer with a preinstalled operating system commonly known as Windows.&lt;/p&gt;
&lt;p&gt;You may ask: why?&lt;/p&gt;
&lt;p&gt;Surely it would have been possible to find a machine with an empty drive and save myself the trouble.&lt;/p&gt;
&lt;p&gt;Well, I happened to find a computer with what was then the latest Core i5, 64 GB of RAM, a 1 TB NVMe drive, and an NVIDIA RTX 3050 at a price low enough that the correct order of operations was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;buy the computer,&lt;/li&gt;
&lt;li&gt;ask questions later.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And Windows?&lt;/p&gt;
&lt;p&gt;It came with the machine.&lt;/p&gt;
&lt;p&gt;Might as well keep it. You never know when it might become useful.&lt;/p&gt;
&lt;p&gt;After several months, however, &lt;em&gt;working&lt;/em&gt; with this otherwise magnificent operating system started to resemble an experiment designed to determine the limits of human patience.&lt;/p&gt;
&lt;p&gt;I wanted it gone.&lt;/p&gt;
&lt;p&gt;Or, at the very least, I wanted its influence over my life significantly reduced.&lt;/p&gt;
&lt;p&gt;Using Windows itself, I managed to shrink its partition and install &lt;strong&gt;Ubuntu&lt;/strong&gt;, which had long been my default Linux distribution both on PCs and on many ARM64 machines.&lt;/p&gt;
&lt;p&gt;Ubuntu received 244 GiB.&lt;/p&gt;
&lt;p&gt;In theory, that should be plenty. With a little maintenance, that amount of space can last for a very long time.&lt;/p&gt;
&lt;p&gt;The problem was that the rest of the drive was being wasted spectacularly.&lt;/p&gt;
&lt;p&gt;Windows later allowed me to reclaim another 115 GiB or so, but no more.&lt;/p&gt;
&lt;p&gt;Where was the administrator&amp;rsquo;s control over his own computer?&lt;/p&gt;
&lt;p&gt;Where was the sacred right to partition a disk according to one&amp;rsquo;s own unreasonable plans?&lt;/p&gt;
&lt;p&gt;This led to a bold decision:&lt;/p&gt;
&lt;p&gt;delete the main NTFS partition, reinstall the &lt;em&gt;hostile operating system&lt;/em&gt; into the smallest sensible amount of space, and use everything else to live dangerously.&lt;/p&gt;
&lt;p&gt;For Fedora, which I had never had time for.&lt;/p&gt;
&lt;p&gt;For FreeBSD, which I had never had room for.&lt;/p&gt;
&lt;p&gt;For Arch Linux, so that I could finally approach random strangers in the street and say:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;I use Arch, btw.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;For Slackware, so that I could watch its installer produce a &lt;code&gt;segmentation fault&lt;/code&gt; and reassure myself that reports of the distribution&amp;rsquo;s death had indeed been greatly exaggerated.&lt;/p&gt;
&lt;p&gt;And so on.&lt;/p&gt;
&lt;p&gt;That is exactly what I did.&lt;/p&gt;
&lt;h1 id="backup"&gt;Backup
&lt;/h1&gt;&lt;p&gt;First things first: backups.&lt;/p&gt;
&lt;p&gt;Important files from NTFS first, then the &lt;code&gt;ext4&lt;/code&gt; partition as well.&lt;/p&gt;
&lt;p&gt;Because you never know.&lt;/p&gt;
&lt;p&gt;A question for the brave:&lt;/p&gt;
&lt;p&gt;how often do you &lt;strong&gt;not&lt;/strong&gt; make backups?&lt;/p&gt;
&lt;p&gt;And what happens if the power disappears halfway through repartitioning the drive?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m seriously asking.&lt;/p&gt;
&lt;p&gt;For a friend.&lt;/p&gt;
&lt;p&gt;Who also does not make backups.&lt;/p&gt;
&lt;p&gt;The obvious tool is &lt;code&gt;rsync&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rsync -av --info&lt;span style="color:#f92672"&gt;=&lt;/span&gt;progress2 /source-directory/ /destination-directory/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The destination will probably be an external NTFS drive already containing other important backups.&lt;/p&gt;
&lt;p&gt;Converting it to &lt;code&gt;ext4&lt;/code&gt; right now would merely create another project that nobody asked for.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;rsync&lt;/code&gt; as many times as necessary.&lt;/p&gt;
&lt;p&gt;Including the Windows user directory.&lt;/p&gt;
&lt;p&gt;You never know when something from there might turn out to be useful.&lt;/p&gt;
&lt;p&gt;At worst, six months later you discover several dozen gigabytes of Go, Firefox, &lt;code&gt;pip&lt;/code&gt;, and other caches proving that civilization once existed there.&lt;/p&gt;
&lt;h1 id="a-quick-trip-through-windows"&gt;A Quick Trip Through Windows
&lt;/h1&gt;&lt;p&gt;The world has moved on since Windows XP.&lt;/p&gt;
&lt;p&gt;You no longer need to keep an installation DVD hidden in a drawer somewhere.&lt;/p&gt;
&lt;p&gt;Windows installation media can be downloaded from the Internet, and on machines originally sold with Windows, activation will normally happen automatically using the OEM key stored in UEFI firmware.&lt;/p&gt;
&lt;p&gt;For peace of mind, however, you can still retrieve the key before doing anything destructive:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(Get-CimInstance -ClassName SoftwareLicensingService).OA3xOriginalProductKey
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On Linux, the key stored in the ACPI MSDM table can often be displayed with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo strings /sys/firmware/acpi/tables/MSDM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On my machine, that produced the correct activation key as well.&lt;/p&gt;
&lt;p&gt;To make reinstalling Windows slightly less painful, I prepared the USB stick using &lt;strong&gt;Rufus&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Rufus detects Windows installation images and offers several additional installation options.&lt;/p&gt;
&lt;p&gt;After pressing &lt;code&gt;Start&lt;/code&gt;, I was presented with the &lt;strong&gt;Windows User Experience&lt;/strong&gt; dialog.&lt;/p&gt;
&lt;p&gt;I selected, among other things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no requirement for a Microsoft account,&lt;/li&gt;
&lt;li&gt;creation of a local user with a name of my choosing,&lt;/li&gt;
&lt;li&gt;fewer telemetry and privacy questions,&lt;/li&gt;
&lt;li&gt;disabling automatic BitLocker device encryption.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the installer prepared, the time finally came to delete some partitions.&lt;/p&gt;
&lt;p&gt;Using a proper operating system, naturally.&lt;/p&gt;
&lt;h1 id="whats-on-the-plate"&gt;What&amp;rsquo;s on the Plate?
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;gparted&lt;/code&gt; revealed the following landscape:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Partition&lt;/th&gt;
 &lt;th style="text-align: right"&gt;Size&lt;/th&gt;
 &lt;th&gt;Purpose&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p1&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;300 MiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;EFI System Partition&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p2&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;128 MiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Microsoft Reserved Partition (MSR)&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p3&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;546.37 GiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Windows C:&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;unallocated&lt;/td&gt;
 &lt;td style="text-align: right"&gt;&lt;strong&gt;115.86 GiB&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;free space&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p4&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;1.12 GiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Windows Recovery / WinRE&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p5&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;244.14 GiB&lt;/td&gt;
 &lt;td&gt;existing Ubuntu&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;unallocated&lt;/td&gt;
 &lt;td style="text-align: right"&gt;1.05 GiB&lt;/td&gt;
 &lt;td&gt;a small gap&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p6&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;21.07 GiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Dell factory recovery image&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/dev/nvme0n1p7&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: right"&gt;1.49 GiB&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Dell support / diagnostics&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;unallocated&lt;/td&gt;
 &lt;td style="text-align: right"&gt;1.71 MiB&lt;/td&gt;
 &lt;td&gt;alignment&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The plan:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Delete &lt;code&gt;nvme0n1p3&lt;/code&gt; and &lt;code&gt;nvme0n1p4&lt;/code&gt;. Windows Setup can recreate what it needs. Leave &lt;code&gt;p1&lt;/code&gt;, &lt;code&gt;p2&lt;/code&gt;, &lt;code&gt;p5&lt;/code&gt;, &lt;code&gt;p6&lt;/code&gt;, and &lt;code&gt;p7&lt;/code&gt; alone.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Snip.&lt;/p&gt;
&lt;p&gt;Gone.&lt;/p&gt;
&lt;h1 id="installing-windows"&gt;Installing Windows
&lt;/h1&gt;&lt;p&gt;On Dell laptops, pressing &lt;strong&gt;F12&lt;/strong&gt; during boot opens the temporary boot menu, from which the Windows installer USB stick can be selected.&lt;/p&gt;
&lt;p&gt;The installer started correctly.&lt;/p&gt;
&lt;p&gt;There was just one tiny problem:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;The only visible drive was the USB stick itself.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;The solution was simple.&lt;/p&gt;
&lt;p&gt;Back into the firmware setup using &lt;strong&gt;F2&lt;/strong&gt;, then change the storage-controller mode from &lt;strong&gt;RAID&lt;/strong&gt; to &lt;strong&gt;AHCI&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;After rebooting, the NVMe drive appeared in Windows Setup.&lt;/p&gt;
&lt;p&gt;This is where a little attention becomes important:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Do not simply keep clicking &lt;em&gt;Next&lt;/em&gt;.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Windows is perfectly happy to consume all available space for itself.&lt;/p&gt;
&lt;p&gt;I manually created a partition of roughly 150 GiB and installed Windows there.&lt;/p&gt;
&lt;p&gt;Partition created.&lt;/p&gt;
&lt;p&gt;Windows installed.&lt;/p&gt;
&lt;h1 id="initial-windows-configuration"&gt;Initial Windows Configuration
&lt;/h1&gt;&lt;p&gt;The objective here was simple: prevent Windows from quietly reserving unreasonable amounts of disk space for things I did not particularly care about.&lt;/p&gt;
&lt;p&gt;First, disable hibernation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;powercfg /h off
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This also removes &lt;code&gt;hiberfil.sys&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sysdm.cpl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advanced → Performance → Settings → Advanced → Virtual Memory → Change&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Automatic pagefile management can be disabled and a fixed limit selected.&lt;/p&gt;
&lt;p&gt;In my case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initial size: &lt;code&gt;1024 MB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Maximum size: &lt;code&gt;4096 MB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not universal advice.&lt;/p&gt;
&lt;p&gt;My machine has 64 GB of RAM. On systems with significantly less memory, leaving pagefile management to Windows may be the better option.&lt;/p&gt;
&lt;p&gt;Next:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advanced → Startup and Recovery → Settings → Write debugging information → None&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If full crash dumps are not useful to you, there is little reason to reserve many gigabytes for them.&lt;/p&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SystemPropertiesProtection
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;C:&lt;/code&gt;, System Protection can either be disabled or given a small storage limit.&lt;/p&gt;
&lt;p&gt;I kept it enabled but limited.&lt;/p&gt;
&lt;p&gt;After major updates, the component store can also be cleaned:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DISM /Online /Cleanup-Image /AnalyzeComponentStore
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DISM /Online /Cleanup-Image /StartComponentCleanup
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And finally:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Settings → System → Storage → Temporary Files&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Phew.&lt;/p&gt;
&lt;p&gt;Windows had now been successfully confined to its 150-gigabyte room.&lt;/p&gt;
&lt;p&gt;It was time to return to the actual experiment.&lt;/p&gt;
&lt;h1 id="the-second-operating-system"&gt;The Second Operating System
&lt;/h1&gt;&lt;p&gt;For the second operating system — from the normal family — I chose &lt;strong&gt;Fedora KDE&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;With every intention of eventually making it my main system.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;fvwm3&lt;/code&gt; configuration can wait for long autumn evenings, when ordinary life stops providing enough problems.&lt;/p&gt;
&lt;h2 id="installing-fedora"&gt;Installing Fedora
&lt;/h2&gt;&lt;p&gt;Fedora boots into a Live environment, which has several advantages.&lt;/p&gt;
&lt;p&gt;First, a complete system and disk tools are available before installation.&lt;/p&gt;
&lt;p&gt;Second, you can open a browser, play a movie, and enjoy a genuine &lt;em&gt;sit back and relax&lt;/em&gt; experience.&lt;/p&gt;
&lt;p&gt;Another company advertised that concept back in 1995.&lt;/p&gt;
&lt;p&gt;It did not go particularly well.&lt;/p&gt;
&lt;p&gt;Fedora&amp;rsquo;s installer was also quite enthusiastic about using all available disk space, so I politely declined and prepared the partitions myself.&lt;/p&gt;
&lt;p&gt;I allocated 2 GiB of &lt;code&gt;ext4&lt;/code&gt; for &lt;code&gt;/boot&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The root filesystem received roughly 215 GiB of &lt;code&gt;btrfs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is worth keeping Fedora&amp;rsquo;s usual Btrfs subvolume layout:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;root&lt;/code&gt; → &lt;code&gt;/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;home&lt;/code&gt; → &lt;code&gt;/home&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is no need for a separate &lt;code&gt;/home&lt;/code&gt; partition.&lt;/p&gt;
&lt;p&gt;Both subvolumes share the same Btrfs storage pool, so free space is not artificially divided between the operating system and user files.&lt;/p&gt;
&lt;p&gt;The installer then needed three mount points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/boot&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/boot/efi&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last one comes with an important rule:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;do &lt;strong&gt;not&lt;/strong&gt; format the existing EFI System Partition.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Unless crying and gnashing of teeth happens to be part of the plan.&lt;/p&gt;
&lt;p&gt;At this point, tea can be prepared while the installer does its work.&lt;/p&gt;
&lt;h2 id="unsupportedpartitioningerror"&gt;&lt;code&gt;UnsupportedPartitioningError&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;There was, naturally, one surprise.&lt;/p&gt;
&lt;p&gt;The installer refused to use the Btrfs filesystem I had prepared for &lt;code&gt;/&lt;/code&gt; and stopped with &lt;code&gt;UnsupportedPartitioningError&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In my particular case, manually creating the expected subvolumes solved the problem:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mount /dev/nvme0n1p9 /mnt/btrfs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo btrfs subvolume create /mnt/btrfs/root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo btrfs subvolume create /mnt/btrfs/home
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo btrfs subvolume list /mnt/btrfs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In other words:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mount the filesystem,&lt;/li&gt;
&lt;li&gt;create &lt;code&gt;root&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;create &lt;code&gt;home&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;verify that they actually exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next installation attempt completed successfully.&lt;/p&gt;
&lt;p&gt;Fedora installed its own GRUB configuration afterward.&lt;/p&gt;
&lt;p&gt;Fortunately, it also discovered the other operating systems and added them to the boot menu.&lt;/p&gt;
&lt;h2 id="first-boot"&gt;First Boot
&lt;/h2&gt;&lt;p&gt;After the first successful boot, I created the normal administrative user.&lt;/p&gt;
&lt;p&gt;Its UID and GID were the usual:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1000:1000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Exactly the same as my user account under Ubuntu.&lt;/p&gt;
&lt;p&gt;A small detail, but a very convenient one when files are shared between installations.&lt;/p&gt;
&lt;p&gt;The root password remained unset.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Use sudo, Luke.&lt;/em&gt;&lt;/p&gt;
&lt;h1 id="mounting-the-ntfs-partition"&gt;Mounting the NTFS Partition
&lt;/h1&gt;&lt;p&gt;Once the Windows partition was known, it could be added to &lt;code&gt;/etc/fstab&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My first version used the kernel &lt;code&gt;ntfs3&lt;/code&gt; driver:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-fstab" data-lang="fstab"&gt;UUID=NTFS-PART-UUID /mnt/c ntfs3 rw,nosuid,nodev,nofail,uid=1000,gid=1000,umask=022,windows_names 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Later, however, I found that &lt;code&gt;ntfs-3g&lt;/code&gt; behaved much better in my particular setup, so that is what I ultimately kept.&lt;/p&gt;
&lt;h1 id="fonts"&gt;Fonts
&lt;/h1&gt;&lt;p&gt;With the Windows partition mounted, its fonts can also be reused.&lt;/p&gt;
&lt;p&gt;After all, the files are already sitting on a machine whose Windows license came with the hardware.&lt;/p&gt;
&lt;p&gt;For manually installed system-wide fonts, a suitable location is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir -p /usr/local/share/fonts/microsoft
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo cp /mnt/c/Windows/Fonts/*.ttf /usr/local/share/fonts/microsoft/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo fc-cache -fv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And this is where another adventure began.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fc-cache&lt;/code&gt; reported no usable fonts.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fc-scan&lt;/code&gt; failed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fc-scan /usr/local/share/fonts/microsoft/arial.ttf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;while:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;file /usr/local/share/fonts/microsoft/arial.ttf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;identified the file merely as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Something was clearly wrong.&lt;/p&gt;
&lt;p&gt;After several experiments, the issue disappeared when I switched the Windows filesystem from the kernel &lt;code&gt;ntfs3&lt;/code&gt; driver to &lt;code&gt;ntfs-3g&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I remounted it, copied the font files again, rebuilt the Fontconfig cache, and this time everything was recognized correctly.&lt;/p&gt;
&lt;p&gt;I am &lt;strong&gt;not&lt;/strong&gt; claiming that &lt;code&gt;ntfs3&lt;/code&gt; inherently breaks font files.&lt;/p&gt;
&lt;p&gt;I am saying that this was the exact symptom on my machine, and changing the driver fixed it.&lt;/p&gt;
&lt;p&gt;That distinction becomes rather important once something is published on the Internet.&lt;/p&gt;
&lt;p&gt;I could, of course, have installed one of the packages that retrieves Microsoft&amp;rsquo;s traditional core fonts.&lt;/p&gt;
&lt;p&gt;But why add another mechanism for downloading data when the files I actually wanted were already sitting on the neighboring partition?&lt;/p&gt;
&lt;h1 id="standard-software"&gt;Standard Software
&lt;/h1&gt;&lt;p&gt;After this unexpected NTFS lesson, normal life could finally begin.&lt;/p&gt;
&lt;p&gt;First:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf upgrade --refresh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then the basic toolkit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fish rsync curl wget zip unzip ansible git &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; emacs vim firefox gimp inkscape jq yq mc htop tmux &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gcc gcc-g++ make cmake python3-pip python3-devel &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; podman buildah skopeo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point the computer finally begins to resemble a workstation.&lt;/p&gt;
&lt;h1 id="additional-software"&gt;Additional Software
&lt;/h1&gt;&lt;h2 id="keepassxc"&gt;KeePassXC
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;KeePassXC&lt;/strong&gt; is available directly from the Fedora repositories:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install keepassxc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Years ago, applications like this required considerably more effort.&lt;/p&gt;
&lt;p&gt;Civilization occasionally moves forward.&lt;/p&gt;
&lt;h2 id="heidisql"&gt;HeidiSQL
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;HeidiSQL&lt;/strong&gt; now offers a Linux build and an RPM package.&lt;/p&gt;
&lt;p&gt;Installing it is therefore considerably less exotic than it once would have been.&lt;/p&gt;
&lt;p&gt;The Linux version uses Qt rather than .NET.&lt;/p&gt;
&lt;h2 id="opera"&gt;Opera
&lt;/h2&gt;&lt;p&gt;Opera provides its own RPM repository.&lt;/p&gt;
&lt;p&gt;Import the signing key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo rpm --import https://rpm.opera.com/rpmrepo.key
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add the repository:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo tee /etc/yum.repos.d/opera.repo &lt;span style="color:#e6db74"&gt;&amp;lt;&amp;lt;&amp;#39;RPMREPO&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;[opera]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;name=Opera packages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;type=rpm-md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;baseurl=https://rpm.opera.com/rpm
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;gpgcheck=1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;gpgkey=https://rpm.opera.com/rpmrepo.key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;enabled=1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;RPMREPO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then install:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install opera-stable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Not &lt;code&gt;opera-developer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I have no idea why I briefly considered installing that one.&lt;/p&gt;
&lt;h2 id="visual-studio-code"&gt;Visual Studio Code
&lt;/h2&gt;&lt;p&gt;Following the recommendations of the company whose extremely enthusiastic CEO once ran around a stage shouting:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Developers! Developers! Developers!&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;first import &lt;em&gt;their&lt;/em&gt; signing key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then add the repository:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s\n&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;[code]&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;name=Visual Studio Code&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;baseurl=https://packages.microsoft.com/yumrepos/vscode&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;enabled=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;autorefresh=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;type=rpm-md&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;gpgcheck=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;gpgkey=https://packages.microsoft.com/keys/microsoft.asc&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| sudo tee /etc/yum.repos.d/vscode.repo &amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And install:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install code
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From this point on, a normal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;will update VS Code along with everything else.&lt;/p&gt;
&lt;h2 id="vscodium"&gt;VSCodium
&lt;/h2&gt;&lt;p&gt;The process is similar, except that the packages no longer come from the repository belonging to the company whose enthusiastic CEO&amp;hellip;&lt;/p&gt;
&lt;p&gt;All right.&lt;/p&gt;
&lt;p&gt;Enough.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s\n&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;[gitlab.com_paulcarroty_vscodium_repo]&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;name=VSCodium&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;baseurl=https://paulcarroty.gitlab.io/vscodium-deb-rpm-repo/rpms/&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;enabled=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;gpgcheck=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;repo_gpgcheck=1&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;gpgkey=https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;metadata_expire=1h&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| sudo tee /etc/yum.repos.d/vscodium.repo &amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install codium
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="brave"&gt;Brave
&lt;/h2&gt;&lt;p&gt;Right.&lt;/p&gt;
&lt;p&gt;Definitely enough about enthusiastic CEOs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install dnf-plugins-core
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf config-manager addrepo &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --from-repofile&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install brave-browser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="spotify"&gt;Spotify
&lt;/h2&gt;&lt;p&gt;Spotify comes from Flatpak.&lt;/p&gt;
&lt;p&gt;Possibly because the company is Swedish and its CEO, in turn&amp;hellip;&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Never mind.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flatpak remote-add --if-not-exists flathub &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; https://dl.flathub.org/repo/flathub.flatpakrepo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flatpak install flathub com.spotify.Client
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="virtualbox"&gt;VirtualBox
&lt;/h2&gt;&lt;p&gt;First enable RPM Fusion:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install VirtualBox akmod-VirtualBox kernel-devel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To explicitly build the module for the currently running kernel:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo akmods --kernels &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;uname -r&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Future kernel updates should normally be handled automatically by &lt;code&gt;akmods&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="a-better-looking-grub-menu"&gt;A Better-Looking GRUB Menu
&lt;/h2&gt;&lt;p&gt;Once a computer contains several operating systems, it seems only reasonable to make the screen used to choose between them somewhat pleasant to look at.&lt;/p&gt;
&lt;p&gt;Fortunately, there is no need to spend an evening designing one.&lt;/p&gt;
&lt;p&gt;There is &lt;strong&gt;Tela&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/vinceliuice/grub2-themes.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd grub2-themes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ./install.sh -t tela -s 1080p
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And suddenly the boot menu looks as though somebody actually expected a human being to see it.&lt;/p&gt;
&lt;h1 id="enough-for-one-day"&gt;Enough for One Day
&lt;/h1&gt;&lt;p&gt;In a single day, I managed to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;confine Windows to an amount of disk space I can tolerate,&lt;/li&gt;
&lt;li&gt;preserve Ubuntu,&lt;/li&gt;
&lt;li&gt;add Fedora,&lt;/li&gt;
&lt;li&gt;learn something about Btrfs,&lt;/li&gt;
&lt;li&gt;discover an interesting difference between &lt;code&gt;ntfs3&lt;/code&gt; and &lt;code&gt;ntfs-3g&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;recover the fonts,&lt;/li&gt;
&lt;li&gt;install the basic workstation software,&lt;/li&gt;
&lt;li&gt;and make GRUB look respectable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Doctors do not recommend more excitement than this in a twenty-four-hour period.&lt;/p&gt;
&lt;p&gt;And there is still plenty of unallocated disk space left.&lt;/p&gt;
&lt;p&gt;FreeBSD is waiting.&lt;/p&gt;
&lt;p&gt;So is Arch.&lt;/p&gt;
&lt;p&gt;Slackware, one hopes, is still waiting too.&lt;/p&gt;
&lt;p&gt;So there will be more.&lt;/p&gt;
&lt;p&gt;Probably sooner rather than later.&lt;/p&gt;</description></item></channel></rss>