diff --git a/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt b/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt index 7679b8aa4..d599a3ffd 100644 --- a/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt +++ b/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt @@ -361,7 +361,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { override fun surfaceDestroyed(holder: SurfaceHolder) { surfaceW = 0 surfaceH = 0 - CompositorHost.detach() + CompositorHost.detach(holder.surface) } /** diff --git a/app/src/main/java/com/steamdeck/launcher/session/SessionService.kt b/app/src/main/java/com/steamdeck/launcher/session/SessionService.kt index bda8e5740..aac6af793 100644 --- a/app/src/main/java/com/steamdeck/launcher/session/SessionService.kt +++ b/app/src/main/java/com/steamdeck/launcher/session/SessionService.kt @@ -292,6 +292,8 @@ class SessionService : Service() { } // Where the guest leaves a request for another session (the desktop's Steam launchers). guest.add("BL_LAUNCH_DIR=" + sessionRoot.path) + // The second library's name, for bannerlator-steam-library; the bind itself is made below. + GameStorage.effective(this)?.let { guest.add("BL_LIBRARY_LABEL=" + it.label.replace('"', ' ')) } if (SessionState.mode == MODE_STEAM && SessionState.steamUi == "desktop") guest.add("BL_STEAM_UI=desktop") guest.add(LinuxRuntime.SESSION_SCRIPT) guest.add(SessionState.mode) @@ -339,7 +341,6 @@ class SessionService : Service() { if (problem == null) { File(LinuxRuntime.rootDir(this), "mnt/bannerlator-sd").mkdirs() binds.add("${library.path}:/mnt/bannerlator-sd") - guest.add("BL_LIBRARY_LABEL=" + library.label.replace('"', ' ')) Log.i(TAG, "game storage: ${library.path} -> /mnt/bannerlator-sd (\"${library.label}\")") } else { Log.w(TAG, "game storage: $problem; internal only this session") diff --git a/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt b/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt index 4cc47698c..b68f291fe 100644 --- a/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt +++ b/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt @@ -34,6 +34,7 @@ object CompositorHost { refreshHz: Float, ): Boolean { if (started) { + attached = surface WaylandCompositor.nativeSetSurface(surface) resumeVsync() return false @@ -43,6 +44,7 @@ object CompositorHost { WaylandCompositor.nativeStartWithSurface( surface, xdgRuntimeDir, driverPath, libraryName, nativeLibDir, ) + attached = surface started = true resumeVsync() return true @@ -66,6 +68,7 @@ object CompositorHost { WaylandCompositor.nativeSetFrameGenArmed(false, 0) WaylandCompositor.nativeLog("screen", "surface resized: rebinding the window, frame generation re-armed after") WaylandCompositor.nativeSetSurface(null) + attached = surface WaylandCompositor.nativeSetSurface(surface) android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(rearm, 600) } @@ -87,9 +90,20 @@ object CompositorHost { * The activity is going away. The compositor keeps running with nothing to present into — * the guest carries on, and its next frames land on the Surface the next activity brings. */ + /** The Surface the compositor presents on; only its own owner may take it away. */ + private var attached: Surface? = null + + /** + * Only for the Surface that is attached. When one session hands over to the next (the + * desktop's Steam launchers), the new activity attaches its Surface before the old one is + * destroyed - and the old one's surfaceDestroyed then arrived here and took the new Surface + * away: gamescope's frames came in by the thousand and nothing reached the screen. + */ @Synchronized - fun detach() { + fun detach(surface: Surface?) { if (!started) return + if (surface != null && attached != null && attached !== surface) return + attached = null pauseVsync() WaylandCompositor.nativeSetSurface(null) }