feat(apple): client-selectable compositor in the macOS client
ci / rust (push) Has been cancelled

Adopts punktfunk_connect_ex from the compositor-selection batch: a Compositor enum on
PunktfunkConnection (auto/kwin/wlroots/mutter/gamescope, with the host's name aliases
for env parsing), a "Host compositor" picker in Settings (default Automatic — a
concrete choice is honored only if that backend is available host-side), and
PUNKTFUNK_COMPOSITOR / PUNKTFUNK_REMOTE_COMPOSITOR pass-throughs for the autoconnect
dev hook and the remote first-light test. The wire change is backward-compatible
(optional trailing byte), so no behavior changes at the default.

Validated live against the box: host with no compositor env (auto-detect = KWin)
logged "honoring client compositor request compositor=gamescope" and streamed 60/60
decoded frames from the spawned gamescope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 22:51:42 +02:00
parent 6fdf7d1511
commit a9d1c16067
6 changed files with 82 additions and 11 deletions
@@ -1,13 +1,16 @@
// App settings (,): the stream mode. The host creates a native virtual output at
// exactly this size/refresh there is no scaling anywhere in the pipeline.
// App settings (,): the stream mode + the host compositor. The host creates a native
// virtual output at exactly this size/refresh there is no scaling anywhere in the
// pipeline.
import AppKit
import PunktfunkKit
import SwiftUI
struct SettingsView: View {
@AppStorage("punktfunk.width") private var width = 1920
@AppStorage("punktfunk.height") private var height = 1080
@AppStorage("punktfunk.hz") private var hz = 60
@AppStorage("punktfunk.compositor") private var compositor = 0
var body: some View {
Form {
@@ -30,6 +33,23 @@ struct SettingsView: View {
.font(.caption)
.foregroundStyle(.secondary)
}
Section {
Picker("Compositor", selection: $compositor) {
Text("Automatic").tag(0)
Text("KWin (KDE Plasma)").tag(1)
Text("wlroots (Sway / Hyprland)").tag(2)
Text("Mutter (GNOME)").tag(3)
Text("gamescope").tag(4)
}
} header: {
Text("Host compositor")
} footer: {
Text("Which compositor drives the virtual output on the host. A specific "
+ "choice is honored only if that backend is available there — "
+ "otherwise the host falls back to auto-detection.")
.font(.caption)
.foregroundStyle(.secondary)
}
}
.formStyle(.grouped)
.frame(width: 380)