Gamescope: the container CPU list (Advanced tab) reaches the game

Merged
UT
6d ago
+243-2

Description

A user reported that the CPU pinning only works on the X11 server, not under gamescope. For the container "Processor affinity" list on the Advanced tab that is true: the list is sent to a process by Win32AppWorkarounds.applyWindowWorkarounds when the in-app X server maps its first top-level window. Under gamescope the windows map on Xwayland, so that listener never fires and the list is silently ignored. Worse, an explicit list makes PowerManager.ownsGameAffinity false, so on RP6 / Odin 3 power control left the game alone as well and the game ran with no pin at all.

Fix (app only, no shim or payload change):

  • WinHandler gains addProcessInfoObserver / removeProcessInfoObserver, so a second receiver of the LIST_PROCESSES reply can coexist with the exit-watch listener the UI swaps in.
  • New ContainerAffinity, armed in the gamescope branch after PowerManager.autoStart and disarmed in exit(). It listens once for GamescopeGameContent (the daemon's "60 published frames" event that already stands in for the X11 window map in MainViewModel), then takes one process list from the winhandler and sends the container mask to each process by pid. No polling, one round trip per session. The winhandler reports whether a process is WoW64, so the 32-bit list applies the same way as on X11, with no PE parsing. Same exclusions as the X11 path (steam.exe, and the game when power control owns its affinity), plus the processes power control's background pin manages (winhandler.exe, services.exe) and Wine's own service processes (start.exe, wineboot, winedevice, plugplay, svchost, rpcss, conhost), which map no window on X11 and never got the list there either. Windowed helpers (explorer.exe, tabtip.exe, crash handlers) still get it, as on X11.
  • Power control's own game pin and compositor placement already ran under gamescope and are unchanged.

Unit test ContainerAffinityTest covers the mask selection rules.

Recording

Device verification to follow in a comment.

Type of Change

  • Bug fix

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by CodeRabbit

  • New Features
    • Gamescope sessions now apply configured CPU affinity to eligible processes, using the appropriate settings for standard and WoW64 processes.
    • Affinity is applied when game content starts, or immediately if it has already started.
    • Processes excluded by existing power-control settings remain unaffected.