Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0b368b4
third-party: Add stubs for EGL DMA-BUF query APIs
garnacho May 4, 2024
655e86d
feat(linux): Support streaming through XDG portals and Pipewire
garnacho May 5, 2024
6f79ca5
style: fix lint errors
ReenigneArcher Nov 12, 2025
a31a931
Update XDG portal dependencies and error message
ReenigneArcher Nov 12, 2025
5ed7c50
Add Pipewire as a dependency for Linux builds
ReenigneArcher Nov 13, 2025
0e63675
fix(portalgrab): change PERSIST_WHILE_RUNNING to 2
ReenigneArcher Dec 6, 2025
a617c25
feat(linux/portal): improve XDG portal capture for KDE and dual GPU s…
Traine9 Jan 20, 2026
703347c
fix(xdg)!: remove default setcap on sunshine binaries
ReenigneArcher Jan 22, 2026
2e83d2f
refactor: move xdg portal capture after x11
ReenigneArcher Jan 23, 2026
e4481bc
Fix install path for sunshine-kms binary
ReenigneArcher Jan 23, 2026
1d432e5
style: fix several sonar warnings
ReenigneArcher Jan 23, 2026
cf9cc3d
Refactor to use std::array for buffer and struct storage
ReenigneArcher Jan 23, 2026
6ed15e6
Refactor array usage and variable declarations in portalgrab.cpp
ReenigneArcher Jan 23, 2026
e302bc0
Replace g_strdup_printf with std::format for path generation
ReenigneArcher Jan 23, 2026
cff079a
Refactor portalgrab.cpp for code clarity
ReenigneArcher Jan 23, 2026
b098814
Refactor parameter assignment and improve type usage
ReenigneArcher Jan 23, 2026
346d28c
Refactor portalgrab.cpp for const correctness and C++ casts
ReenigneArcher Jan 23, 2026
857091a
Enable SUNSHINE_ENABLE_PORTAL in build configurations
ReenigneArcher Jan 23, 2026
3ce55cc
fix(linux): Split service unit into privileged and unprivileged varia…
psyke83 Jan 24, 2026
97fa599
fix(linux/xdgportal): sync capture delay logic/logging with x11/kms (…
psyke83 Jan 24, 2026
8414c6b
fix(linux/xdgportal): set variable rate capture (#4624)
psyke83 Jan 25, 2026
eb063e1
fix(linux): install vendor preset for sunshine-kms service (#4626)
psyke83 Jan 26, 2026
da6a8e5
Format mark_as_advanced call for readability
ReenigneArcher Jan 27, 2026
cb67b3e
fix(linux/kmsgrab): deprioritize setcap error message for non-KMS Way…
psyke83 Jan 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci-freebsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jobs:
graphics/wayland \
lang/python312 \
multimedia/libva \
multimedia/pipewire \
net/miniupnpc \
ports-mgmt/pkg \
security/openssl \
Expand Down Expand Up @@ -167,6 +168,7 @@ jobs:
-DSUNSHINE_EXECUTABLE_PATH=/usr/local/bin/sunshine \
-DSUNSHINE_ENABLE_CUDA=OFF \
-DSUNSHINE_ENABLE_DRM=OFF \
-DSUNSHINE_ENABLE_PORTAL=ON \
-DSUNSHINE_ENABLE_WAYLAND=ON \
-DSUNSHINE_ENABLE_X11=ON \
-DSUNSHINE_PUBLISHER_NAME="${GITHUB_REPOSITORY_OWNER}" \
Expand Down
12 changes: 11 additions & 1 deletion cmake/FindSystemd.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ IF (NOT WIN32)
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SYSTEMD_USER_UNIT_INSTALL_DIR)

execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE}
--variable=systemd_user_preset_dir systemd
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SYSTEMD_USER_PRESET_INSTALL_DIR)

execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE}
--variable=systemd_system_unit_dir systemd
OUTPUT_STRIP_TRAILING_WHITESPACE
Expand All @@ -29,7 +34,12 @@ IF (NOT WIN32)
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SYSTEMD_MODULES_LOAD_DIR)

mark_as_advanced(SYSTEMD_USER_UNIT_INSTALL_DIR SYSTEMD_SYSTEM_UNIT_INSTALL_DIR SYSTEMD_MODULES_LOAD_DIR)
mark_as_advanced(
SYSTEMD_USER_UNIT_INSTALL_DIR
SYSTEMD_USER_PRESET_INSTALL_DIR
SYSTEMD_SYSTEM_UNIT_INSTALL_DIR
SYSTEMD_MODULES_LOAD_DIR
)

endif ()

Expand Down
19 changes: 18 additions & 1 deletion cmake/compile_definitions/linux.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,29 @@ if(X11_FOUND)
"${CMAKE_SOURCE_DIR}/src/platform/linux/x11grab.cpp")
endif()

# XDG portal
if(${SUNSHINE_ENABLE_PORTAL})
pkg_check_modules(GIO gio-2.0 gio-unix-2.0 REQUIRED)
pkg_check_modules(PIPEWIRE libpipewire-0.3 REQUIRED)
else()
set(GIO_FOUND OFF)
set(PIPEWIRE_FOUND OFF)
endif()
if(PIPEWIRE_FOUND)
add_compile_definitions(SUNSHINE_BUILD_PORTAL)
include_directories(SYSTEM ${GIO_INCLUDE_DIRS} ${PIPEWIRE_INCLUDE_DIRS})
list(APPEND PLATFORM_LIBRARIES ${GIO_LIBRARIES} ${PIPEWIRE_LIBRARIES})
list(APPEND PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/linux/portalgrab.cpp")
endif()

if(NOT ${CUDA_FOUND}
AND NOT ${WAYLAND_FOUND}
AND NOT ${X11_FOUND}
AND NOT ${PIPEWIRE_FOUND}
AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
AND NOT ${LIBVA_FOUND})
message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, (libdrm and libcap), or libva")
message(FATAL_ERROR "Couldn't find either cuda, libva, pipewire, wayland, x11, or (libdrm and libcap)")
endif()

# tray icon
Expand Down
11 changes: 10 additions & 1 deletion cmake/packaging/linux.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ if(${SUNSHINE_BUILD_APPIMAGE} OR ${SUNSHINE_BUILD_FLATPAK})
DESTINATION "${SUNSHINE_ASSETS_DIR}/modules-load.d")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service"
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine-kms.service"
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/00-sunshine-kms.preset"
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user-preset")
else()
find_package(Systemd)
find_package(Udev)
Expand All @@ -29,6 +33,10 @@ else()
if(SYSTEMD_FOUND)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service"
DESTINATION "${SYSTEMD_USER_UNIT_INSTALL_DIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine-kms.service"
DESTINATION "${SYSTEMD_USER_UNIT_INSTALL_DIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/00-sunshine-kms.preset"
DESTINATION "${SYSTEMD_USER_PRESET_INSTALL_DIR}")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/60-sunshine.conf"
DESTINATION "${SYSTEMD_MODULES_LOAD_DIR}")
endif()
Expand Down Expand Up @@ -105,10 +113,11 @@ list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
audio/opus
ftp/curl
devel/libevdev
multimedia/pipewire
net/avahi
x11/libX11
net/miniupnpc
security/openssl
x11/libX11
)

if(NOT BOOST_USE_STATIC)
Expand Down
2 changes: 2 additions & 0 deletions cmake/prep/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ elseif(UNIX) # Linux
"Enable building wayland specific code." ON)
option(SUNSHINE_ENABLE_X11
"Enable X11 grab if available." ON)
option(SUNSHINE_ENABLE_PORTAL
"Enable XDG portal grab if available" ON)
endif()
2 changes: 2 additions & 0 deletions cmake/prep/special_package_configuration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ elseif(UNIX)

# configure service
configure_file(packaging/linux/sunshine.service.in sunshine.service @ONLY)
configure_file(packaging/linux/sunshine-kms.service.in sunshine-kms.service @ONLY)
configure_file(packaging/linux/00-sunshine-kms.preset.in 00-sunshine-kms.preset @ONLY)

# configure the arch linux pkgbuild
if(${SUNSHINE_CONFIGURE_PKGBUILD})
Expand Down
35 changes: 7 additions & 28 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,16 +274,11 @@ flatpak install --user ./sunshine_{arch}.flatpak
flatpak run --command=additional-install.sh dev.lizardbyte.app.Sunshine
```

##### Run with NVFBC capture (X11 Only)
##### Run with NVFBC capture (X11 Only) or XDG Portal (Wayland Only)
```bash
flatpak run dev.lizardbyte.app.Sunshine
```

##### Run with KMS capture (Wayland & X11)
```bash
sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run dev.lizardbyte.app.Sunshine
```

##### Uninstall
```bash
flatpak run --command=remove-additional-install.sh dev.lizardbyte.app.Sunshine
Expand Down Expand Up @@ -405,37 +400,21 @@ After adding yourself to the group, log out and log back in for the changes to t

### Linux

#### KMS Capture

> [!WARNING]
> Capture of most Wayland-based desktop environments will fail unless this step is performed.
#### Services

> [!NOTE]
> `cap_sys_admin` may as well be root, except you don't need to be root to run the program. This is necessary to
> allow Sunshine to use KMS capture.

##### Enable
```bash
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
```

#### X11 Capture
For X11 capture to work, you may need to disable the capabilities that were set for KMS capture.

```bash
sudo setcap -r $(readlink -f $(which sunshine))
```

#### Service
> Two service unit files are available. Pick "sunshine" for unprivileged XDG Portal or X11 capture, otherwise
> pick "sunshine-kms" for privileged KMS capture.

**Start once**
```bash
systemctl --user start sunshine
```

**Start on boot**
**Start on boot (unprivileged; swap logic for KMS)**
```bash
systemctl --user enable sunshine
systemctl --user --now disable sunshine-kms
systemctl --user --now enable sunshine
```

### macOS
Expand Down
12 changes: 7 additions & 5 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,18 @@ sudo usermod -aG input $USER
```

### KMS Streaming fails
If screencasting fails with KMS, you may need to run the following to force unprivileged screencasting.
If screencasting fails with KMS, you may be using the unprivileged sunshine service unit. Switch to the privileged
sunshine-kms service:

```bash
sudo setcap -r $(readlink -f $(which sunshine))
systemctl --user --now disable sunshine
systemctl --user --now enable sunshine-kms
```

> [!NOTE]
> The above command will not work with the AppImage or Flatpak packages. Please refer to the
> [AppImage setup](md_docs_2getting__started.html#appimage) or
> [Flatpak setup](md_docs_2getting__started.html#flatpak) for more specific instructions.
> The above commands will not work with the AppImage or Flatpak packages, as KMS screencasting
> requires elevated privileges which are not allowed by their respective packaging security policies.
> As an alternative, XDG Portal capture is recommended.

### KMS streaming fails on Nvidia GPUs
If KMS screen capture results in a black screen being streamed, you may need to
Expand Down
4 changes: 4 additions & 0 deletions packaging/linux/00-sunshine-kms.preset.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# @PROJECT_DESCRIPTION@
# KMS service should preset to disabled

disable sunshine-kms.service
1 change: 1 addition & 0 deletions packaging/linux/Arch/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ depends=(
'libevdev'
'libmfx'
'libnotify'
'libpipewire'
'libpulse'
'libva'
'libx11'
Expand Down
8 changes: 6 additions & 2 deletions packaging/linux/copr/Sunshine.spec
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ BuildRequires: libXinerama-devel
BuildRequires: libXrandr-devel
BuildRequires: libXtst-devel
BuildRequires: openssl-devel
BuildRequires: pipewire-devel
BuildRequires: rpm-build
BuildRequires: systemd-rpm-macros
BuildRequires: wget
Expand Down Expand Up @@ -194,9 +195,10 @@ cmake_args=(
"-DCMAKE_INSTALL_PREFIX=%{_prefix}"
"-DSUNSHINE_ASSETS_DIR=%{_datadir}/sunshine"
"-DSUNSHINE_EXECUTABLE_PATH=%{_bindir}/sunshine"
"-DSUNSHINE_ENABLE_DRM=ON"
"-DSUNSHINE_ENABLE_PORTAL=ON"
"-DSUNSHINE_ENABLE_WAYLAND=ON"
"-DSUNSHINE_ENABLE_X11=ON"
"-DSUNSHINE_ENABLE_DRM=ON"
"-DSUNSHINE_PUBLISHER_NAME=LizardByte"
"-DSUNSHINE_PUBLISHER_WEBSITE=https://app.lizardbyte.dev"
"-DSUNSHINE_PUBLISHER_ISSUE_URL=https://app.lizardbyte.dev/support"
Expand Down Expand Up @@ -366,8 +368,10 @@ fi
%caps(cap_sys_admin+p) %{_bindir}/sunshine
%caps(cap_sys_admin+p) %{_bindir}/sunshine-*

# Systemd unit file for user services
# Systemd unit/preset files for user services
%{_userunitdir}/sunshine.service
%{_userunitdir}/sunshine-kms.service
%{_userpresetdir}/00-sunshine-kms.preset

# Udev rules
%{_udevrulesdir}/*-sunshine.rules
Expand Down
4 changes: 0 additions & 4 deletions packaging/linux/dev.lizardbyte.app.Sunshine.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
<code>flatpak run --command=additional-install.sh @PROJECT_FQDN@</code>
</p>
<p>NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, but it is safe.</p>
<p>NOTE: KMS Grab (Flatpak)</p>
<p>
<code>sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run @PROJECT_FQDN@</code>
</p>
</description>

<releases>
Expand Down
5 changes: 3 additions & 2 deletions packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ modules:
- -DSUNSHINE_ASSETS_DIR=share/sunshine
- -DSUNSHINE_BUILD_FLATPAK=ON
- -DSUNSHINE_EXECUTABLE_PATH=/app/bin/sunshine
- -DSUNSHINE_ENABLE_CUDA=ON
- -DSUNSHINE_ENABLE_DRM=ON
- -DSUNSHINE_ENABLE_PORTAL=ON
- -DSUNSHINE_ENABLE_WAYLAND=ON
- -DSUNSHINE_ENABLE_X11=ON
- -DSUNSHINE_ENABLE_DRM=ON
- -DSUNSHINE_ENABLE_CUDA=ON
- -DSUNSHINE_PUBLISHER_NAME='LizardByte'
- -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev'
- -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
Expand Down
16 changes: 16 additions & 0 deletions packaging/linux/sunshine-kms.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=@PROJECT_DESCRIPTION@
StartLimitIntervalSec=500
StartLimitBurst=5
Conflicts=sunshine.service

[Service]
# Avoid starting Sunshine before the desktop is fully initialized.
ExecStartPre=/bin/sleep 5
@SUNSHINE_SERVICE_START_COMMAND@
@SUNSHINE_SERVICE_STOP_COMMAND@
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=xdg-desktop-autostart.target
2 changes: 2 additions & 0 deletions packaging/linux/sunshine.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Description=@PROJECT_DESCRIPTION@
StartLimitIntervalSec=500
StartLimitBurst=5
Conflicts=sunshine-kms.service

[Service]
# Avoid starting Sunshine before the desktop is fully initialized.
Expand All @@ -10,6 +11,7 @@ ExecStartPre=/bin/sleep 5
@SUNSHINE_SERVICE_STOP_COMMAND@
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true

[Install]
WantedBy=xdg-desktop-autostart.target
1 change: 1 addition & 0 deletions packaging/sunshine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class Sunshine < Formula
depends_on "mesa"
depends_on "numactl"
depends_on "pango"
depends_on "pipewire"
depends_on "pulseaudio"
depends_on "systemd"
depends_on "wayland"
Expand Down
5 changes: 4 additions & 1 deletion scripts/linux_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ function add_debian_based_deps() {
"libnotify-dev"
"libnuma-dev"
"libopus-dev"
"libpipewire-0.3-dev"
"libpulse-dev"
"libssl-dev"
"libsystemd-dev"
Expand Down Expand Up @@ -322,6 +323,7 @@ function add_fedora_deps() {
"numactl-devel"
"openssl-devel"
"opus-devel"
"pipewire-devel"
"pulseaudio-libs-devel"
"rpm-build" # if you want to build an RPM binary package
"wget" # necessary for cuda install with `run` file
Expand Down Expand Up @@ -545,9 +547,10 @@ function run_step_cmake() {
"-DCMAKE_INSTALL_PREFIX=/usr"
"-DSUNSHINE_ASSETS_DIR=share/sunshine"
"-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine"
"-DSUNSHINE_ENABLE_DRM=ON"
"-DSUNSHINE_ENABLE_PORTAL=ON"
"-DSUNSHINE_ENABLE_WAYLAND=ON"
"-DSUNSHINE_ENABLE_X11=ON"
"-DSUNSHINE_ENABLE_DRM=ON"
)

if [[ "$appimage_build" == 1 ]]; then
Expand Down
6 changes: 3 additions & 3 deletions src/platform/linux/kmsgrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,9 +1660,9 @@ namespace platf {

if (!fb->handles[0]) {
BOOST_LOG(error) << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Probably not permitted"sv;
BOOST_LOG((window_system != window_system_e::X11 || config::video.capture == "kms") ? fatal : error)
<< "You must run [sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))] for KMS display capture to work!\n"sv
<< "If you installed from AppImage or Flatpak, please refer to the official documentation:\n"sv
BOOST_LOG((config::video.capture == "kms") ? fatal : error)
<< "If you installed from AppImage or Flatpak, KMS capture is not supported.\n"sv
<< "Please refer to the official documentation:\n"sv
<< "https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2getting__started.html#linux"sv;
break;
}
Expand Down
Loading
Loading