diff --git a/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt b/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt index ef5133d9c..368858f3b 100644 --- a/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt +++ b/app/src/main/java/com/steamdeck/launcher/SessionActivity.kt @@ -226,9 +226,22 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { applyFrameGen() } - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {} + private var surfaceW = 0 + private var surfaceH = 0 + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + val resized = surfaceW != 0 && (width != surfaceW || height != surfaceH) + surfaceW = width + surfaceH = height + if (resized) { + Log.i(TAG, "surface resized to ${width}x$height — rebinding the compositor") + CompositorHost.resize(holder.surface) + } + } override fun surfaceDestroyed(holder: SurfaceHolder) { + surfaceW = 0 + surfaceH = 0 CompositorHost.detach() } 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 fa311957c..95fbae473 100644 --- a/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt +++ b/app/src/main/java/com/steamdeck/launcher/wayland/CompositorHost.kt @@ -48,6 +48,20 @@ object CompositorHost { return true } + /** + * The Surface changed size under the compositor (a foldable opening or closing). Android does + * not always recreate the Surface for that, and a swapchain built for the old size keeps + * presenting: the system then scales those buffers onto the new window, which on a Fold showed + * a 16:9 picture stretched to the square panel. Rebinding the window rebuilds the swapchain at + * the new size, and the scale mode letterboxes as it should. + */ + @Synchronized + fun resize(surface: Surface) { + if (!started) return + WaylandCompositor.nativeSetSurface(null) + WaylandCompositor.nativeSetSurface(surface) + } + /** * 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.