The perfect Raspberry Pi setup
I am doing some semi-serious Raspberry Pi development, so it was time I figured out how to do it comfortably.
My desktop setup is a two-monitor configuration, with my notebook on the table and a larger monitor above it. I like it, it's nice. The pointer naturally goes from one screen to the other in the obvious way.
Specially nice is that the laptop's screen is touch and has an active pen, so I can use it naturally.
But now, with the Raspberry, I want to occasionally show its display. And that means switching the monitor to it. Since I hate plugging and unplugging things, I use one of these:
It's a cheap tiny black plastic box that takes up to 5 HDMI inputs and switches between them to its one output by clicking a button. It only goes through the inputs that have signal, so since I only have the laptop's and the Pi's the button toggles between them.
If your monitor has more than one HDMI input you can probably just use that, but mine has just one.
But... what about keyboard and mouse?
I could get a multidevice keyboard and mouse, but I like the ones I have.
I could use a USB switch and toggle between the two devices, but ... I don't have one.
So, I use barrier and configure it in both the raspberry pi and in the laptop so that when my pointer goes "up" input goes to the Pi, and when it goes "down" input goes to the laptop. That's exactly the same as with the dual-display setup, but with two computers. Neat!
So, go ahead and configure barrier. It's easy and there are tons of tutorials.
Next, make sure barrier starts when I login into both computers. They way I prefer to do these things is using systemd.
Put this in ~/.local/share/systemd/user/barrier.service
in both machines:
[Unit]
Description=Barrier server
[Service]
Environment=DISPLAY=:0
Type=simple
TimeoutStartSec=0
ExecStart=/usr/bin/barrier
[Install]
WantedBy=default.target
Now you can make it start with systemctl --user start barrier
or stop with systemctl --user stop barrier
and make it start on every login with systemctl --user enable barrier
But while this is nice, it presents a problem. When I am using both displays for the laptop, I don't want barrier running! Since I can't see the Pi's display, it makes no sense.
So, I want to start barrier when the laptop is using one monitor, and stop it when it's using two.
To do that, the trick is udev
in the laptop. Put this (replacing my username with yours) in /etc/udev/rules.d/90-barrier.rules
:
ACTION=="change", \
KERNEL=="card0", \
SUBSYSTEM=="drm", \
ENV{DISPLAY}=":0", \
ENV{XAUTHORITY}="/home/ralsina/.Xauthority", \
ENV{XDG_RUNTIME_DIR}="/run/user/1000", \
RUN+="/home/ralsina/bin/monitors-changed"
Basically that means "when there is a change in the configuration of the video card, run monitors-changed
. Change the 1000
by your user ID, too.
The last piece of the puzzle is the monitors-changed
script:
if `xrandr --listmonitors | grep -q HDMI`
then
# The HDMI output is connected, stop barrier
su ralsina -c '/usr/bin/systemctl stop --user barrier'
else
# The Pi is using the monitor, start barrier
su ralsina -c '/usr/bin/systemctl start --user barrier'
fi
And that's it!
This is the behaviour now:
When the laptop is using both displays, they work normally in a "extended display" configuration. They behave like a single large screen.
When I click on the HDMI switch and change the top display to show the Pi's desktop, automatically barrier starts in the laptop, and now the pointer and keyboard change from one computer to the other when the pointer moves from one monitor to the next.
If I click on the HDMI switch again, barrier stops on the laptop and I have a single two-screen desktop again.
Everything behaves perfectly and I can switch between computers by clicking a button.
Alternatively, we could start the barrier client when the raspberry pi "gets" the display, and stops it when it goes away. The result should be the same except for some corner cases, but it has the added benefit of allowing for a setup with up to 5 devices :-)