# How Fluxer Display Media Capture Works: Source Caching and Cross-Platform Handling

> Discover how Fluxer display media capture works with per-request and global source caching. Learn about its cross-platform handling for Windows macOS and Linux.

- Repository: [Fluxer/fluxer](https://github.com/fluxerapp/fluxer)
- Tags: internals
- Published: 2026-03-17

---

**Fluxer implements display media capture through a coordinated Electron main-renderer architecture that uses per-request caching, a global 60-second source cache, and platform-specific fallbacks to handle screen sharing across Windows, macOS, and Linux.**

Fluxer's screen sharing system is built into its desktop Electron process and manages `navigator.mediaDevices.getDisplayMedia` requests through a custom IPC pipeline. According to the fluxerapp/fluxer source code, the implementation balances performance optimization through source caching with strict cross-platform compatibility requirements, particularly for Linux portal environments.

## Architecture Overview

The display media capture system operates across three coordinated components: the Electron main process handler, the source caching layer, and the renderer-side picker interface.

### Main Process Handler in Window.tsx

In [`src/main/Window.tsx`](https://github.com/fluxerapp/fluxer/blob/main/src/main/Window.tsx), Fluxer registers a display-media request handler on each Electron `Session` via `setupDisplayMediaHandler`. When a renderer invokes `getDisplayMedia`, the handler generates a unique **requestId** using the format `display-media-${++displayMediaRequestCounter}` and forwards the request to the renderer via IPC (`webContents.send('display-media-requested', …)`).

The handler stores the resolution callback in a `pendingDisplayMediaRequests` map and initiates a **60-second timeout** that auto-rejects the request if the UI remains unresponsive. This prevents dangling promises from orphaned picker windows.

### Renderer Coordination via Preload Scripts

The preload script at [`src/preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/src/preload/index.tsx) exposes three critical IPC helpers to the web context:
- `onDisplayMediaRequested`: Listens for main-process display-media events
- `selectDisplayMediaSource`: Transmits the user's source selection back to the main process
- `getDesktopSources`: Retrieves cached source lists or triggers fresh captures

## Request Lifecycle and Timeout Management

Fluxer implements strict request lifecycle management to prevent memory leaks and zombie picker states.

When the main process receives a `getDisplayMedia` call, it:
1. Generates a unique request identifier
2. Stores the pending callback with a 60-second timeout timer
3. Awaits the `select-display-media-source` IPC message from the renderer

If the user selects a source, the main process resolves the pending request, clears the timeout, and invokes the callback with an `Electron.Streams` object. If the timeout expires or the user cancels, the callback receives `null` to reject the promise.

## Source Caching Strategy

Fluxer employs a dual-layer caching system to minimize redundant calls to `desktopCapturer.getSources` while avoiding stale data on dynamic desktop environments.

### Global Cache with TTL

When the renderer requests desktop sources via `get-desktop-sources`, the main process calls `desktopCapturer.getSources` and caches the result in `latestDesktopSources` alongside a `latestDesktopSourcesTimestamp`. This global cache remains valid for **60 seconds** (controlled by `DESKTOP_SOURCE_CACHE_TTL_MS`).

### Per-Request Cache Attachment

The request handler can attach the cached source list to individual pending requests. When a `display-media-requested` event fires, the handler checks for cached sources and attaches them to `pending.cachedSources` if available. During source selection, the code prefers the per-request cache, falling back to the global cache if fresh.

## Cross-Platform Handling and Limitations

Fluxer adapts its caching behavior based on the operating system to accommodate platform-specific constraints in screen capture permissions and portal implementations.

### Windows (win32)

On Windows, Fluxer fully utilizes both the per-request and global caches within the 60-second TTL. The platform supports **loopback audio** capture by setting `streams.audio = 'loopback'` in the returned stream configuration.

### macOS (darwin)

macOS follows the same caching logic as Windows but adds a native permission check. Before displaying the picker UI, Fluxer verifies that the application holds **screen recording permission** using system APIs. Unlike Windows, macOS does not support loopback audio through this mechanism, though system audio can be added through secondary means.

### Linux (linux) Portal Limitations

Linux requires special handling due to XDG Desktop Portal behavior. The source code explicitly excludes Linux from global cache reuse for new requests to prevent duplicate portal picker windows from appearing.

If a display media request arrives and the global cache has expired, the main process immediately cancels the pending request by calling `pending.callback(null)` and forces the UI to re-initiate a fresh picker workflow. This ensures users never encounter conflicting permission dialogs. Linux also lacks built-in loopback audio support in this implementation.

## Renderer-Side Picker Implementation

The React hook [`useElectronScreenSharePicker.tsx`](https://github.com/fluxerapp/fluxer/blob/main/useElectronScreenSharePicker.tsx) in the renderer process orchestrates the user-facing picker flow:

1. Registers the `onDisplayMediaRequested` listener
2. Validates that video is requested (rejects audio-only calls)
3. On macOS, verifies native screen-recording permissions
4. Fetches sources via `electronApi.getDesktopSources`
5. **Automatic selection**: If only one source exists, it selects immediately without showing a modal
6. **Manual selection**: If multiple sources exist, opens `ScreenShareSourceModal` for user choice
7. Transmits the selection via `selectDisplayMediaSource` or cancels on timeout

## Summary

- Fluxer intercepts `getDisplayMedia` calls in the Electron main process using `setupDisplayMediaHandler` in [`Window.tsx`](https://github.com/fluxerapp/fluxer/blob/main/Window.tsx), assigning unique request IDs and 60-second timeouts.
- The system maintains a **global 60-second source cache** and **per-request cached source lists** to optimize performance, stored in `latestDesktopSources`.
- **Windows** supports full caching and loopback audio; **macOS** adds native permission verification but lacks loopback support.
- **Linux** never reuses stale caches for new requests to avoid duplicate portal windows, cancelling requests immediately if the cache misses.
- The renderer-side React hook handles automatic single-source selection and modal-based multi-source picking through IPC exposed in [`preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/preload/index.tsx).

## Frequently Asked Questions

### How does Fluxer prevent duplicate permission dialogs on Linux?

Fluxer explicitly disables cache reuse for display media requests on Linux. If the global source cache has expired when a new request arrives, the main process immediately cancels the pending callback with `null` and forces the UI to re-initiate a fresh capture workflow. This prevents the XDG Desktop Portal from spawning multiple concurrent picker windows.

### What happens if the user doesn't select a source within 60 seconds?

The main process starts a 60-second timeout timer when a display media request enters the `pendingDisplayMediaRequests` map. If the timeout expires before the renderer sends a `select-display-media-source` message, the stored callback is invoked with `null`, rejecting the `getDisplayMedia` promise and cleaning up the pending request entry.

### Does Fluxer support system audio capture during screen sharing?

Audio support varies by platform. **Windows** supports loopback audio via `streams.audio = 'loopback'`. **macOS** does not support loopback audio through this mechanism but can capture system audio through additional configuration. **Linux** has no built-in loopback audio support in the current implementation.

### How does Fluxer handle single-source vs. multi-source scenarios?

In [`useElectronScreenSharePicker.tsx`](https://github.com/fluxerapp/fluxer/blob/main/useElectronScreenSharePicker.tsx), the renderer checks the length of the cached source list returned by `getDesktopSources`. If exactly one source exists, it automatically selects that source and sends the selection to the main process without displaying a modal. If multiple sources exist, it renders the `ScreenShareSourceModal` component to let the user choose between available displays and windows.