Files
JulianandClaude Opus 5 a01843a312 Revert the X11 window shaping
It did not build, xcb_shape_id was not resolving, and it was not worth fixing.
It bought a workaround for one configuration, cost two libraries and a window
grab fifteen times a second, and still gave harder edges than the thing it was
working around.

Qt's transparent window background is the right mechanism and it already works.
On X11 it needs a compositing manager, which Xfce ships with and which was
simply switched off. The warning that names that setting stays, so the cause
shows up in the log.

Kept from the reverted commit: opaque mode paints a neutral card rather than
the coat colour.

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

157 lines
7.9 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, 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 |
| `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:
```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, 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:
```bash
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.** Qt draws the cat on a transparent window
background, and on X11 that only works while a compositing manager is running.
Without one there is no alpha channel to blend against and the background comes
out black, so the cat sits in a black box.
Xfce has a compositor built in. Turn it on under Settings, Window Manager
Tweaks, Compositor, Enable display compositing. That is the whole fix.
TNCat prints a warning naming that setting when its window comes up without an
alpha channel, so the cause is in the log rather than left to guesswork. If the
compositor has to stay off, `TNCAT_OPAQUE=1` paints a solid background instead:
the cat then sits on a plain card, which is honest 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 |