Screen sharing, Wayland, Gentoo, Firefox, Zoom
Trying to share a screen in Zoom on Gentoo with Wayland (Sway), and failing miserably. If you are reading this, you've probably been there. I did get it to work, eventually, so here are some pointers for future me or perhaps current you.
Disclaimer
Before you read on, beware: I fully admit that I have very little clue about
Pipewire and how it exactly interacts with other parts of my system, or yours.
My audio/video use is limited to listening to music with deadbeef and watching
videos with mpv and that still works after what I've done to make screen
sharing work. If you have some complicated video editing or live-stream setup,
please don't break it. (Then again, you probably know better how all of this
ties together).
My system
At the time of writing this post and trying to get screen sharing to work, my setup is:
- Gentoo, kernel 6.13.3
- systemd 256
- Sway 1.9
- wlroots 0.17.4 / 0.18.2
- Firefox 135
- Zoom 6.3.10.7150
And eventually after installing what is described below:
- Pipewire 1.2.7
- Wireplumber 0.5.7
- xdg-desktop-portal 1.18.4
- xdg-desktop-portal-wlr 0.7.1
- gstreamer 1.24.11
It was while using Zoom that I realised screen sharing was not working at all, but perhaps more convenient is this page to test screen sharing in the browser:
https://mozilla.github.io/webrtc-landing/gum_test.html.
For me, when I finally got things working, both Zoom and Firefox allowed me to share my screen.
Installing ... stuff
My system already had media-video/pipewire installed, but I had to add the
dbus and gstreamer USE flags. sys-apps/xdg-desktop-portal was also already
installed, not sure why.
Install / recompile those, and install media-video/wireplumber and
gui-libs/xdg-desktop-portal-wlr as well. Make sure to enable and start both
pipewire and wireplumber for your user.
(Apparently in the past, there was at least on Arch Linux a thing called
gst-plugin-pipewire but its functionality is provided by wireplumber since.)
sudo emerge pipewire wireplumber xdg-desktop-portal xdg-desktop-portal-wlr
systemctl --user enable --now pipewire
systemctl --user enable --now wireplumber.service
Edit /usr/share/xdg-desktop-portal/portals.conf:
[preferred]
default=*
org.freedesktop.impl.portal.Screenshot=wlr
org.freedesktop.impl.portal.ScreenCast=wl
Incorporate the following somewhere in the sway config
(~/.config/sway/config):
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
exec systemctl --user restart xdg-desktop-portal
And now, perhaps reloading your sway config is sufficient, but I just stopped my sway entirely, logged out and back in (I don't use a login/session manager) and started it back up. And eventually, I verified everything worked after a full reboot.
Hopefully at this point, sharing the screen in the Mozilla test page linked above works. If not, checking the statuses of all these might reveal some errors or provide hints:
systemctl --user status pipewire
systemctl --user status wireplumber
systemctl --user status xdg-desktop-portal
systemctl --user status xdg-desktop-portal-wlr
There is also this python script that does something, unsure what exactly, but
it might provide some pointers if things are still not working. Specifically the
pipewire pipeline on line 68 was throwing errors on my system which gave me
clues on where to look. I never got the last part of that pipeline,
xvimagesink, to work, but replacing that with autovideosink made the script
work without erroring out. And still I have no clue what it does, but hey.
Credits to Jonas Ã…dahl for this script, which can be found at
https://gitlab.gnome.org/-/snippets/19
But I want to share an application window
Sharing individual windows in Wayland-land is not yet possible (though things
seem to be moving and we might see something soon, fingers crossed), but a nice
workaround in Sway using a headless output and wl-mirror was posted by Nicolas
Gotchac (ngotchac) in [0]. Credits and many thanks to them for this cool
solution! Copied verbatim, two scripts that are hopefully self-explanatory for
swaywm users, firstly one to set things up:
#!/usr/bin/env bash
# Step 1: Create a new output
swaymsg create_output
# Step 2: Find the name of the newly created output
NEW_OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name' | sort | tail -n 1)
# Check if the output was successfully created
if [ -z "$NEW_OUTPUT" ]; then
echo "Failed to create a new output."
exit 1
fi
# Step 3: Assign a workspace to the new output
swaymsg workspace sshr output "$NEW_OUTPUT"
# Step 4: Set the resolution for the new output
swaymsg output "$NEW_OUTPUT" resolution 1280x720
# Step 5: Set the background color for the new output
swaymsg output "$NEW_OUTPUT" bg "#220900" solid_color
# Step 6: Switch to workspace sshr and then back to the previous workspace
CURRENT_WORKSPACE=$(swaymsg -t get_workspaces | jq -r '.[] | select(.focused) | .name')
swaymsg workspace sshr
swaymsg workspace "$CURRENT_WORKSPACE"
wl-mirror "$NEW_OUTPUT"
notify-send "Created new output $NEW_OUTPUT."
And secondly the script to tear things down again:
#!/usr/bin/env bash
# Get all outputs with names starting with HEADLESS-
headless_outputs=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name')
# Check if there are any HEADLESS outputs
if [ -z "$headless_outputs" ]; then
echo "No HEADLESS outputs found."
exit 0
fi
# Unplug each HEADLESS output
for output in $headless_outputs; do
echo "Unplugging $output..."
swaymsg output "$output" unplug
done
notify-send "All HEADLESS outputs have been unplugged."
This worked beautifully with both Zoom and Firefox for me! Simply move the application window you want to share to the sshr desktop on the new headless output, and make the application window full screen. Then pick that headless output as the 'screen' you want to share in Firefox/Zoom/whatever. With the mirrored view, you can still see what's going on on the headless output. Really a clever trick from Nicolas.
Disclaimer, again
YMMV etc, I honestly have no clue how all of this works, and presumably I already had some things installed that are crucial in all of this. But who knows.
Feel free to hit me up via mastodon if you are trying to get this to work on a similar setup.