pragma ComponentBehavior: Bound import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Layouts import QtQuick.Shapes import qs.widgets.bar import qs.widgets.theme // Headlessly renderable visual core for the primary application launcher. // Runtime concerns (DesktopEntries, layer shell, launching) stay in // ApplicationLauncher.qml; this component only renders state and emits intent. Item { id: root property var apps: [] property int selectedIndex: 0 property bool showIcons: true property alias query: searchInput.text readonly property var selectedApp: apps.length > 0 && selectedIndex >= 0 && selectedIndex < apps.length ? apps[selectedIndex] : null signal selectionRequested(int index) signal moveRequested(int delta) signal launchRequested(int index) signal dismissRequested function focusSearch() { searchInput.forceActiveFocus(); } function clearSearch() { searchInput.text = ""; } implicitWidth: 1080 implicitHeight: 620 component MicroText: Text { color: Theme.muted font.family: Theme.microFont font.pixelSize: 7 font.letterSpacing: 0.9 elide: Text.ElideRight } component KeyHint: Row { property string keyText: "" property string actionText: "" spacing: 6 Rectangle { width: keyLabel.implicitWidth + 10 height: 18 color: Theme.accentAlpha(0.14) border.width: 1 border.color: Theme.accent Text { id: keyLabel anchors.centerIn: parent text: parent.parent.keyText color: Theme.accent font.family: Theme.microFont font.pixelSize: 7 font.bold: true } } MicroText { anchors.verticalCenter: parent.verticalCenter text: parent.actionText } } StatusBarPanel { anchors.fill: parent panelId: "008" title: "APPLICATION COMMAND INDEX" meta: root.apps.length + " TARGETS" chamfer: 18 // Query module. StatusBarPanel { id: queryPanel x: 18 y: 34 width: 670 height: 76 panelId: "QRY" title: "SEARCH VECTOR" meta: "FUZZY / PREFIX" RowLayout { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.leftMargin: 16 anchors.rightMargin: 16 anchors.topMargin: 31 height: 34 spacing: 12 Text { text: ">_" color: Theme.accent font.family: Theme.displayFont font.pixelSize: 20 font.bold: true } TextInput { id: searchInput Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: TextInput.AlignVCenter color: Theme.text selectionColor: Theme.accent selectedTextColor: Theme.surface font.family: Theme.displayFont font.pixelSize: 18 font.letterSpacing: 1 clip: true onTextChanged: root.selectionRequested(0) Keys.onPressed: event => { switch (event.key) { case Qt.Key_Down: case Qt.Key_Tab: root.moveRequested(1); event.accepted = true; break; case Qt.Key_Up: case Qt.Key_Backtab: root.moveRequested(-1); event.accepted = true; break; case Qt.Key_PageDown: root.moveRequested(5); event.accepted = true; break; case Qt.Key_PageUp: root.moveRequested(-5); event.accepted = true; break; case Qt.Key_Return: case Qt.Key_Enter: root.launchRequested(root.selectedIndex); event.accepted = true; break; case Qt.Key_Escape: root.dismissRequested(); event.accepted = true; break; } } Text { anchors.fill: parent verticalAlignment: Text.AlignVCenter visible: searchInput.text.length === 0 text: "TYPE APPLICATION DESIGNATION" color: Theme.muted font: searchInput.font } } Rectangle { Layout.preferredWidth: 84 Layout.preferredHeight: 22 color: Theme.accentAlpha(0.12) border.width: 1 border.color: Theme.hair Text { anchors.centerIn: parent text: "LIVE INDEX" color: Theme.accent font.family: Theme.microFont font.pixelSize: 7 font.bold: true font.letterSpacing: 0.8 } } } } // Search result table. StatusBarPanel { id: resultPanel x: 18 y: 118 width: 670 height: 424 panelId: "IDX" title: "APPLICATION TABLE" meta: root.query.length > 0 ? "FILTER ACTIVE" : "A–Z / LOCAL" ListView { id: appList x: 9 y: 29 width: parent.width - 18 height: parent.height - 38 clip: true spacing: 3 model: root.apps currentIndex: root.selectedIndex boundsBehavior: Flickable.StopAtBounds onCurrentIndexChanged: positionViewAtIndex(currentIndex, ListView.Contain) delegate: MouseArea { id: row required property int index required property var modelData width: ListView.view.width height: 48 hoverEnabled: true cursorShape: Qt.PointingHandCursor readonly property bool selected: index === root.selectedIndex onEntered: root.selectionRequested(index) onClicked: root.launchRequested(index) Shape { id: rowShape anchors.fill: parent preferredRendererType: Shape.CurveRenderer ShapePath { fillColor: row.selected ? Theme.selection : Theme.textAlpha(0.025) strokeColor: row.selected ? Theme.accent : Theme.textAlpha(0.10) strokeWidth: 1 startX: 9; startY: 0 PathLine { x: rowShape.width; y: 0 } PathLine { x: rowShape.width - 9; y: rowShape.height } PathLine { x: 0; y: rowShape.height } PathLine { x: 9; y: 0 } } ShapePath { fillColor: row.selected ? Theme.accent : Theme.textAlpha(0.12) strokeWidth: 0 startX: 9; startY: 0 PathLine { x: 13; y: 0 } PathLine { x: 4; y: rowShape.height } PathLine { x: 0; y: rowShape.height } PathLine { x: 9; y: 0 } } } RowLayout { anchors.fill: parent anchors.leftMargin: 18 anchors.rightMargin: 18 spacing: 12 Text { Layout.preferredWidth: 28 text: String(row.index + 1).padStart(2, "0") color: row.selected ? Theme.accent : Theme.muted font.family: Theme.microFont font.pixelSize: 8 font.bold: row.selected } Rectangle { Layout.preferredWidth: 34 Layout.preferredHeight: 34 color: row.selected ? Theme.accentAlpha(0.14) : Theme.textAlpha(0.035) border.width: 1 border.color: row.selected ? Theme.accent : Theme.hair IconImage { visible: root.showIcons anchors.centerIn: parent implicitSize: 24 source: root.showIcons ? Quickshell.iconPath(row.modelData.icon || "application-x-executable", "application-x-executable") : "" } Text { visible: !root.showIcons anchors.centerIn: parent text: String(row.modelData.name || "?").charAt(0).toUpperCase() color: row.selected ? Theme.accent : Theme.text font.family: Theme.displayFont font.pixelSize: 14 font.bold: true } } ColumnLayout { Layout.fillWidth: true spacing: 1 Text { Layout.fillWidth: true text: row.modelData.name || "UNKNOWN TARGET" color: row.selected ? Theme.accent : Theme.text font.family: Theme.displayFont font.pixelSize: 11 font.bold: row.selected font.letterSpacing: 0.5 elide: Text.ElideRight } MicroText { Layout.fillWidth: true text: row.modelData.genericName || row.modelData.comment || "DESKTOP APPLICATION" } } MicroText { Layout.preferredWidth: 100 horizontalAlignment: Text.AlignRight text: row.index === root.selectedIndex ? "LOCKED" : "AVAILABLE" color: row.selected ? Theme.accent : Theme.muted } Rectangle { Layout.preferredWidth: 38 Layout.preferredHeight: 6 color: Theme.textAlpha(0.05) border.width: 1 border.color: Theme.hair Rectangle { width: row.selected ? parent.width : Math.max(5, parent.width * (1 - row.index / Math.max(1, root.apps.length))) height: parent.height color: row.selected ? Theme.accent : Theme.textAlpha(0.20) } } } } Text { anchors.centerIn: parent visible: root.apps.length === 0 text: "NO EXECUTABLE TARGETS MATCH QUERY" color: Theme.muted font.family: Theme.microFont font.pixelSize: 9 font.letterSpacing: 1.2 } } } // Selected application inspector. StatusBarPanel { id: inspector x: 700 y: 34 width: 362 height: 508 panelId: "SEL" title: "TARGET INSPECTOR" meta: root.selectedApp ? "LOCKED" : "NO TARGET" Item { id: reticle anchors.horizontalCenter: parent.horizontalCenter y: 39 width: 126 height: 126 Rectangle { anchors.centerIn: parent width: 112 height: 112 radius: 56 color: Theme.textAlpha(0.015) border.width: 1 border.color: Theme.accentAlpha(0.52) } Rectangle { anchors.centerIn: parent width: 84 height: 84 radius: 42 color: Theme.textAlpha(0) border.width: 1 border.color: Theme.hair } Rectangle { anchors.centerIn: parent; width: 126; height: 1; color: Theme.hair } Rectangle { anchors.centerIn: parent; width: 1; height: 126; color: Theme.hair } Rectangle { anchors.centerIn: parent width: 60 height: 60 color: Theme.surface border.width: 1 border.color: Theme.accent IconImage { visible: root.showIcons anchors.centerIn: parent implicitSize: 44 source: root.showIcons && root.selectedApp ? Quickshell.iconPath(root.selectedApp.icon || "application-x-executable", "application-x-executable") : "" } Text { visible: !root.showIcons anchors.centerIn: parent text: root.selectedApp ? String(root.selectedApp.name || "?").charAt(0).toUpperCase() : "?" color: Theme.accent font.family: Theme.displayFont font.pixelSize: 28 font.bold: true } } Repeater { model: 4 Rectangle { required property int index width: 5; height: 5 x: index % 2 === 0 ? 8 : reticle.width - 13 y: index < 2 ? 8 : reticle.height - 13 color: Theme.accent } } } Text { anchors.top: reticle.bottom anchors.topMargin: 14 anchors.horizontalCenter: parent.horizontalCenter width: parent.width - 34 horizontalAlignment: Text.AlignHCenter text: root.selectedApp ? root.selectedApp.name : "NO TARGET" color: Theme.text font.family: Theme.displayFont font.pixelSize: 19 font.bold: true font.letterSpacing: 1 elide: Text.ElideRight } MicroText { id: genericLabel anchors.top: reticle.bottom anchors.topMargin: 42 x: 18 width: parent.width - 36 horizontalAlignment: Text.AlignHCenter text: root.selectedApp ? (root.selectedApp.genericName || "DESKTOP APPLICATION") : "AWAITING SEARCH VECTOR" color: Theme.accent } Rectangle { x: 18 anchors.top: genericLabel.bottom anchors.topMargin: 12 width: parent.width - 36 height: 1 color: Theme.hair } MicroText { id: description x: 22 anchors.top: genericLabel.bottom anchors.topMargin: 27 width: parent.width - 44 height: 42 text: root.selectedApp ? (root.selectedApp.comment || "No application description supplied by desktop entry.") : "Enter a designation to acquire an executable target." wrapMode: Text.Wrap elide: Text.ElideRight maximumLineCount: 3 horizontalAlignment: Text.AlignHCenter } GridLayout { id: telemetryGrid x: 18 anchors.top: description.bottom anchors.topMargin: 15 width: parent.width - 36 columns: 2 rowSpacing: 7 columnSpacing: 7 Repeater { model: [ { label: "ENTRY", value: "DESKTOP" }, { label: "MODE", value: "DETACHED" }, { label: "AUTH", value: "LOCAL USER" }, { label: "INDEX", value: String(Math.max(0, root.selectedIndex + 1)).padStart(3, "0") } ] Rectangle { required property var modelData Layout.fillWidth: true Layout.preferredHeight: 46 color: Theme.textAlpha(0.025) border.width: 1 border.color: Theme.hair MicroText { x: 8; y: 7; width: parent.width - 16; text: modelData.label } Text { x: 8; y: 22; width: parent.width - 16 text: modelData.value color: Theme.text font.family: Theme.displayFont font.pixelSize: 9 font.bold: true font.letterSpacing: 0.6 elide: Text.ElideRight } } } } Item { x: 18 anchors.bottom: executeTile.top anchors.bottomMargin: 12 width: parent.width - 36 height: 18 Row { spacing: 5 Repeater { model: 24 Rectangle { required property int index width: 7; height: 3 y: index % 3 === 0 ? 0 : 4 color: index < 16 ? Theme.accent : Theme.hair transform: Rotation { angle: -35 } } } } } MouseArea { id: executeTile x: 18 anchors.bottom: parent.bottom anchors.bottomMargin: 14 width: parent.width - 36 height: 42 enabled: root.selectedApp !== null hoverEnabled: true cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: root.launchRequested(root.selectedIndex) Rectangle { anchors.fill: parent color: executeTile.containsMouse ? Theme.accent : Theme.accentAlpha(0.16) border.width: 1 border.color: Theme.accent Text { anchors.centerIn: parent text: root.selectedApp ? "EXECUTE SELECTED TARGET" : "NO TARGET ACQUIRED" color: executeTile.containsMouse ? Theme.surface : Theme.accent font.family: Theme.displayFont font.pixelSize: 10 font.bold: true font.letterSpacing: 1.2 } } } } // Dense command footer. StatusBarPanel { x: 18 y: 550 width: 1044 height: 52 showHeader: false chamfer: 9 RowLayout { anchors.fill: parent anchors.leftMargin: 16 anchors.rightMargin: 16 spacing: 18 MicroText { text: "INPUT CHANNEL // KEYBOARD"; color: Theme.accent } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 22; color: Theme.hair } KeyHint { keyText: "↑ ↓"; actionText: "SELECT" } KeyHint { keyText: "ENTER"; actionText: "EXECUTE" } KeyHint { keyText: "ESC"; actionText: "ABORT" } Item { Layout.fillWidth: true } MicroText { text: "QRY:" + (root.query.length > 0 ? "ACTIVE" : "IDLE") } MicroText { text: "CRC // A7F2" } Rectangle { Layout.preferredWidth: 76 Layout.preferredHeight: 4 color: Theme.accent } } } } }