feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(macOS): libdispalydevice integration - #5338

Merged
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice
Jul 4, 2026
Merged

feat(macOS): libdispalydevice integration#5338
ReenigneArcher merged 5 commits into
LizardByte:masterfrom
martona:integrate-macos-libdisplaydevice

Conversation

@martona

Copy link
Copy Markdown
Contributor

Description

This is a follow-up from last week's libdisplaydevice work: macOS integration in Sunshine.

macOS now uses libdisplaydevice for display enumeration as well as applying/reverting changes.

I also removed the patch that kept the display awake; Sunshine now relies on the new libdisplaydevice functionality to do the same. Note that while libdisplaydevice gained the ability to wake displays on Windows, this PR does not take advantage of it; the scope was kept to macOS.

I had to bump the libdisplaydevice submodule.

Screenshot

Issues Fixed or Closed

Roadmap Issues

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
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@ReenigneArcher

ReenigneArcher commented Jun 26, 2026

Copy link
Copy Markdown
Member

Apologies, but I merged a change a little while ago that causes conflicts with this one.

@martona
martonaforce-pushed the integrate-macos-libdisplaydevice branch from ede0ab1 to b733db8CompareJune 26, 2026 03:39
@martona

Copy link
Copy Markdown
ContributorAuthor

No worries, should merge cleanly now.

Comment threadsrc/display_device.cpp Outdated
Comment threadsrc/display_device.cpp
@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6c46fdc to 5700431CompareJune 27, 2026 00:04
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

#endif
}

std::unique_ptr<DisplayPowerInterface> make_display_power() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this added for Windows as well?

https://github.com/LizardByte/libdisplaydevice/blob/65616076ba881046085438c80fddead9beedf74f/src/windows/display_power.cpp#L43

Also, found this which should maybe replaced with the new library code?

// Keep the display awake during capture. If the display goes to sleep during
// capture, best case is that capture stops until it powers back on. However,
// worst case it will trigger us to reinit DD, waking the display back up in
// a neverending cycle of waking and sleeping the display of an idle machine.
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
auto clear_display_required = util::fail_guard([]() {
SetThreadExecutionState(ES_CONTINUOUS);
});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's what I meant in part when I said I could make a power management pass after the interface-factories. Technically it could have been a part of this PR, but I did not want it out of control, touching multiple OSes. A note regarding it is also in the body text of the PR: it's definitely not forgotten about, it just felt out of scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I have a reading problem today. Thanks for the clarification!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just throw a couple TODO comments in? (Sonar will complain about the TODOs, but I'll bypass it)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do!

@codecov

codecovBot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.53846% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.23%. Comparing base (33aaefa) to head (7c52ebc).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/display_device.cpp46.75%38 Missing and 3 partials ⚠️
src/platform/macos/display.mm60.00%20 Missing ⚠️
src/platform/macos/av_video.m33.33%2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## master #5338 +/- ##
==========================================
- Coverage 27.44% 27.23% -0.22% 
==========================================
Files 113 113 Lines 25547 25451 -96 Branches 11244 11218 -26 ==========================================
- Hits 7012 6932 -80 + Misses 15474 15410 -64 - Partials 3061 3109 +48 
FlagCoverage Δ
Archlinux0.00% <0.00%> (ø)
FreeBSD-aarch64?
FreeBSD-amd6413.19% <2.63%> (-0.06%)⬇️
Homebrew-macos-1420.44% <26.01%> (-0.58%)⬇️
Homebrew-macos-1520.61% <26.01%> (-0.57%)⬇️
Homebrew-macos-2620.73% <26.01%> (-0.55%)⬇️
Homebrew-ubuntu-24.0412.98% <4.54%> (-0.03%)⬇️
Linux-AppImage12.31% <4.54%> (-0.03%)⬇️
Windows-AMD6415.22% <4.65%> (-0.04%)⬇️
Windows-ARM6413.29% <2.70%> (-0.04%)⬇️
macOS-arm6418.89% <19.23%> (-0.39%)⬇️
macOS-x86_6418.39% <18.44%> (-0.36%)⬇️

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

Files with missing linesCoverage Δ
src/platform/macos/av_video.m92.59% <33.33%> (-1.41%)⬇️
src/platform/macos/display.mm61.30% <60.00%> (-5.36%)⬇️
src/display_device.cpp67.08% <46.75%> (-0.96%)⬇️

... and 56 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 33aaefa...7c52ebc. Read the comment docs.

@martona

Copy link
Copy Markdown
ContributorAuthor

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

@ReenigneArcher

ReenigneArcher commented Jun 27, 2026

Copy link
Copy Markdown
Member

Everything going red is on libdisplaydevice. EnumeratedDevice is an aggregate and does not define a constructor, so calls like:

devices.emplace_back(device_id, display_name, friendly_name, edid, info);

rely on C++20 parenthesized aggregate initialization through std::construct_at. Newer toolchains accept that, which is why it built for me locally, but the Xcode 15.4 CI toolchain rejects it here.

The cleanest fix is to go back to libdisplaydevice and undo the SONAR fix that caused this by changing the affected EnumeratedDevice insertions back to explicit braced aggregate construction, e.g. push_back(EnumeratedDevice { ... }). I'll submit a PR for that, then update the Sunshine submodule pin.

Before I do that though... does this sound like the best course of action to you too?

That sounds fine, maybe we should add an older macOS runner to the libdisplaydevice build/test matrix as well.

I think there's a few other things going on as well.

  1. Unused function on Linux... you can apply [[maybe_unused]]?
[34](https://github.com/LizardByte/Sunshine/actions/runs/28272130054/job/83772706710?pr=5338#step:6:2835)
Error: /home/runner/work/Sunshine/Sunshine/src/display_device.cpp:144:10: error: ‘bool display_device::{anonymous}::is_unsigned_integer(std::string_view)’ defined but not used [-Werror=unused-function]
144 | bool is_unsigned_integer(std::string_view value) {
| ^~~~~~~~~~~~~~~~~~~
  1. Two tests failing on macos-latest runners:
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <01-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/2 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/2, where GetParam() = ((4-byte object <01-00 00-00>, true), (4-byte object <01-00 00-00>)) (0 ms)
[ RUN ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3
/Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122: Failure
Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: From /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:110
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 started
[2026-06-27 01:07:15.242]: Info: Ignoring HDR display device request on macOS because macOS HDR changes are not supported by libdisplaydevice.
[2026-06-27 01:07:15.242]: Tests: At /Users/runner/work/Sunshine/Sunshine/tests/unit/test_display_device.cpp:122
[2026-06-27 01:07:15.242]: Tests: Non-fatal failure: Expected equality of these values:
std::get<display_device::SingleDisplayConfiguration>(result).m_hdr_state
Which is: (nullopt)
expected_value
Which is: (4-byte object <00-00 00-00>)
[2026-06-27 01:07:15.242]: Tests: DisplayDeviceConfigTest/ParseHdrOption/IntegrationTest/3 failed
[ FAILED ] DisplayDeviceConfigTest/ParseHdrOption.IntegrationTest/3, where GetParam() = ((4-byte object <01-00 00-00>, false), (4-byte object <00-00 00-00>)) (0 ms)

I didn't check every failure though, this was only a spot check.

@martona

Copy link
Copy Markdown
ContributorAuthor

There seem to be three failure cases. Everything else appears to be noise stemming from these:

  • mac_display_device_general.cpp (line 60) / win_display_device_general.cpp (line 72): the EnumeratedDeviceemplace_back(...) issue: revert to push_back instead; add SONAR override if it complains.
  • The unused helper in display_device.cpp (line 144): put it beind an #ifdef __APPLE__ guard.
  • macOS HDR test mismatch: fix the test expectation

I'll work on the libdisplaydevice-side fix and send a PR for it. Then we can bump the libdisplaydevice pin on this PR which should clear the errors.

@martona

Copy link
Copy Markdown
ContributorAuthor

Apologies for the delay, life got in the way. With the libdisplaydevice-changes integrated and the two Sunshine-side fixes, this should now build cleanly in CI.

@ReenigneArcher
ReenigneArcherforce-pushed the integrate-macos-libdisplaydevice branch from 6859972 to 7c52ebcCompareJuly 3, 2026 23:41
@ReenigneArcher
ReenigneArcher merged commit fbafc49 into LizardByte:masterJul 4, 2026
69 checks passed
@martona
martona deleted the integrate-macos-libdisplaydevice branch July 4, 2026 02:45
Sign up for freeto 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.

2 participants

@martona@ReenigneArcher