Manifest for Linux; connect as Background app where Utility is refused

- manifest.vrmanifest: binary_path_linux and binary_path_linux_arm. The
  Steam Frame's SteamVR reads only binary_path_linux_arm.
- handleManifests(): connect as Utility app first (works without a running
  SteamVR, e.g. from the Windows installer); if SteamVR refuses Utility apps,
  as on the Steam Frame, connect as Background app. Fail right away on other
  errors instead of going through initializeOpenVR()'s retry loop.
- main(): check --graphics-api before connecting to OpenVR, so a wrong value
  fails right away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Matthias Janetschek
2026-10-07 13:42:16 +02:00
co-authored by Claude Opus 5.5
parent 4826686a4d
commit b22c35ae29
4 changed files with 52 additions and 10 deletions
+20
View File
@@ -102,3 +102,23 @@
- `MyTextField` opens the SteamVR keyboard on `activeFocus`. The template had to send the - `MyTextField` opens the SteamVR keyboard on `activeFocus`. The template had to send the
offscreen window an explicit `FocusIn`, otherwise `activeFocusItem` stayed null. The `qt6` offscreen window an explicit `FocusIn`, otherwise `activeFocusItem` stayed null. The `qt6`
branch doesn't send it. If text fields don't respond on the Frame, that is the cause (R4). branch doesn't send it. If text fields don't respond on the Frame, that is the cause (R4).
### Step 4: manifest and installation (2026-10-07)
**Changes:**
- **`manifest.vrmanifest`:** `binary_path_linux` and `binary_path_linux_arm` →
`AdvancedSettings_app`.
- **`manifest::handleManifests`:**
- `VR_Init(Utility)`; on `VRInitError_Init_NotAvailableToUtilityApps`,
`VR_Init(Background)`.
- Other errors: message and exit code `OPENVR_INIT_ERROR`, instead of
`initializeOpenVR`'s retry loop.
- **`main.cpp`:** `--graphics-api` is checked before connecting to OpenVR. A wrong value
used to fail only after `initializeOpenVR`'s retry loop.
**Results (x86_64, without SteamVR):**
- `--force-install-manifest` exits right away with `OPENVR_INIT_ERROR` (−2).
- `--graphics-api foo` exits right away with `GENERAL_FAILURE` (−1).
- The build tree contains the binary, `libopenvr_api.so`, both manifests,
`default_action_manifests/` and `res/`.
- Not tested yet: `Background` on the Frame (step 5).
+10 -8
View File
@@ -45,14 +45,8 @@ int main( int argc, char* argv[] )
commandLineArgs.forceRemoveManifest ); commandLineArgs.forceRemoveManifest );
} }
openvr_init::initializeOpenVR( // Render backend (render/RenderBackend.h). Chosen before connecting to
openvr_init::OpenVrInitializationType::Overlay ); // OpenVR, so a wrong --graphics-api fails right away.
// Render backend (render/RenderBackend.h). Created after OpenVR, because
// the Vulkan backend needs SteamVR's device requirements
// (openvr_init::renderInterop()), and before OverlayController, because
// QQuickWindow::setGraphicsApi() must run before any QQuickWindow exists
// (OverlayController owns one).
GraphicsApi graphicsApi = GraphicsApi::OpenGL; GraphicsApi graphicsApi = GraphicsApi::OpenGL;
if ( !parseGraphicsApi( commandLineArgs.graphicsApi, &graphicsApi ) ) if ( !parseGraphicsApi( commandLineArgs.graphicsApi, &graphicsApi ) )
{ {
@@ -68,6 +62,14 @@ int main( int argc, char* argv[] )
<< "is not compiled into this build"; << "is not compiled into this build";
return ReturnErrorCode::GENERAL_FAILURE; return ReturnErrorCode::GENERAL_FAILURE;
} }
openvr_init::initializeOpenVR(
openvr_init::OpenVrInitializationType::Overlay );
// Initialized after OpenVR, because the Vulkan backend needs SteamVR's
// device requirements (openvr_init::renderInterop()), and before
// OverlayController, because QQuickWindow::setGraphicsApi() must run
// before any QQuickWindow exists (OverlayController owns one).
QString renderBackendError; QString renderBackendError;
if ( !renderBackend->initialize( openvr_init::renderInterop(), if ( !renderBackend->initialize( openvr_init::renderInterop(),
&renderBackendError ) ) &renderBackendError ) )
+2
View File
@@ -4,6 +4,8 @@
"app_key": "steam.overlay.1009850", "app_key": "steam.overlay.1009850",
"launch_type": "binary", "launch_type": "binary",
"binary_path_windows": "AdvancedSettings.exe", "binary_path_windows": "AdvancedSettings.exe",
"binary_path_linux": "AdvancedSettings_app",
"binary_path_linux_arm": "AdvancedSettings_app",
"is_dashboard_overlay": true, "is_dashboard_overlay": true,
"strings": { "strings": {
+20 -2
View File
@@ -262,8 +262,26 @@ void forceRemoveApplicationManifest()
[[noreturn]] void handleManifests( const bool installManifest, [[noreturn]] void handleManifests( const bool installManifest,
const bool removeManifest ) const bool removeManifest )
{ {
openvr_init::initializeOpenVR( // Connect as Utility app first: it works without a running SteamVR (e.g.
openvr_init::OpenVrInitializationType::Utility ); // from the Windows installer). The Steam Frame's SteamVR refuses Utility
// apps (VRInitError_Init_NotAvailableToUtilityApps); there, connect as
// Background app, which needs a running SteamVR and never starts it.
// VR_Init is called directly: initializeOpenVR() retries every error with
// waits, including the one expected here.
vr::EVRInitError initError = vr::VRInitError_None;
vr::VR_Init( &initError, vr::VRApplication_Utility );
if ( initError == vr::VRInitError_Init_NotAvailableToUtilityApps )
{
qInfo() << "SteamVR refuses Utility apps, connecting as Background "
"app.";
vr::VR_Init( &initError, vr::VRApplication_Background );
}
if ( initError != vr::VRInitError_None )
{
qCritical() << "Failed to connect to SteamVR for manifest handling:"
<< vr::VR_GetVRInitErrorAsEnglishDescription( initError );
exit( ReturnErrorCode::OPENVR_INIT_ERROR );
}
int exit_code = ReturnErrorCode::SUCCESS; int exit_code = ReturnErrorCode::SUCCESS;
try try