Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clients/deck/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ target_compile_definitions(nova_deck_core

include(CTest)
if(BUILD_TESTING)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
add_executable(nova_deck_layout_test
tests/deck_layout_test.cpp
)
Expand All @@ -77,6 +78,10 @@ if(BUILD_TESTING)
)
target_link_libraries(nova_deck_stream_media_adapters_test PRIVATE nova_deck_core)
add_test(NAME nova_deck_stream_media_adapters_test COMMAND nova_deck_stream_media_adapters_test)

add_test(NAME nova_deck_gamemode_capture_harness_test
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/deck_gamemode_capture_test.py
)
endif()

option(NOVA_DECK_BUILD_QT_SHELL "Build the experimental Qt/QML Steam Deck shell" ON)
Expand Down
87 changes: 48 additions & 39 deletions clients/deck/qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ ApplicationWindow {
readonly property int sampleCardWidth: 392
readonly property int detailColumnWidth: 424
readonly property int hostCardHeight: 104
readonly property int detailPanelHeight: 196
readonly property int launchPreviewHeight: 236
readonly property int detailPanelHeight: 184
readonly property int launchPreviewHeight: 258
readonly property int hostTextWidth: hostColumnWidth - 40
readonly property int sampleTextWidth: sampleCardWidth - 48
readonly property int detailTextWidth: detailColumnWidth - 48
readonly property color focusRingColor: "#8AFFC1"
readonly property color focusGlowColor: "#243D57"
property int previewCopyActivationCount: 0
property var selectedHostForPreview: novaSelectedHostDetail
property var selectedGameForPreview: novaSelectedGameCard
Expand All @@ -34,7 +36,7 @@ ApplicationWindow {
property string selectedStreamLifecycleCopy: launchIntentPreview.streamLifecycleCopy

function selectedHostSubtitle() {
return "Read-only host detail only — not discovered from the network."
return "Selected host only — not discovered from the network."
}

function previewComponent(value) {
Expand Down Expand Up @@ -68,8 +70,8 @@ ApplicationWindow {
+ "&stream="
+ previewComponent(streamMode)
+ "&state=noop-preview"
selectedLaunchPublicCopy = "Preview " + gameTitle + " on " + hostName + " via " + steamCopy + "; no launch will run."
selectedStreamLifecycleCopy = "Preview stream for " + gameTitle + " on " + hostName + " remains noop_preview/not_started."
selectedLaunchPublicCopy = "Review " + gameTitle + " on " + hostName + " via " + steamCopy + ". Safe preview only; no game or stream starts."
selectedStreamLifecycleCopy = "Safe preview of " + gameTitle + " on " + hostName + "; stream remains not started."
launchPreviewCopyAction = {
"id": novaLaunchPreviewCopyAction.id,
"label": novaLaunchPreviewCopyAction.label,
Expand Down Expand Up @@ -167,6 +169,14 @@ ApplicationWindow {
}
}

MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
cursorShape: Qt.BlankCursor
z: 1000
}

FocusScope {
id: libraryFocusScope
anchors.fill: parent
Expand All @@ -193,7 +203,7 @@ ApplicationWindow {
}

Label {
text: "Controller-first Steam Deck shell scaffold"
text: "Your couch-ready Nova command center"
color: "#A8B0D8"
font.pixelSize: 24
}
Expand Down Expand Up @@ -227,8 +237,8 @@ ApplicationWindow {
Layout.preferredWidth: hostColumnWidth
Layout.preferredHeight: visible ? 120 : 0
radius: 20
color: activeFocus ? "#202B55" : "#151D39"
border.color: activeFocus ? "#B8C2FF" : "#39466F"
color: activeFocus ? focusGlowColor : "#151D39"
border.color: activeFocus ? focusRingColor : "#39466F"
border.width: activeFocus ? 5 : 2
focus: visible
activeFocusOnTab: visible
Expand All @@ -250,7 +260,7 @@ ApplicationWindow {
Label {
text: "Empty host state is focusable and deterministic."
color: "#A8B0D8"
font.pixelSize: 12
font.pixelSize: 14
}
}
}
Expand All @@ -268,7 +278,7 @@ ApplicationWindow {
Layout.preferredHeight: hostCardHeight
radius: 20
color: selectedHostForPreview.id === modelData.id ? "#202B55" : "#151D39"
border.color: activeFocus ? "#B8C2FF" : selectedHostForPreview.id === modelData.id ? "#8AFFC1" : "#7C73FF"
border.color: activeFocus ? focusRingColor : selectedHostForPreview.id === modelData.id ? "#8AFFC1" : "#7C73FF"
border.width: activeFocus ? 5 : selectedHostForPreview.id === modelData.id ? 4 : 3
focus: modelData.initialFocus
activeFocusOnTab: true
Expand Down Expand Up @@ -316,7 +326,7 @@ ApplicationWindow {
visible: selectedHostForPreview.id === modelData.id
text: "Selected host"
color: "#8AFFC1"
font.pixelSize: 12
font.pixelSize: 14
font.bold: true
}
}
Expand All @@ -331,15 +341,15 @@ ApplicationWindow {
spacing: deckPanelSpacing

Label {
text: "Read-only Polaris library"
text: "Polaris library preview"
color: "#E9ECFF"
font.pixelSize: 24
font.bold: true
}

Label {
Layout.preferredWidth: sampleTextWidth
text: novaLibraryFixtureSource + (novaLibraryReadOnly ? " · read-only · Read-only snapshot loaded" : " · Snapshot unavailable in this preview shell — no backend request will be made")
text: novaLibraryFixtureSource + (novaLibraryReadOnly ? " · read-only · Preview snapshot ready" : " · Snapshot unavailable in this preview shell — no backend request will be made")
color: "#A8B0D8"
font.pixelSize: 13
wrapMode: Text.WordWrap
Expand All @@ -352,8 +362,8 @@ ApplicationWindow {
Layout.preferredWidth: sampleCardWidth
Layout.preferredHeight: visible ? 116 : 0
radius: 18
color: activeFocus ? "#202B55" : "#151D39"
border.color: activeFocus ? "#B8C2FF" : "#39466F"
color: activeFocus ? focusGlowColor : "#151D39"
border.color: activeFocus ? focusRingColor : "#39466F"
border.width: activeFocus ? 5 : 2
focus: visible
activeFocusOnTab: visible
Expand All @@ -378,7 +388,7 @@ ApplicationWindow {
Layout.preferredWidth: sampleTextWidth
text: "Snapshot unavailable in this preview shell — no backend request will be made."
color: "#A8B0D8"
font.pixelSize: 12
font.pixelSize: 14
wrapMode: Text.WordWrap
}
}
Expand All @@ -397,7 +407,7 @@ ApplicationWindow {
Layout.preferredHeight: 88
radius: 18
color: selectedGameForPreview.id === modelData.id ? "#202B55" : "#151D39"
border.color: activeFocus ? "#B8C2FF" : selectedGameForPreview.id === modelData.id ? "#8AFFC1" : "#7C73FF"
border.color: activeFocus ? focusRingColor : selectedGameForPreview.id === modelData.id ? "#8AFFC1" : "#7C73FF"
border.width: activeFocus ? 5 : selectedGameForPreview.id === modelData.id ? 4 : 2
focus: modelData.initialFocus
activeFocusOnTab: true
Expand Down Expand Up @@ -445,14 +455,14 @@ ApplicationWindow {
Label {
text: modelData.launchModeLabel
color: "#A8B0D8"
font.pixelSize: 12
font.pixelSize: 14
}

Label {
visible: selectedGameForPreview.id === modelData.id
text: "Selected game"
color: "#8AFFC1"
font.pixelSize: 11
font.pixelSize: 13
font.bold: true
}
}
Expand All @@ -470,8 +480,8 @@ ApplicationWindow {
Layout.preferredWidth: detailColumnWidth
Layout.preferredHeight: detailPanelHeight
radius: 22
color: activeFocus ? "#202B55" : "#151D39"
border.color: activeFocus ? "#B8C2FF" : "#39466F"
color: activeFocus ? focusGlowColor : "#151D39"
border.color: activeFocus ? focusRingColor : "#39466F"
border.width: activeFocus ? 5 : 2
focus: true
activeFocusOnTab: true
Expand All @@ -488,7 +498,7 @@ ApplicationWindow {
spacing: 8

Label {
text: "Read-only host detail"
text: "Selected host"
color: "#7C88B8"
font.pixelSize: 16
}
Expand Down Expand Up @@ -530,8 +540,8 @@ ApplicationWindow {
Layout.preferredWidth: detailColumnWidth
Layout.preferredHeight: launchPreviewHeight
radius: 20
color: activeFocus ? "#2A2948" : "#181D34"
border.color: activeFocus ? "#B8C2FF" : "#39466F"
color: activeFocus ? focusGlowColor : "#181D34"
border.color: activeFocus ? focusRingColor : "#39466F"
border.width: activeFocus ? 5 : 2
opacity: novaHostLaunchCta.enabled ? 1.0 : 0.72
focus: false
Expand Down Expand Up @@ -561,64 +571,63 @@ ApplicationWindow {
Layout.preferredWidth: detailTextWidth
text: novaHostLaunchCta.helpText
color: "#B8C2F0"
font.pixelSize: 12
font.pixelSize: 14
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: novaHostLaunchCta.previewStateLabel
color: "#FFDDA8"
font.pixelSize: 12
font.pixelSize: 14
font.bold: true
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: "Typed launch boundary: " + novaLaunchIntentBoundary.label + " · network/process/Moonlight blocked"
text: "Safe preview: no game, stream, or network launch starts from this screen."
color: "#FFDDA8"
font.pixelSize: 11
font.pixelSize: 13
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: novaLaunchIntentBoundary.reason
color: "#A8B0D8"
font.pixelSize: 10
font.pixelSize: 13
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: selectedLaunchPublicCopy
color: "#C9F0D4"
font.pixelSize: 11
font.pixelSize: 13
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: selectedStreamLifecycleCopy
color: "#A8B0D8"
font.pixelSize: 10
font.pixelSize: 13
wrapMode: Text.WordWrap
}

Label {
Layout.preferredWidth: detailTextWidth
text: selectedLaunchPreviewText
color: "#A8B0D8"
text: "Exact preview details stay behind Copy preview details — copy locally to inspect the preview URI."
color: "#7C88B8"
font.pixelSize: 12
font.family: "monospace"
wrapMode: Text.WrapAnywhere
wrapMode: Text.WordWrap
}

Button {
id: copyPreviewButton
objectName: launchPreviewCopyAction.id
text: activeFocus ? "A · " + launchPreviewCopyAction.label : launchPreviewCopyAction.label
text: activeFocus ? "D-pad focus · A · " + launchPreviewCopyAction.label : launchPreviewCopyAction.label
enabled: launchPreviewCopyAction.enabled
focusPolicy: Qt.StrongFocus
activeFocusOnTab: true
Expand All @@ -636,9 +645,9 @@ ApplicationWindow {
Label {
id: copyStatusLabel
Layout.preferredWidth: detailTextWidth
text: launchPreviewCopyAction.idleStatusLabel + " Press A on Copy to verify. A copies the preview URI locally only."
text: launchPreviewCopyAction.idleStatusLabel + " Press A on Copy to verify. A Copy preview saves this safe plan locally for inspection."
color: "#FFDDA8"
font.pixelSize: 12
font.pixelSize: 14
wrapMode: Text.WordWrap
}
}
Expand All @@ -650,7 +659,7 @@ ApplicationWindow {

Label {
text: novaDeckFullscreenPreferred
? "Deck default: 1280×800 · fullscreen-first · controller-first"
? "D-pad Navigate · A Copy preview · 1280×800 Deck-first"
: "Deck default: 1280×800 · windowed test mode"
color: "#7C88B8"
font.pixelSize: 18
Expand Down
Loading
Loading