The project is now TNCat, after HEIDENHAIN's TNC controls. Binary, QML module URI, settings path, bundle id and .desktop entry follow; the environment switches are TNCAT_*. Entertainment: a curled steel chip skitters in every minute or two, the cat runs it down and bats it away a few times before sitting back looking pleased. Mood changes flash the matching machine code above its head, G00 for a sprint, G01 for a stroll, M08 while it washes, G28 for a stretch, M30 for a nap. Window handling was split into two layouts. X11 and macOS keep one small window per object, positioned by the app. Wayland gets a screen-filling overlay whose input region is masked down to the cat, since a Wayland client cannot place its own window. Overlay mode is automatic there and available elsewhere via TNCAT_OVERLAY=1. Also adds a ground-line setting so the cat can walk above a softkey row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
126 lines
6.1 KiB
Markdown
126 lines
6.1 KiB
Markdown
# 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. 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.
|
|
|
|
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), movement tick, chip chase, 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` | 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/SettingsWindow.qml` | Coat swatches, size, pace, ground line, eye tracking, codes, chips, 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 and the chip 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 |
|