import Quickshell import Quickshell.Bluetooth import Quickshell.Wayland import Quickshell.Hyprland import QtQuick import QtMultimedia PanelWindow { id: overlay anchors { top: true left: true right: true bottom: true } WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.focusable: true WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive WlrLayershell.namespace: "deltarune-startup-overlay" color: "#000000" exclusionMode: ExclusionMode.Ignore aboveWindows: true focusable: true property string bluetoothTargetName: "JBL Tune 525BT" property int bluetoothTimeoutMs: 5000 property bool waitingForBluetooth: true property bool animationLaunchScheduled: false property bool animationStarted: false function bluetoothModelCount() { if (!Bluetooth.devices) return 0; if (typeof Bluetooth.devices.count === "function") return Bluetooth.devices.count(); if (Bluetooth.devices.count !== undefined) return Bluetooth.devices.count; if (Bluetooth.devices.length !== undefined) return Bluetooth.devices.length; return 0; } function bluetoothModelGet(index) { if (!Bluetooth.devices || index < 0 || index >= bluetoothModelCount()) return null; if (Bluetooth.devices.get) return Bluetooth.devices.get(index); if (Bluetooth.devices.length !== undefined) return Bluetooth.devices[index]; return null; } function bluetoothDeviceName(device) { if (!device) return ""; if (device.name && device.name.length > 0) return String(device.name); if (device.deviceName && device.deviceName.length > 0) return String(device.deviceName); return ""; } function findTargetBluetoothDevice() { for (var i = 0; i < bluetoothModelCount(); i++) { var device = bluetoothModelGet(i); if (bluetoothDeviceName(device) === bluetoothTargetName) return device; } return null; } function beginAnimation() { if (animationStarted || animationLaunchScheduled) return; waitingForBluetooth = false; bluetoothRetryTimer.stop(); bluetoothTimeoutTimer.stop(); animationLaunchScheduled = true; startupDelayTimer.restart(); } function handlePrimaryAction() { if (!animationStarted) beginAnimation(); else finishStartup(); } function finishStartup() { if (player.playbackState !== MediaPlayer.StoppedState) player.stop(); else Qt.quit(); } HyprlandFocusGrab { active: true windows: [overlay] } FocusScope { id: overlayFocus anchors.fill: parent focus: true Component.onCompleted: overlayFocus.forceActiveFocus() onVisibleChanged: if (visible) overlayFocus.forceActiveFocus() onFocusChanged: if (focus) overlayFocus.forceActiveFocus() Keys.onReleased: function (event) { switch (event.key) { case Qt.Key_Z: case Qt.Key_Return: case Qt.Key_Enter: event.accepted = true; overlay.handlePrimaryAction(); return; } } } Connections { target: Bluetooth.devices ignoreUnknownSignals: true function onCountChanged() { if (overlay.waitingForBluetooth) bluetoothRetryTimer.restart(); } function onModelReset() { if (overlay.waitingForBluetooth) bluetoothRetryTimer.restart(); } function onRowsInserted() { if (overlay.waitingForBluetooth) bluetoothRetryTimer.restart(); } } MediaPlayer { id: player source: "deltarune.webm" // Local file or URL autoPlay: false videoOutput: videoOutput playbackRate: 1 audioOutput: AudioOutput {} onPlaybackStateChanged: a => { if (player.playbackState === MediaPlayer.StoppedState) overlay.finishStartup(); } } Timer { id: startupDelayTimer interval: 1000 repeat: false onTriggered: { overlay.animationLaunchScheduled = false; overlay.animationStarted = true; player.play(); } } Timer { id: bluetoothRetryTimer interval: 250 running: true repeat: true onTriggered: { if (!overlay.waitingForBluetooth) { stop(); return; } const device = overlay.findTargetBluetoothDevice(); if (!device) return; if (device.connected) { overlay.beginAnimation(); return; } device.connect(); } } Timer { id: bluetoothTimeoutTimer interval: overlay.bluetoothTimeoutMs running: true repeat: false onTriggered: overlay.beginAnimation() } VideoOutput { id: videoOutput anchors.fill: parent } Text { visible: overlay.waitingForBluetooth anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter color: "#ffffff" font.family: "Determination Mono" font.pixelSize: 28 text: "CONNECTING TO " + overlay.bluetoothTargetName.toUpperCase() z: 1 } Text { visible: !overlay.animationStarted anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.bottomMargin: 56 color: "#ffffff" font.family: "Determination Mono" font.pixelSize: 28 text: overlay.waitingForBluetooth ? "PRESS Z OR ENTER TO SKIP WAIT" : "STARTING..." z: 1 } MouseArea { anchors.fill: parent acceptedButtons: Qt.NoButton hoverEnabled: true cursorShape: Qt.BlankCursor } }