Jan Grulich

Tutorial: Screen Sharing and Remote Desktop on Fedora Workstation 30 (Wayland)

I recently got an email from a user asking me how to make all this work on Fedora. Problem is that unlike in old XServer sessions, there are certain things which need to be enabled first. There are also dependencies which need to be installed and services which need to be running. While most of the dependencies are automatically installed and services automatically activated, there still might be situations when this is not true, for example when switching from another desktop so it’s better to cover it all. This tutorial targets Fedora, but it can be probably used by any other distribution.

Dependencies

Both screen sharing and remote desktop work almost identically on Wayland, they both use portals as a communication tool between applications and compositor (in this case Mutter) to start the process of sharing and setup PipeWire stream (see below). While portals were primarily meant to be used by sandboxed applications (e.g. Flatpak) to get access to system (like files or printing) outside the sandbox, their design perfectly fits for Wayland usage too. In Fedora you should have portals automatically installed, they are represented by two separate packages, first is xdg-desktop-portal, which is the portal service communicating with sandboxed applications and with a backend implementation of portals, and the second package is the backend implementation, in our case xdg-desktop-portal-gtk. Both are DBus activatable, which means they are automatically started whenever application calls them. The reason why portals consist from two services is that there can be multiple backends, each one providing native dialogs for your desktop. For example you don’t get a gtk dialog to open a file in KDE Plasma session or you want a backend communicating with specific compositor (like in our case with Mutter).

The second important dependency is PipeWire. PipeWire is the core technology used for screen content delivery from the compositor to applications. This is done throught a PipeWire stream shared between the compositor and application. PipeWire should be automatically installed on your system, the package name is pipewire and it provides socket-based activation so you shouldn’t need to worry if it’s running or not.

Enabling screen sharing and remote desktop in Gnome

You don’t seem to do any additional step in order to make screen sharing work. However, you need to enable remote desktop (if you want to). Go and open gnome-control-center (Settings) and there go to Sharing section. There you should see this window when you click on Screen Sharing:

If you don’t have such option, make sure you have installed gnome-remote-desktop, because I’m not sure whether it’s installed by default. Allowing screen sharing will start a server instance which you can connect to from another computer, using vnc://linux.local or your_computer_ip:5900. You will most likely need to open a hole to your firewall, but the same you need to do for any other VNC server. I tried to connect with Vinagre and Krdc (KDE VNC viewer) and both worked for me, but I was unable to connect with Tigervnc (vncviewer) due to not maching security type.

Screen sharing in Firefox

Firefox in Fedora already comes with PipeWire support enabled and you don’t need to do anything special. You can test it for example with this testing page. The PipeWire support in Firefox unfortunately needs to be enabled during build by handmade changes, which is most likely not happening in other distributions, but from what I now there is an ongoing effort to make this configurable with a build option.

Screen sharing in Chromium/Chrome

Similar situation is with Chromium, where PipeWire needs to be also enabled during build, but it’s already configurable via a build option. In Fedora we have this enabled by default. Official Chrome builds are build with PipeWire support enabled as well. I should maybe mention that PipeWire support is in Chromium starting with version 74.

Unlike with Firefox, this support needs to be also enabled in runtime. You can do that with following chrome flag:

chrome://flags/#enable-webrtc-pipewire-capturer

Then you should be all set to be able to share a screen or a window from your Chromium or Chrome.

Issues

Don’t get scared by higher number of dialogs for screen/windows selection you will get when sharing screen in your browser. We are aware of this annoying usability issue and hopefully we will manage to solve it one day. The reason why this happens is that every browser provide their dialog for screen/window selection and in both browsers these dialogs show previews of your selection. You need to select screen/window first in the portal dialog for the preview dialog and once you accept the preview dialog in your browser, you again need to select screen/window in the portal dialog to get the content into the web page itself.

Support in other applications

There is a KDE application called Krfb, which in the next release (19.08) will have similar support for remote desktop on Wayland as you have in Gnome. Otherwise there are probably no other applications which would allow you to share a screen or control your desktop remotely on Gnome Wayland sessions. You will not be able to use TeamViewer, Tigervnc or any other application you are used to use. If you want to use these applications, you will have to switch to X session for now.

KDE Flatpak portals introduction

I guess you all have heard about Flatpak, Snappy and sandboxing in general. Flatpak is a new way of distributing applications. With Flatpak applications are running in sandbox, which means they are isolated from the rest of your system. With that in mind you need a way how to access some stuff outside the sandbox, like your files or have access to your hardware. To solve this problem the Flatpak developers came up with portals. Portals are high-level session bus APIs that provide access to resources to sandboxed applications. Idea is that there is one DBus service available and visible for the sandboxed application which is supposed to communicate with it to get access outside the sandbox. Then this one service communicates with backend implementations which may be different per desktop so you have in example a Gnome implementation or in my case KDE implementation. The backend then provides dialogs so users can access files or hardware outside the sandbox. To add portal support you need to add your backend implementation, which is quite easy part and if you don’t have any then one from other available ones will be used. Complicated part is to alter the framework the application is using to use the portal DBus service instead of doing what it usually do (e.g. when opening a file dialog you want to send a request over DBus instead of actually displaying the dialog). I’ve been playing with this for some time and I tried to cover the most common or required portals. Let’s go through all of this:

File chooser portal

I think this is the most common and needed portal from all of them. I’ve added a backend implementation as well as support for this to Qt in form of my own Qt platform plugin. Given you can modify Qt’s behaviour using your own Qt platform plugin then I didn’t have to modify Qt at all. The platform plugin alters FileDialog to talk around DBus instead of showing the dialog. The dialog is then shown thanks to the backend implementation and user running app in sandbox shouldn’t notice any difference. The file chooser portal supports both opening and saving files with possibilities to set properties like filters, accept label text etc. which are all already implemented in both like in the platform plugin and the backend.

App chooser portal

This portal allows the user to select an application outside the sandbox which should be used for opening a document, a file or whatever. It is also used when opening an url. On the backend side this is just a simple dialog with list of possible applications associated with given file/document type. On Qt side I added my own implementation of OpenUrl() again into the platform plugin to make it transparent the same way the file dialog works.

Print portal

I guess the most complicated and also quite important portal. I’ve been able to add just backend implementation so far which will be used for printing from gtk applications as gtk already supports printing from sandbox. The idea behind this portal is that when app requests to print a document, it calls PreparePrint() method and the backend presents classic print dialog to the user where he can configure printer, setup the page and paper and so on. This configuration is then passed back to the application where the framework is supposed to create a pdf or ps file already pre-formatted and ready for printing. This file is then passed as file descriptor again to the backend using Print() method and printed. This all works with Qt backend and gtk app, or Gnome backend and gtk app, but unfortunately not yet with Qt apps as I still don’t know how to do this without touching Qt code as this cannot be done on platform plugin level, at least from what I can see. A simple solution can be to don’t touch Qt at all and let the app print the document to file and have a simple utility sending this file through the portal to print it. As you can set application name which should be used for printing in QPrinter, then we maybe can just set this automatically when the app is running in sandbox to make this work automatically. I’m definitely open to your ideas or any help :).

Notification portal

Again very useful portal and not that complicated. I have full backend implementation presenting a notification outside the sandbox when someone calls AddNotification() method. To make this work for KDE applications automatically I had to modify KNotifications framework and implement my own flatpak plugin which replaces NotifyByPopup plugin. All this plugin does instead displaying a popup it calls the portal DBus service which then calls AddNotification() in my backend and presents notification outside the sandbox. Both the plugin and backend supports also sending back information about triggered action so you can also get feedback back to the sandboxed application.

Those are all the portals I have fully or partially covered so far. There are of course more portals designed in Flatpak portal API, like screenshot portal, inhibit portal, but for some of them we don’t have any framework/API or they are not that important so they will be added later. I also have a test application which you can run in sandbox and test all the portals.

How to use flatpak portals

In order to use flatpak portals, either my implementation or the Gnome one, you need to install xdg-desktop-portal which is the main portal DBus service visible to sandboxed applications and which calls backend implementation. For gtk implementation you need xdg-desktop-portal-gtk and for KDE/Qt implementation you need xdg-desktop-portal-kde. This is required to be installed outside the sandbox to present dialogs for file and hardware access. To add support for portals to your sandboxed application you should be fine already with gtk, with Qt and KDE you need my Qt platform plugin and my modifications made to KNotifications. To use those you need to modify flatpak manifest to include them during build so they are available in the sandbox. You can get inspiration in my test app manifest. And finally to use my platform plugin as KNotifications will be used automatically you need to start your app using flatpak run your_app -platform flatpak.

I guess that’s all from me today. Patches and improvements are warmly welcomed as well as any reported issue. If you want some information about Flatpak and KDE in general, we have setup a wiki page where you can find information about KDE runtimes and applications packaged for Flatpak. There will be also a talk at FOSDEM this year about Flatpak and KDE from Aleix Pol.

Scroll To Top