pragma ComponentBehavior: Bound import QtQuick import TNCat // One screen-filling, click-through window that holds the cat and the chip. // Wayland does not let a client place its own window, so there the cat moves // inside this overlay instead of the window moving across the desktop. Window { id: win required property CatController cat required property AppSettings settings signal settingsRequested() // Fullscreen is a visibility, not a visible flag, so the mode switch has to // go through visibility or the two fight each other. property bool overlayActive: false readonly property int catW: settings.catSize readonly property int catH: Math.round(settings.catSize * CatDefs.aspect) readonly property real groundY: height - catH - settings.bottomMargin // Only the cat itself should swallow clicks; everything else falls through. function refreshInputRegion() { Platform.setInputRegion(win, Qt.rect(Math.round(cat.x), Math.round(groundY), catW, catH)) } visibility: overlayActive ? Window.FullScreen : Window.Hidden color: "transparent" flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.NoDropShadowWindowHint | Qt.WindowDoesNotAcceptFocus title: qsTr("TNCat") onOverlayActiveChanged: { if (!overlayActive) return cat.stageWidth = width cat.catWidth = catW refreshInputRegion() } onWidthChanged: cat.stageWidth = width onCatWChanged: cat.catWidth = catW Binding { target: win.cat property: "catCenter" value: Qt.point(win.x + win.cat.x + win.catW / 2, win.y + win.groundY + win.catH / 2) } // Coalesce mask updates: one X11 round trip per frame of walking is plenty. Timer { interval: 33 running: win.overlayActive repeat: true onTriggered: win.refreshInputRegion() } Chip { x: win.cat.chipX - width / 2 y: win.height - height - win.settings.bottomMargin width: Math.round(win.settings.catSize * 0.45) height: Math.round(width * 0.73) visible: win.cat.chipVisible kick: win.cat.chipKick Behavior on x { NumberAnimation { duration: 320; easing.type: Easing.OutQuad } } } Cup { x: win.cat.cupX - width / 2 y: win.height - height - win.settings.bottomMargin width: Math.round(win.settings.catSize * 0.38) height: Math.round(width * 1.18) visible: win.cat.cupVisible } Item { id: catItem x: win.cat.x y: win.groundY width: win.catW height: win.catH Cat { anchors.fill: parent coat: win.settings.coat facingRight: win.cat.facingRight mood: CatDefs.mood(win.cat.mood) 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.catW, catItem.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() } } }