Files
TNCcat/qml/CatWindow.qml
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

99 lines
3.1 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import TNCat
// One small window that is exactly the cat. Used wherever a client may place
// its own window, which is everything except Wayland.
Window {
id: win
required property CatController cat
required property AppSettings settings
signal settingsRequested()
width: settings.catSize
// The drawing knows its own proportions; no constant to keep in sync.
height: Math.round(width * sprite.implicitHeight / sprite.implicitWidth)
x: cat.x
y: Screen.desktopAvailableHeight - height - settings.bottomMargin
color: Platform.opaqueBackground ? settings.coat : "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool
| Qt.NoDropShadowWindowHint | Qt.WindowDoesNotAcceptFocus
| (Platform.bypassWindowManager ? Qt.X11BypassWindowManagerHint : 0)
visible: true
title: qsTr("TNCat")
Component.onCompleted: {
cat.stageWidth = Screen.desktopAvailableWidth
cat.catWidth = width
Platform.checkTranslucency(win)
if (Platform.debug)
win.logGeometry("created")
}
function logGeometry(what) {
console.log("TNCat cat window", what,
"x", win.x, "y", win.y, "w", win.width, "h", win.height,
"| screen", Screen.width + "x" + Screen.height,
"available", Screen.desktopAvailableWidth + "x" + Screen.desktopAvailableHeight,
"| platform", Platform.name, "overlay", Platform.overlayMode)
}
onHeightChanged: if (Platform.debug) logGeometry("height changed")
onWidthChanged: {
cat.catWidth = width
if (Platform.debug)
logGeometry("width changed")
}
Screen.onDesktopAvailableWidthChanged: cat.stageWidth = Screen.desktopAvailableWidth
// The eyes need to know where the face sits on the desktop.
Binding {
target: win.cat
property: "catCenter"
value: Qt.point(win.x + win.width / 2, win.y + win.height / 2)
}
Cat {
id: sprite
anchors.fill: parent
coat: win.settings.coat
facingRight: win.cat.facingRight
mood: win.cat.moodName
lifted: win.cat.dragging
petted: win.cat.hovered && !win.cat.dragging
look: win.cat.look
showCodes: win.settings.showCodes
Accessible.role: Accessible.Button
Accessible.name: qsTr("TNCat")
}
HoverHandler {
onHoveredChanged: win.cat.hovered = hovered
}
DragHandler {
target: null
onActiveChanged: win.cat.dragging = active
onCentroidChanged: {
if (active)
win.cat.x = Math.max(0, Math.min(win.cat.stageWidth - win.width,
win.x + centroid.position.x - centroid.pressPosition.x))
}
}
TapHandler {
acceptedButtons: Qt.LeftButton
onTapped: win.cat.pet()
onDoubleTapped: win.settingsRequested()
onLongPressed: win.settingsRequested()
}
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: win.settingsRequested()
}
}