Back to news

Every app asks differently

A run of days that all turned out to be the same lesson wearing different clothes. The desktop knew the accent colour, the cursor theme, the button layout, the menu. It was publishing all of it. And yet app after app ignored it and fell back to some grey default, and each time the reason was the same: the app was asking for that fact in a dialect I wasn’t answering.

The clearest case was the one where GTK apps showed only a close button, no minimize or maximize, even though my own apps wore all three and the setting was plainly there. What made it strange is that it worked the instant you toggled anything in settings, and never on a cold start. That split, live works, fresh launch doesn’t, is the tell: two different sources, and only one of them right. So I watched the bus while a window opened, and there it was. At startup GTK asks the settings portal for everything under org.gnome.*, a wildcard, in one call. My portal only matched namespaces by exact string, so that wildcard request came back empty, and not just for the button layout, for the GTK theme and icon theme too. The app got nothing and fell back to GTK’s own default, which is a close-only titlebar. Teaching the portal to honour the org.gnome.* glob fixed all three in one line (github.com/…/issues/107).

The window buttons were only half of it. The bigger piece is the look of the app itself, and there is now a proper Singularity GTK theme that third-party GTK apps can opt into from settings, so a file manager or a text editor pulled from your distro’s repositories wears the same surfaces, accents and rounded corners as the rest of the desktop instead of plain stock Adwaita (github.com/…/issues/101). I did not build it from nothing. It is a fork of Orchis by vinceliuice, which I chose for two reasons: it is remarkably versatile and easy to reshape, and its baseline already sits very close to the Singularity aesthetic, so bending it the rest of the way felt natural rather than like a fight. A real thank you to vinceliuice for building and sharing it; starting from such a clean, flexible base saved a great deal of work, and that is exactly what open source is for.

The cursor was the same shape of bug. Pick a theme and most apps follow, but a few XWayland ones, Steam, Discord, stayed stubbornly on Adwaita. GTK reads the cursor name from XSETTINGS, which I was setting; apps that call libXcursor directly read it from the X resource database, which I wasn’t writing at all. Merge Xcursor.theme and Xcursor.size into that database when the theme changes and they come along too (github.com/…/issues/154). That sits on top of the cursor picker itself, which now finds the themes you actually have installed and applies them live (github.com/…/issues/149).

Flatpaks not following the accent was the same story once more, down to the data type. libadwaita reads the accent as a tuple of three numbers on the appearance portal, and I had been handing it a string, so apps like Bazaar quietly ignored it and stayed blue. Serve it as the tuple it expects and they pick it up (github.com/…/issues/160).

Then there is the hardest dialect of all, the global menu, and the place where I finally hit a wall I can’t talk my way around. Firefox and a few others don’t export their menu in any form the panel can read. The trick I leaned on elsewhere was reading the menu from the accessibility tree, but Firefox builds those entries lazily: they don’t exist until you actually open each menu on screen, so to mirror them I would have to pop every menu open first, which is not a thing anyone should watch happen. So I stopped pretending. When no real menu can be read, the File menu is now filled with the actions the app declares in its own desktop entry, shown next to the standard File and Window entries. It is a fallback, not a victory, but a populated menu beats a blank bar (github.com/…/issues/82, github.com/…/issues/112). In the same corner, Wine apps now show their real name in the menu bar instead of the literal word “Exe” (github.com/…/issues/94).

The dock had its own version of two-sources-one-truth. It and the alt-tab switcher resolved a window’s icon and name in completely different ways, so Minecraft wore its real icon in the switcher and a generic gear on the dock, and Bitwig showed up as “Unknown Wayland Surface”. I pointed the dock at the same answer the switcher already had, the window’s own icon and title, and they agree now (github.com/…/issues/159, github.com/…/issues/161). While I was there I gave the dock’s bottom shadow the room it needed, since the surface edge had been clipping it into a hard line (github.com/…/issues/162).

A handful of other things landed in between. Apps you add to the autostart list now actually launch when the session starts, the page wrote the entries but nothing had ever read them back (github.com/…/issues/170). The emoji picker closes on Escape again, app-drawer folders open and launch what you click, screenshots stopped coming out transparent and dark, fullscreening on a second monitor no longer drags the first one with it, the Wi-Fi tile in quick settings stopped flipping on and off in a loop, and the tiling preview rectangles snap into place instantly instead of arriving half a second late (github.com/…/issues/148, github.com/…/issues/51, github.com/…/issues/40, github.com/…/issues/99, github.com/…/issues/177, github.com/…/issues/120).

If these days had a lesson, it’s that there is no single “system setting” you flip once. The accent, the cursor, the menu, the window buttons: every toolkit reads them through its own channel, in its own shape, and supporting an app means answering it in the exact form it asks, not the form that felt right to me. The desktop was never wrong. It was just speaking past them.

If you try Singularity and something looks off, please tell me: open an issue on GitHub or come find me on Discord. The reports from machines that aren’t mine are what make this real.