# 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](https://workcat.app/en/), 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 | | `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 | | `src/traycontroller.*` | Tray icon and menu, silently skipped when the desktop has no tray | | `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: ```bash ~/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: ```bash cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release ``` ```bash cmake --build build ``` Needs Qt 6.5 or newer. Required modules: Core, Gui, Quick, QuickControls2, Widgets. Widgets is only there because `QSystemTrayIcon` needs it for its context menu. ## 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. | | `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. ## 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 required.** If the desktop has no status-notifier host, the tray icon is skipped and the cat itself stays the entry point: long-press or right-click opens the settings window. - **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 or right-click | Settings window | | Tray menu | Tricks, nap toggle, settings, quit |