Black screen when you RDP into your own Linux desktop? Give the console to a second user
Log in at the physical console, then RDP in as the same user, and you get a black screen. Worse, unlike Windows, the remote connection can't kick the console session — so any machine you walked away from while logged in is a machine you can't reach.
Neither is really an RDP problem, and one trick fixes both: create a second Unix account that owns the console.
sudo adduser desk
desk logs in at the display manager and holds the physical machine. Your real user never logs in locally at all — its desktop exists only as an xrdp session. When you're sitting at the machine, desk connects to it over loopback:
xfreerdp3 /v:127.0.0.1 /u:youruser +clipboard /multimon
Now every client is equal. Connect from a laptop on the other side of the world and it takes over the same session your local xfreerdp was showing; the local one just exits and desk's desktop is still sitting there underneath. Don't wrap that command in an auto-reconnect loop, or the machine at home will keep stealing the session back and you'll never get in from outside.
The black screen was never about RDP — it was one user running two concurrent desktop sessions, colliding on all the per-user singletons: the session D-Bus, xfce4-session, ibus, gvfs. The second session's window manager never comes up. Two different uids have none of that.
The takeover failure is a separate mechanism. "Taking over" is really xrdp-sesman reconnecting you to a session in its own table. A console session started by lightdm was never in that table, so nothing can ever reattach to it — which is also why a second RDP client can kick the first: those two are the same session.
One setting is load-bearing. In /etc/xrdp/sesman.ini:
[Sessions]
Policy=Default
KillDisconnected=false
Default means sesman matches on <user, bpp> only. If it's ever UBD or UBDI, connecting at a different resolution or from a different IP spawns a second session instead of taking over, and the whole design quietly collapses.
Now the parts that cost me real time.
Your real user can never reach the mic, webcam or sound card. systemd-logind grants the ACLs on /dev/snd/* and /dev/video* to the active seat session only — that's desk:
$ getfacl /dev/snd/controlC0
user:desk:rw-
Don't fight this. Run Teams and Zoom in desk's session, where the hardware natively is. It's also why desk should be a normal desktop account rather than a locked-down kiosk shell.
failed to open display: with nothing after the colon has nothing to do with RDP. FreeRDP opens the X display in pre_connect, before any network activity, so this fires long before the server is contacted. An empty display name just means $DISPLAY is unset, and su - desk is a login shell that resets the environment — exactly like ssh does. Run the script from a terminal inside desk's own X session. You can reproduce it offline with env -u DISPLAY xfreerdp3 ....
An "empty desktop with no panel" is often a perfectly healthy session drawn where you can't see it. Check that before you debug anything else:
pgrep -u youruser -a -f "xfce4-panel|xfce4-session|xfdesktop"
If they're all running, the session is fine. On a laptop running lid-closed, the built-in panel usually stays connected 1920x1200+0+0 — still enabled, and still at the origin. /multimon forwards it like any other monitor, so the first RDP monitor is that dark screen, and the whole region silently swallows your panel, your dialogs and every new window. Drop it from the layout:
xrandr --output eDP-1 --off --output DP-1 --primary --pos 0x0 --output DP-2 --right-of DP-1
Setting a different primary output will not rescue a panel that's already stranded there. xfce4-panel stores an absolute position like p=5;x=0;y=0 and only relocates itself when that position falls outside every monitor — here it falls inside one that is perfectly legal and simply switched off. Fix the layout instead and the panel walks back into view on its own, config untouched.
The neat part is that you only fix this once. The RDP session's monitor layout is whatever the client forwards, so cleaning up the console user's xrandr cleans up the remote session too.