Skip to content

fix(linux): preserve PipeWire startup history for portal recovery - #6102

Draft
ReenigneArcher wants to merge 1 commit into
SunshineStream:masterfrom
ReenigneArcher:codex/fix-pipewire-started-state
Draft

ReenigneArcher wants to merge 1 commit into
SunshineStream:masterfrom
ReenigneArcher:codex/fix-pipewire-started-state

Conversation

@ReenigneArcher

@ReenigneArcher ReenigneArcher commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

Description

After an established portal stream transitions streaming -> paused -> error, checking only the previous state mistakes it for a stream that never started. Depending on when the capture thread handles the pause, this permanently disables maxFramerate negotiation for subsequent streams until Sunshine restarts.

Track an atomic has_streamed flag for each PipeWire connection and use it to restrict the existing fallback to streams that have never reached streaming. Reset the flag for a new connection, and retain it across pauses, errors, and disconnects. The tests exercise the real PipeWire callback and portal handler without a compositor or portal session.

Screenshot

Issues Fixed or Closed

Prevents the display-disconnect sequence in the failure log from permanently disabling maxFramerate negotiation. The same state-handling defect also exists in stable v2026.914.233613. Reporter testing has been requested to verify recovery on the affected KDE/NVIDIA setup.

Roadmap Issues

Testing

  • Added five regression tests covering startup history, both pause/error handling orders, the never-started fallback and its already-disabled case, and reset on a new connection. All nine PipeWire lifecycle tests passed.
  • In an isolated build, restoring the original previous_state condition makes PortalRetainsMaxFramerateAfterAnEstablishedStreamFails fail; the never-started fallback test still passes. Both pass with the fix.
  • Fedora 43 aarch64 / GCC 15.3.1: CMake configuration and native sunshine and test_sunshine builds passed with BUILD_WERROR=ON, portal, KWin, Wayland, VA-API, DRM and Vulkan enabled; CUDA and tray disabled.
  • Runnable native suite: 925 tests, 922 passed and 3 skipped. The unfiltered run had no individual test failures, but three suites (Configurations/AudioTest, MouseInputs/MouseHIDTest, EncoderVariants/EncoderTest) failed platform setup because the container has no graphical capture session; those 11 tests were excluded from the runnable pass. The remaining skips cover Windows-only support, an unavailable scoped network interface, and disabled tray support.
  • GCC coverage: all 21 changed executable source lines covered, including the test-only portal adapter (6/6 production lines).
  • uv sync --locked, uv run --locked lb-update-clang-format, and git diff --check: passed. No unrelated formatting changes.
  • Strict Dockle/Doxygen documentation build: passed (1,164 HTML pages).
  • Live streaming and monitor power-state recovery on the reporter's setup were not tested. Hosted CI is pending.

Type of Change

  • feat: New feature (non-breaking change which adds functionality)
  • fix: Bug fix (non-breaking change which fixes an issue)
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semicolons, etc.)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit
  • BREAKING CHANGE: Introduces a breaking change (can be combined with any type above)

Checklist

  • Code follows the style guidelines of this project
  • Code has been self-reviewed
  • Code has been commented, particularly in hard-to-understand areas
  • Code docstring/documentation-blocks for new or existing methods/components have been added or updated
  • Tests have been added or updated for new or modified functionality, including regression tests for bug fixes

AI Usage

See our AI usage policy.

  • AI tools were used while preparing this PR

This pull request was generated by Codex, GPT-6, high thinking level.

Copy link
Copy Markdown
Member Author

This pull request was generated by Codex, GPT-6, high thinking level.

@codecov

codecov Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 50.98%. Comparing base (02246e6) to head (46f0a38).
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6102      +/-   ##
==========================================
+ Coverage   50.80%   50.98%   +0.17%     
==========================================
  Files         148      148              
  Lines       32413    32446      +33     
  Branches    13701    13711      +10     
==========================================
+ Hits        16469    16544      +75     
- Misses      12362    14227    +1865     
+ Partials     3582     1675    -1907     
Flag Coverage Δ
Alpine-aarch64 34.42% <95.23%> (+0.27%) ⬆️
Alpine-x86_64 34.55% <95.23%> (+0.27%) ⬆️
Archlinux 35.16% <90.47%> (+0.28%) ⬆️
FreeBSD-amd64 35.09% <86.95%> (+0.27%) ⬆️
Homebrew-macos-15 48.81% <ø> (ø)
Homebrew-macos-26 49.18% <ø> (ø)
Homebrew-ubuntu-24.04 37.55% <76.19%> (+0.14%) ⬆️
Linux-AppImage-aarch64 40.28% <95.23%> (+0.25%) ⬆️
Linux-AppImage-x86_64 40.53% <95.23%> (+0.26%) ⬆️
PowerShell 100.00% <ø> (ø)
Web-UI 57.74% <ø> (ø)
Windows-AMD64 41.35% <ø> (ø)
Windows-ARM64 35.29% <ø> (ø)
macOS-arm64 41.70% <ø> (ø)
macOS-x86_64 40.59% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/platform/linux/pipewire.cpp 16.23% <100.00%> (+5.60%) ⬆️
src/platform/linux/portalgrab.cpp 52.92% <100.00%> (+3.69%) ⬆️

... and 48 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 02246e6...46f0a38. Read the comment docs.

@github-actions

Copy link
Copy Markdown
Last Updated 2026-11-14 18:14:24 UTC
Source Run CI Run #6766
Commit 46f0a38b0d3036106e18e36c97a41e15136033b6

Screenshot Comparison

PR #6102 screenshots vs screenshots baseline.

Matrix: AppImage-aarch64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: AppImage-x86_64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: Windows-AMD64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: Windows-ARM64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: macOS-arm64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: macOS-x86_64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XDG portal: after a display briefly disappears, capture never recovers ("no more input formats" loop) in 2026.1113.231225; 2026.914 recovers

1 participant