Thursday, September 05, 2013

Raspberry pi boot straight into a GUI application

I wanted the pi to automatically start x and run my mono application but I don't need a pile of menus etc, so I googled a bit, but couldn't find an article that really did what I want.

I followed the instructions in this article with some additions.

Step 1: add startx to /etc/rc.local

#/etc/rc.local
sudo -u pi startx &
Step 2: allow non-interactive processes to launch an X server
sudo dpkg-reconfigure x11-common
(and select Any User)

Step 3: add your application to ~/.xinitrc
I deviated here a bit, to run my mono app I wrapped it in a perl script, which monitors STDOUT and STDERR because I found that there can occasionally be exceptions which cause the program to stop being displayed, but the mono process does not exit. I monitor the output for /exception: read failure/i and if it is in the output, I kill the process and start another. I'll post the script if anyone wants it.

These steps are enough to start x and run my app, but its actually pretty much the same as running the standard LXDE with an autostart entry.

Step 4: Change the x-session-manager
sudo update-alternatives --config x-session-manager
 I selected the option /usr/bin/openbox-session which provides a much more minimal x-session.

Step 5: Add a startup background
I discovered that x starts pretty quickly, but it leaves the background black for quite a while before it begins to draw my application. So I want to display a png file in the background while my app is starting.
sudo apt-get install feh
 feh can be used to display an image, so I just added it to my xinitrc file
#~/.xinitrc
export DISPLAY=:0
xscreensaver -no-splash &
feh  /home/pi/images/starting_background.png &
/home/pi/mono/Debug/runGUI.pl

Now almost as soon as the screen goes black, it displays my waiting image.


Step 6: remove the normal raspi-config start x

Finally run raspi-config, and change the pi so it doesnt automatically try to start x through the init method.
sudo raspi-config

Conclusion

This solution works perfectly for me, I don't mind some text scrolling on startup, but I know there are ways to get rid of that too.  Now there is no overhead of menus etc, and the only app running in the GUI is mine. Job done.

6 comments:

Julian Jorgov said...

Thank you very much for the post!

Could you please post or send me the scripts that you talk about in "Step 3"

Thank you again!

Simon said...

Julian, really sorry, just noticed your comment, perl script is:

#!/usr/bin/perl

use strict;
use warnings;

use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
$ENV{'DISPLAY'} = ":0";
while(1==1){
local *CATCHERR = IO::File->new_tmpfile;
my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "mono SimpleGui.exe");
print "Started process pid is $pid\n";
while( ) {
handle($_, $pid);
}
waitpid($pid, 0);
seek CATCHERR, 0, 0;
while( ) {
handle($_, $pid);
}
sleep 2;
}

sub handle{
my ($line, $pid) = @_;
chomp($line);
print "handling $line\n";
if($line =~ /exception: read failure/i){
print "kill process $pid\n";
print `kill $pid`;
}
}

Simon said...

That perl script just gets run from a shell script: runGUI.sh

echo attempt >> /tmp/attempts.txt

cd /home/pi/mono/Debug
export DISPLAY=:0

./runGUI.pl


Simon said...

...and the shell script gets run from .config/autostart/heating_gui.desktop

which will load when x starts, and it looks like this:


[Desktop Entry]
Name=Heating GUI
Exec=/home/pi/mono/Debug/runGUI.sh
Type=application

Rohan Jadhav said...

Thank you for the post, Simon. Can you please also explain how to get rid of scrolling text at startup. Switching on RaspberryPi directly to the application would be so awesome. Thanks again.

Simon said...

Hi Rohan, in the newest raspi-config there is an option for splash screen. If that isn't what you are looking for then you should check on the raspberry pi forums - there is a lot of general information on there!