APPLICATION ICON AND DESKTOP INTEGRATION
Context
On Plasma Wayland the Katalog titlebar icon renders with a black rim and stray
impossible colours, in both user interfaces. The cause is not the artwork. Both
UIs set the window icon from a multi-entry .ico whose smallest entry is 16x16;
Qt 6.9 and later hand every entry of that icon to the compositor through
xdg_toplevel_icon_v1, and the compositor picks the entry nearest its advertised
icon size. KWin advertises 96; the nearest available entries are small, and a
small buffer upscaled into the titlebar slot magnifies a per-pixel colour
error instead of averaging it away.
The per-pixel error itself is an upstream Qt defect: qtwayland allocates those
icon buffers as QImage::Format_ARGB32 (straight alpha) while declaring
WL_SHM_FORMAT_ARGB8888, which Wayland defines as premultiplied. Katalog cannot
fix that. What Katalog controls is which buffer it offers. Offering a single
large buffer makes the compositor downscale rather than upscale, and the error
becomes invisible. That is the mitigation this spec requires, and it is recorded
as a mitigation rather than a preference so it is not "tidied away" later.
Measurements, the Wayland protocol trace and the A/B probe results are in
SpecApplicationIconBacklogNotes.md. They are evidence, not requirements, and
are deliberately kept out of the tables below.
This spec covers three separable pieces of work:
- The defect fix (
ICO-F1,ICO-F2) — which asset each platform sets the window icon from. This alone resolves the reported corruption. - Desktop integration (
ICO-F3,ICO-F4) — installing a desktop entry and a full hicolor icon set. This is a separate improvement, not part of the defect, and neither depends on the other. - The macOS bundle icon (
ICO-F5) — a second, unrelated defect reported by a K3 3.0 beta1 tester on macOS: "No icon attached to the application, but once running, it is displayed correctly." macOS has two independent icons and only the runtime one was ever set. This depends on neither of the other two.
Reading the requirement IDs. Each requirement has a permanent ID. IDs are never renumbered or reused; a retired requirement is marked
[Removed], not deleted. Status is one of[Implemented] / [Planned] / [Backlog] / [Removed].
Scope at a glance
In scope: the icon each platform sets as the window icon in K2 and K3; the
desktop entry installed on Linux; the hicolor icon sizes installed on Linux; the
macOS bundle icon resource and its CFBundleIconFile entry, in K2 and K3; the
constraints that keep all of the above from regressing.
Out of scope (non-goals): the artwork itself — no icon is redrawn or restyled by this spec. Fixing the upstream qtwayland premultiplied-alpha defect; Katalog mitigates, it does not patch Qt. In-application icons (toolbar, action and device icons) — those come from the icon theme and are untouched. The Windows installer and the macOS bundle layout beyond the icon resource. Any change to the desktop entry's translated strings. Flatpak or other downstream packaging manifests.
Operational requirements — why / for whom
Goals in real use, independent of how they are built.
| ID | Requirement | Status |
|---|---|---|
| ICO-O1 | A user sees the Katalog icon rendered cleanly in the window titlebar, the task manager and the window switcher, on every supported platform and in both user interfaces. | [Implemented] |
| ICO-O2 | A user who installs Katalog finds it in the application launcher under its own name and icon, and can start it from there, whichever user interface is installed. | [Planned] |
| ICO-O3 | On macOS, a user sees the Katalog icon on the application itself — in Finder, in the DMG window, in Launchpad, and on the Dock icon before the application is started — in both user interfaces. | [Planned] |
Functional requirements — what the system does
Observable behaviour that can be triggered and watched.
| ID | Requirement | Status |
|---|---|---|
| ICO-F1 | On Linux, both K2 and K3 set the window icon from the 256-pixel PNG master, not from the .ico. | [Implemented] |
| ICO-F2 | On Windows and macOS, both K2 and K3 continue to set the runtime window icon from the .ico. This is the taskbar/Dock icon while the application is running; it is distinct from the macOS bundle icon of ICO-F5. | [Implemented] |
| ICO-F3 | Installing either user interface on Linux installs exactly one desktop entry, named io.github.stephanecouturier.Katalog.desktop, into share/applications. | [Implemented] |
| ICO-F4 | Installing either user interface on Linux installs the application icon at each of the eight sizes listed in Installed icon set below, into share/icons/hicolor/<size>x<size>/apps. | [Implemented] |
| ICO-F5 | On macOS, both K2 and K3 ship an .icns application icon inside Katalog.app/Contents/Resources, and the generated Info.plist names that file in CFBundleIconFile. | [Planned] |
Constructional requirements — how it is built / limits / MUST-NOTs
Boundaries and implementation constraints, not user-visible behaviour.
| ID | Requirement | Status |
|---|---|---|
| ICO-C1 | The image handed to the compositor as the Linux window icon MUST be a single large raster. It MUST NOT be a multi-entry .ico, and MUST NOT be any image smaller than 256 pixels. This is the root-cause guard: a smaller buffer is upscaled into the titlebar slot and exposes the upstream alpha defect. | [Implemented] |
| ICO-C2 | The .ico MUST be retained. It is the Windows .rc resource and the Windows and macOS window icon, and it stays listed in both images.qrc files. It MUST NOT be deleted as "unused" on the strength of the Linux change. It is not, and MUST NOT be used as, the macOS bundle icon — see ICO-C10. | [Implemented] |
| ICO-C3 | K2 sets its Linux window icon in C++, immediately after setupUi. The windowIcon property in mainwindow.ui MUST NOT be used as the platform-conditional mechanism, and MUST NOT be removed: it remains the Windows and macOS value and the designer-visible icon. The C++ call overrides it on Linux only. | [Implemented] |
| ICO-C4 | The K2 change is limited to the icon source. No other K2 UI change is authorised by this spec — K2 is in maintenance mode. | [Implemented] |
| ICO-C5 | The installed icons are pre-generated PNG files committed under assets/. They MUST NOT be produced by a build-time image conversion step: no ImageMagick or equivalent may be added as a build dependency, because the Windows build must remain viable. | [Implemented] |
| ICO-C6 | K2 and K3 both install as bin/Katalog and deliberately share one desktop entry and one application id. They are mutually exclusive installs and MUST NOT be installed into the same prefix at the same time. A second desktop file, a second application id, or a distinct Exec/StartupWMClass for K3 MUST NOT be created. | [Implemented] |
| ICO-C7 | The desktop entry is reused as-is. Its Name, GenericName, Comment and Keywords values, and all of their localised variants, MUST NOT be edited, reordered or re-generated by this work. | [Implemented] |
| ICO-C8 | No user-visible application string is added, changed or removed by this spec. | [Implemented] |
| ICO-C9 | No core/ change. This spec touches only UI entry points and build files. | [Implemented] |
| ICO-C10 | The macOS bundle icon MUST be an .icns. A .ico MUST NOT be named as MACOSX_BUNDLE_ICON_FILE: macOS reads only .icns as a bundle icon, so naming a .ico there yields a bundle with no icon at all. Naming the file is not sufficient on its own — the .icns MUST also be copied into Contents/Resources by the build. | [Planned] |
| ICO-C11 | The .icns is a pre-generated asset committed under assets/, derived from the master assets/Katalog_logo_256.png. It MUST NOT be produced by a build-time conversion step: iconutil and sips exist only on macOS, and a build-time rule would make the icon unreproducible on the Linux and Windows builders. This extends ICO-C5 to the macOS bundle icon. | [Planned] |
| ICO-C12 | The .icns MUST NOT be added to either images.qrc. It is a bundle resource copied into Contents/Resources by CMake, never a Qt resource; listing it in a .qrc would embed a second copy in every platform's binary. | [Planned] |
| ICO-C13 | The runtime window icon of ICO-F1 / ICO-F2 is unchanged by this work. qt_quick/main.cpp and qt_widgets/mainwindow.ui MUST NOT be touched: the bundle icon and the window icon are two independent macOS icons, and the reported defect concerns only the former. | [Planned] |
| ICO-C14 | The K2 part of ICO-F5 is limited to qt_widgets/CMakeLists.txt and the added asset. No K2 source, UI, layout or string change is authorised — K2 remains in maintenance mode. This is the K2 counterpart of ICO-C4 for this second defect. | [Planned] |
Installed icon set
The complete and exclusive size list authorised by ICO-F4. Every file is a
pre-generated PNG committed under assets/icons/, derived from the master
assets/Katalog_logo_256.png, and installed with RENAME to
io.github.stephanecouturier.Katalog.png in its size directory.
| Size | Source asset | Installed to |
|---|---|---|
| 16 | assets/icons/katalog_16.png | share/icons/hicolor/16x16/apps |
| 22 | assets/icons/katalog_22.png | share/icons/hicolor/22x22/apps |
| 24 | assets/icons/katalog_24.png | share/icons/hicolor/24x24/apps |
| 32 | assets/icons/katalog_32.png | share/icons/hicolor/32x32/apps |
| 48 | assets/icons/katalog_48.png | share/icons/hicolor/48x48/apps |
| 64 | assets/icons/katalog_64.png | share/icons/hicolor/64x64/apps |
| 128 | assets/icons/katalog_128.png | share/icons/hicolor/128x128/apps |
| 256 | assets/Katalog_logo_256.png | share/icons/hicolor/256x256/apps |
Seven new shipped assets are required, at 16 through 128. The 256 row
deliberately reuses the existing assets/Katalog_logo_256.png rather than adding
a copy under assets/icons/: that file is simultaneously the generation master
and the Linux window icon of ICO-F1, and a duplicate could drift from it.
Installing a size set rather than a single 256 master lets the launcher and the
task manager pick an exact match instead of rescaling. This is separate from
ICO-C1: the window icon handed to the compositor is still the single 256
raster, precisely because the compositor rescales it itself.
Both qt_widgets/CMakeLists.txt and qt_quick/CMakeLists.txt install this set,
each iterating the seven sizes and then installing the master for the 256 entry.
The iteration calls install only: no image is converted at build time, which is
what keeps ICO-C5 satisfied and the Windows build free of an ImageMagick-class
dependency.
The desktop entry is installed by both, from packaging/linux/Katalog.desktop
with RENAME io.github.stephanecouturier.Katalog.desktop. K3 reuses the K2 file
rather than owning a copy, per ICO-C6 and ICO-C7.
Both install rules carry comments citing the requirement ids that govern them, so the constraint is visible at the point where someone would otherwise break it.
Window icon sources
The complete mapping authorised by ICO-F1 and ICO-F2.
| Platform | Asset | K2 set at | K3 set at |
|---|---|---|---|
| Linux | :/images/Katalog_logo_256.png | qt_widgets/mainwindow.cpp:115-124, under Q_OS_LINUX, immediately after ui->setupUi(this) | qt_quick/main.cpp:36-47, under Q_OS_LINUX, before the QML engine loads |
| Windows | :/images/Katalog_logo_64.ico | qt_widgets/mainwindow.ui:31-35 property | qt_quick/main.cpp:36-47, #else branch |
| macOS | :/images/Katalog_logo_64.ico | qt_widgets/mainwindow.ui:31-35 property | qt_quick/main.cpp:36-47, #else branch |
This table covers the window icon only. The macOS bundle icon is a separate
asset governed by ICO-F5 and ICO-C10, and is listed in macOS bundle icon
below.
Katalog_logo_256.png is registered at qt_widgets/images.qrc:4 and
qt_quick/images.qrc:47. The .ico entries alongside them are retained per
ICO-C2.
K2 takes no #else branch: on Windows and macOS the .ui property is simply
left in force, which is what ICO-C3 requires and why that property must not be
removed as dead.
The delivered change is 23 insertions and 0 deletions across those four files.
Nothing was removed, which is the direct evidence for ICO-C2 and ICO-C3.
macOS bundle icon
The complete mapping authorised by ICO-F5.
| Item | Value |
|---|---|
| Asset | assets/Katalog.icns, pre-generated from assets/Katalog_logo_256.png |
Info.plist key | CFBundleIconFile, set via MACOSX_BUNDLE_ICON_FILE |
| Copied to | Katalog.app/Contents/Resources/ |
| K2 declared at | qt_widgets/CMakeLists.txt, if(APPLE) block |
| K3 declared at | qt_quick/CMakeLists.txt, set_target_properties block |
macOS has two independent icons. The bundle icon is what Finder, the DMG window,
Launchpad and the not-running Dock tile show; the window icon of ICO-F2 is what
the running application shows. Setting one does not set the other, which is why
the reported defect — "No icon attached to the application, but once running, it
is displayed correctly" — is a bundle-icon defect only.
Manual test charter
For each row: set up the stated condition, run the operation, confirm the result.
- ICO-O1 / ICO-F1 — On Plasma Wayland, start K2 and then K3. In each, look at the titlebar icon, the task manager entry and the Alt-Tab switcher. The icon is clean: no black rim, no stray colours at any edge. Compare against a screenshot taken before the change to confirm the rim is gone.
- ICO-F2 — Build and run on Windows, and on macOS. The window icon, the taskbar or Dock icon, and the executable's own icon are unchanged from the previous release.
- ICO-C1 — Run either UI under
WAYLAND_DEBUG=1and capture thexdg_toplevel_icon_v1traffic. Exactly oneadd_buffercall is made, and it carries the 256 raster. Four buffers, or any buffer smaller than 256, is a failure. Verified after implementation:QIcon(":/images/Katalog_logo_256.png")reportsavailableSizes count=1at 256x256, so Qt offers a single buffer where the.icopreviously offered four (16/32/48/256). That is the configuration measured clean as probe B2. - ICO-C2 — Confirm the
.icois still present inassets/, still listed in both.qrcfiles, and still referenced by the Windows.rc. It is not expected in the macOS bundle configuration; ifMACOSX_BUNDLE_ICON_FILEnames a.ico, that is a failure ofICO-C10. - ICO-C3 — Open
mainwindow.uiin Designer: thewindowIconproperty is still set to the.ico. Then run K2 on Linux and confirm the effective icon is the PNG, proving the C++ call overrides it. Then build for Windows and confirm the effective icon is the.ico. - ICO-C4 — Review the K2 diff: it touches the icon source and nothing else. No layout, no string, no behaviour change.
- ICO-C5 — Configure a clean build tree with no ImageMagick installed. Both UIs configure and build successfully.
grepthe CMake files for any image conversion command: none is present. - ICO-C6 — Install K2 into a clean prefix:
bin/Katalog, one desktop entry, eight icons. Remove it, install K3 into the same clean prefix: the samebin/Katalog, the same single desktop entry, the same eight icons. Confirm only one desktop entry exists inshare/applicationsin each case. Verified after implementation: a staged install of each UI into a throwaway prefix produced byte-identical layouts —bin/Katalog, oneio.github.stephanecouturier.Katalog.desktop, and the eight hicolor icons. - ICO-F3 / ICO-O2 — After installing either UI, open the application launcher and search for Katalog. One entry appears, with the correct name, description and icon. Launching it starts the installed UI.
- ICO-F4 — List
share/icons/hicolor/*/apps/after install. All eight sizes are present, each namedio.github.stephanecouturier.Katalog.png, and each opens as a valid PNG at its nominal size. Verified after implementation: every staged image's pixel dimensions were checked against its directory name; all eight match, and all are 8-bit RGBA so the alpha channel survived generation. - ICO-C7 — Diff the installed desktop entry against
packaging/linux/Katalog.desktop: byte-identical apart from the filename. Confirm every localisedName,GenericName,CommentandKeywordsline is unchanged. - ICO-C8 — Review the full diff for
tr(andqsTr(: no addition, no change, no removal. - ICO-C9 — Confirm no file under
core/is modified. - ICO-O3 / ICO-F5 — On macOS, mount the released DMG. The
Katalog.apptile in the DMG window shows the Katalog icon, not the generic application placeholder. Copy it to/Applications: it shows the Katalog icon in Finder and in Launchpad, and on the Dock tile before it is started. Repeat for K2 and K3. - ICO-C10 —
plutil -p Katalog.app/Contents/Info.plist | grep CFBundleIconFilenames an.icns, andls Katalog.app/Contents/Resources/lists that exact file. A.icoin either place is a failure. - ICO-C11 / ICO-C5 —
grepboth CMake files foriconutil,sipsor any image conversion command: none is present. The.icnsis a committed file inassets/. - ICO-C12 —
grepbothimages.qrcfiles for.icns: no match. - ICO-C13 — Review the diff:
qt_quick/main.cppandqt_widgets/mainwindow.uiare unmodified. Run each UI on macOS and confirm the running Dock icon and window icon are unchanged from beta1. - ICO-C14 — Review the K2 diff:
qt_widgets/CMakeLists.txtand the new asset only.