You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(linux): preserve PipeWire startup history for portal recovery - #6102
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.
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
✅ 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 disablesmaxFrameratenegotiation for subsequent streams until Sunshine restarts.Track an atomic
has_streamedflag for each PipeWire connection and use it to restrict the existing fallback to streams that have never reachedstreaming. 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
maxFrameratenegotiation. 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
previous_statecondition makesPortalRetainsMaxFramerateAfterAnEstablishedStreamFailsfail; the never-started fallback test still passes. Both pass with the fix.sunshineandtest_sunshinebuilds passed withBUILD_WERROR=ON, portal, KWin, Wayland, VA-API, DRM and Vulkan enabled; CUDA and tray disabled.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.uv sync --locked,uv run --locked lb-update-clang-format, andgit diff --check: passed. No unrelated formatting changes.Type of Change
Checklist
AI Usage
See our AI usage policy.