diff --git a/docs/steamframe/PROGRESS.md b/docs/steamframe/PROGRESS.md index b2eb76b..10485c9 100644 --- a/docs/steamframe/PROGRESS.md +++ b/docs/steamframe/PROGRESS.md @@ -102,3 +102,23 @@ - `MyTextField` opens the SteamVR keyboard on `activeFocus`. The template had to send the 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). + +### 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). diff --git a/src/main.cpp b/src/main.cpp index 9ea3c12..95fe86f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,14 +45,8 @@ int main( int argc, char* argv[] ) commandLineArgs.forceRemoveManifest ); } - openvr_init::initializeOpenVR( - openvr_init::OpenVrInitializationType::Overlay ); - - // 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). + // Render backend (render/RenderBackend.h). Chosen before connecting to + // OpenVR, so a wrong --graphics-api fails right away. GraphicsApi graphicsApi = GraphicsApi::OpenGL; if ( !parseGraphicsApi( commandLineArgs.graphicsApi, &graphicsApi ) ) { @@ -68,6 +62,14 @@ int main( int argc, char* argv[] ) << "is not compiled into this build"; 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; if ( !renderBackend->initialize( openvr_init::renderInterop(), &renderBackendError ) ) diff --git a/src/package_files/manifest.vrmanifest b/src/package_files/manifest.vrmanifest index 2e6d50b..cf84525 100644 --- a/src/package_files/manifest.vrmanifest +++ b/src/package_files/manifest.vrmanifest @@ -4,6 +4,8 @@ "app_key": "steam.overlay.1009850", "launch_type": "binary", "binary_path_windows": "AdvancedSettings.exe", + "binary_path_linux": "AdvancedSettings_app", + "binary_path_linux_arm": "AdvancedSettings_app", "is_dashboard_overlay": true, "strings": { diff --git a/src/utils/setup.cpp b/src/utils/setup.cpp index d001db4..7a54960 100644 --- a/src/utils/setup.cpp +++ b/src/utils/setup.cpp @@ -262,8 +262,26 @@ void forceRemoveApplicationManifest() [[noreturn]] void handleManifests( const bool installManifest, const bool removeManifest ) { - openvr_init::initializeOpenVR( - openvr_init::OpenVrInitializationType::Utility ); + // Connect as Utility app first: it works without a running SteamVR (e.g. + // 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; try