Files
TNCcat/README.md
T
JulianandClaude Opus 5 0aceb3665d Fix the collapsed cat window on Linux, warn about the compositor
The CatDefs singleton did not resolve on the reporter's Linux build, which
showed up as "property mood of object CatDefs is not a function". The same
lookup failure made CatDefs.aspect undefined, so the cat window's height became
NaN and the cat rendered as a moving line. The mug survived because its height
used a literal ratio.

The singleton is gone rather than repaired, since nothing in it had to be
shared. The mood name now comes from C++, derived from the enum key, so there
is one source of truth instead of a list in QML that had to match. Window sizes
now follow the implicit size of the drawing they contain, so the proportions
live in the one file that defines them.

Also for X11: TNCat now warns, naming Xfce's compositor setting, when its
window comes up without an alpha channel, which is what a missing compositor
looks like and why the mug had a black background. Opaque mode no longer hides
the chip and the mug. TNCAT_DEBUG=1 logs window geometry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 09:33:44 +02:00

7.6 KiB

TNCat

A little cat that wanders along the bottom edge of the screen, sits down, grooms itself, stretches, dashes off and takes naps. Every now and then a curled steel chip skitters past and the cat goes after it, or a mug appears and the cat takes a coffee break. Drag it around, tap it to pet it, and it purrs.

It announces what it is doing in the machine's own language: G00 when it sprints, G01 when it strolls, M08 while it washes, G28 when it stretches back to reference, M30 when it goes to sleep, M01 when it stops for coffee.

The name is TNC plus cat, because the intended home is a HEIDENHAIN control (TNC7, TNC 640). Primary target is therefore Linux / X11; development happens on macOS and both are supported by the same code.

Inspired by workcat.app, rebuilt from scratch as a plain Qt 6 / QML project.

Layout

Path Purpose
CMakeLists.txt qt_add_executable + qt_add_qml_module (URI TNCat), macOS bundle, .desktop file on Linux
src/main.cpp Wires AppSettings and CatController into the QML engine, warns on Wayland
qml/AppButton.qml, qml/AppSlider.qml, qml/AppToggle.qml, qml/SettingsGroup.qml The controls, built from primitives
src/catcontroller.* Mood machine (walk, run, sit, groom, stretch, sleep, love, alert, chase, bat, drink), movement tick, chip chase, coffee break, cursor tracking
src/appsettings.* QSettings-backed coat, size, pace, ground line, eye tracking, pet counter
src/platforminfo.* QML singleton Platform: platform name plus the X11 escape hatches
qml/Main.qml Non-visual root that picks the window layout for the platform
qml/CatWindow.qml, qml/ChipWindow.qml, qml/CupWindow.qml One small window each, positioned by the app. X11, macOS, Windows
qml/OverlayWindow.qml One screen-filling click-through window holding both. Wayland
qml/Cat.qml The drawing: rounded primitives plus Shape paths for tail, ears and mouth
qml/Chip.qml The curled chip, a stroked Shape spiral
qml/Cup.qml The coffee mug, with Shape steam wisps
qml/SettingsWindow.qml Coat swatches, size, pace, ground line, eye tracking, codes, chips, coffee, tricks

The cat is drawn in a fixed 100 x 90 design space and scaled by width / 100, so every size setting stays crisp. There are no image assets, which keeps the whole thing to one binary plus Qt.

Build

macOS with the Qt online installer:

~/Qt/6.11.1/macos/bin/qt-cmake -S . -B build -G Ninja -DCMAKE_MAKE_PROGRAM=$HOME/Qt/Tools/Ninja/ninja

Linux with distribution Qt packages:

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build

Needs Qt 6.5 or newer. Required modules: Core, Gui, Quick, QuickShapes. There is no dependency on Qt Quick Controls and none on Qt Widgets: every control in the settings window is built from Qt Quick primitives, and there is no tray icon, which is the only thing that pulled Widgets in.

Check what actually got linked with:

otool -L build/tncat.app/Contents/MacOS/tncat | grep -o 'Qt[A-Za-z]*\.framework' | sort -u

Environment switches

Variable Effect
TNCAT_X11_BYPASS=1 Adds Qt::X11BypassWindowManagerHint, making an override-redirect window. Use when the window manager refuses to keep the cat on top or shows it in the taskbar.
TNCAT_OVERLAY=1 Forces the screen-filling overlay layout that Wayland needs, for testing it on X11.
TNCAT_OPAQUE=1 Paints a solid background instead of relying on transparency. Use when no compositor runs and the cat sits in a black box.
TNCAT_POSE=Sitting Freezes the cat in one mood. Handy for screenshots. Accepts any CatController::Mood name.
TNCAT_DEBUG=1 Logs the cat window's geometry and the screen it sits on, every time either changes. First thing to try when a window comes up the wrong size.
QT_QUICK_BACKEND=software Qt Quick's software rasteriser, for machines without a usable OpenGL driver. Shape falls back to its geometry renderer on its own.

Two window layouts

On X11, macOS and Windows the cat, the chip and the mug each get their own small, frameless, always-on-top window, and the app moves those windows around. Nothing else on screen is covered and no clicks are intercepted.

Wayland does not let a client place its own window, so that layout cannot work there. In overlay mode the app instead opens one screen-filling transparent window, moves the cat inside it, and restricts the window's input region to the cat's rectangle with QWindow::setMask, so every click outside the cat lands on whatever is behind. The mask is refreshed about 30 times a second while the cat walks.

Overlay mode switches on automatically on Wayland. TNCAT_OVERLAY=1 turns it on anywhere for testing. It is not the default elsewhere because macOS ignores the input mask, which would make the overlay swallow every click on the desktop.

Xfce and X11

This is the main target. Two things to know.

Transparency needs a compositor. Without one, X11 has no alpha channel to composite against and the transparent window background renders as a black box around the cat. In Xfce it is one checkbox: Settings, Window Manager Tweaks, Compositor, Enable display compositing. TNCat prints a warning naming that setting when its window comes up without an alpha channel. TNCAT_OPAQUE=1 paints a solid background instead, which is usable but not pretty.

Keeping the cat on top. The default is a frameless Qt::Tool window that stays on top. If the window manager puts it behind other windows or shows it in the taskbar, TNCAT_X11_BYPASS=1 makes it an override-redirect window that the window manager does not manage at all.

Running on a HEIDENHAIN control

Untested on real hardware so far. What the code already does for that target:

  • X11 today, Wayland later. Both layouts are in the build; the platform picks one at startup.
  • No tray, no menu bar item. The cat itself is the whole interface: right-click or long-press opens the settings window. Quit from the button there, with Ctrl+C in the terminal that started it, or by killing the process.
  • Touch works without hover. Tap pets the cat, drag picks it up. The blush on hover is a mouse-only extra, not a requirement.
  • Ground line setting. The cat normally stands on the bottom of the available screen area. On a control whose lower edge carries softkeys, raise the ground line in the settings so the cat walks above them.

What still needs checking on the actual machine:

  • Qt version and libraries on HEROS. Build against what the control has, or ship a self-contained bundle with the Qt libraries next to the binary. Building on a newer distribution than the control runs will fail at load time on glibc.
  • Graphics stack. If Qt Quick cannot get an OpenGL context, start with QT_QUICK_BACKEND=software. The drawing is simple enough for that path.
  • Window management. The NC user interface runs fullscreen. Try the default flags first, then TNCAT_X11_BYPASS=1 if the cat disappears behind it.
  • Installing anything on a control is subject to your site's rules. Keep the cat away from anything the operator needs to read, and clear it with whoever administers the machine before it runs on production hardware.

Interaction

Input Result
Click or tap Pet the cat, it closes its eyes and purrs
Drag Pick the cat up and put it somewhere else
Hover Blush and purr wiggle
Double-click, right-click or long-press Settings window
Settings window Coat, size, pace, ground line, habits, tricks, quit