Skip to main content

ADR 001: Use desktopCapturer Source ID Format for Screen Sharing

Status​

Implemented

Context​

When implementing screen sharing preview windows in Teams for Linux, we need to identify which screen or window the user selected for sharing. There are two potential identifiers available:

  1. desktopCapturer source ID: Format screen:x:y or window:x:y (e.g., screen:602:0)

    • Provided by Electron's desktopCapturer.getSources() API
    • Stable identifier for the selected screen/window
    • Required format for Wayland's xdg-desktop-portal
  2. MediaStream ID: UUID format (e.g., a1b2c3d4-5678-90ab-cdef-1234567890ab)

    • Generated when the MediaStream is created from the source
    • Changes on each new stream instance
    • Not recognized by Wayland's preview window APIs

The Problem​

On Wayland, the preview window creation fails with "Invalid State" error when passed a MediaStream UUID because:

  • Wayland's xdg-desktop-portal ScreenCast API expects the desktopCapturer source ID format
  • The portal uses this ID to identify which screen/window to capture
  • UUIDs are not valid portal source identifiers

On X11, the system is more permissive and accepts various formats, which masked this bug.

Technical Background​

Wayland Portal Requirements:

Electron API:

  • DesktopCapturer API returns source objects with id property in format screen:display_id:window_id
  • This id is the canonical identifier for desktop capture sources

Decision​

We will use the desktopCapturer source ID format (screen:x:y or window:x:y) throughout the screen sharing pipeline, not the MediaStream UUID.

Implementation​

  1. Source Selection (app/mainAppWindow/index.js):

    • Store the desktopCapturer source object from setupScreenSharing()
    • Set global.selectedScreenShareSource with the source ID in correct format
  2. Stream Creation (app/screenSharing/injectedScreenSharing.js):

    • Do NOT send stream.id (UUID) via IPC
    • Send null to preserve the source ID already stored in main process
  3. IPC Handler (app/index.js):

    • Validate received source IDs match format screen:x:y or window:x:y
    • Reject UUID format with warning
    • Only update global state if format is valid
  4. Preview Window (app/screenSharing/previewWindow.html):

    • Use the validated source ID from global state
    • Pass to getUserMedia() as chromeMediaSourceId

Consequences​

Positive​

  • ✅ Screen sharing preview works on Wayland
  • ✅ Consistent behavior across X11 and Wayland
  • ✅ Uses canonical Electron API identifiers
  • ✅ Future-proof against platform changes
  • ✅ Validation prevents regression to UUID format

Negative​

  • ⚠️ Requires coordination between main and renderer processes
  • ⚠️ The renderer process (injectedScreenSharing.js) doesn't have access to the desktopCapturer source ID, only the MediaStream

Alternatives Considered​

Alternative 1: Pass desktopCapturer source to renderer

  • ❌ Would require exposing more of Electron's APIs to renderer
  • ❌ Security concerns with broader API access
  • ❌ Violates separation of concerns

Alternative 2: Platform detection (use UUID on X11, source ID on Wayland)

  • ❌ Adds complexity
  • ❌ Inconsistent behavior across platforms
  • ❌ X11 lenience is not guaranteed to continue

Alternative 3: Store source ID in a different global variable

  • ❌ Adds state management complexity
  • ❌ Risk of desynchronization
  • ✅ Selected approach uses existing global.selectedScreenShareSource

Notes​

  • Bug reported in teams-for-linux Issue #1853
  • Fix implemented in v2.5.13
  • The StreamSelector module (app/screenSharing/index.js:73-74) already expected this format
  • Console logging with [SCREEN_SHARE_DIAG] prefix helps verify correct format

References​