Files
TNCcat/qml/ChipWindow.qml
T
JulianandClaude Opus 5 d685bf492a Shape the window when there is no compositor
On Xfce with compositing off, X11 has no alpha to blend against, so the
transparent background came out as a black box around the cat.

When a window comes up without an alpha channel, TNCat now cuts the window down
to the pixels the drawing covers, using the X11 shape extension, and refreshes
that 15 times a second so it follows the animation. A sitting cat in a 120 x 106
window comes out as 96 rectangles over 29 percent of the window, so most of the
box is gone. Edges are harder than with a compositor, one bit per pixel, and the
log says so and names the Xfce setting that gives smooth ones instead.

The image-to-rectangles step is platform independent and folds every device row
into its window row, which both halves the rectangle count on a scaled display
and keeps a pixel that is opaque in only one of them.

xcb and xcb-shape are picked up through pkg-config on Unix and the build still
works without them. Opaque mode now paints a neutral card rather than the coat
colour.

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

44 lines
1.3 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import TNCat
// The chip gets its own little click-through window so it can skitter away
// from the cat across the whole screen.
Window {
id: win
required property CatController cat
required property AppSettings settings
readonly property int chipSize: Math.round(settings.catSize * 0.46)
width: chipSize
height: Math.round(width * curl.implicitHeight / curl.implicitWidth)
x: cat.chipX - width / 2
y: Screen.desktopAvailableHeight - height - settings.bottomMargin
color: Platform.opaqueBackground ? "#d8d8d8" : "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool
| Qt.NoDropShadowWindowHint | Qt.WindowDoesNotAcceptFocus
| Qt.WindowTransparentForInput
| (Platform.bypassWindowManager ? Qt.X11BypassWindowManagerHint : 0)
visible: cat.chipVisible
Behavior on x {
NumberAnimation { duration: 320; easing.type: Easing.OutQuad }
}
Timer {
interval: 66
repeat: true
running: Platform.shapeWindows && win.visible
triggeredOnStart: true
onTriggered: Platform.updateWindowShape(win)
}
Chip {
id: curl
anchors.fill: parent
spin: win.cat.chipSpin
}
}