How to display GUI in Torizon?

Hi! I am trying to display a simple GUI on Torizon. I’m using the Torizon image with evaluation containers, as well as Python3 and GTK+3, and I want to display the basic window example. I’ve tried the following:

First approach:

  • create a container based on the torizon/weston image
  • stop the existing torizon_weston_1 and torizon_kiosk_1 containers
  • run my container in Privileged mode
  • install the required packages (apt-get update && apt-get install python3 python3-pip python3-gi libgtk-3-dev)
  • run the window application

The window is displayed, but the mouse is not visible (maybe the keyboard is not active as well, but I haven’t checked). Thus, I cannot interact with the window. The following message is displayed in the console:

(main.py:40): Gdk-CRITICAL **: 15:31:48.323: gdk_seat_get_keyboard: assertion 'GDK_IS_SEAT (seat)' failed

Second approach:

  • create a container based on the torizon/arm32v7-debian-dev-tools image (basically, an image without weston)
  • stop the existing torizon_kiosk_1 container
  • run my container in Privileged mode
  • install the required packages (apt-get update && apt-get install python3 python3-pip python3-gi libgtk-3-dev)
  • run the window application

The window is not displayed and I get the following error message from GTK:

Unable to init server: Could not connect: Connection refused

What am I doing wrong? I am sure there is a configuration error somewhere. Also, are there other configurations necessary for enabling interaction via touchscreen (including hiding the mouse pointer, touchscreen calibration)?

Greetings @CristianM,

I was able to get the example working as follows:

Launch a weston and wayland container as follows here: https://developer.toradex.com/knowledge-base/debian-container-for-torizon

Added the python dependencies in the wayland container then started the example. I can click on the window and I have a mouse cursor available.

As a side note the mouse cursor functionality is provided by the weston container. With our latest bullseye based weston container the mouse cursor appears and is functional as long as a recognized mouse device is attached to the system. For example I’m just using a USB attached mouse.

Best Regards,
Jeremias

Thank you. I confirm it works. The problem was that I needed to clearly define the following volume mappings: /tmp:/tmp, /run/udev:/run/udev, /dev:/dev, /var/run/dbus:/var/run/dbus.

However, I do not understand why these mappings are necessary when executing the container in priviledged mode.

But I found another issue: if I set in Portainer the Entry point as python3 and the CMD as ‘main.py’ (the GUI file), in order to automatically start the GUI when the container starts, then I get the error:

Unable to init server: Could not connect: Connection refused

and the GUI does not start. It seems that it launches the GUI before Weston starts. Is there a way to launch the GUI after Weston starts (I tried a delay in the python script but it did not help)?

So with containers in order to have access to something you need 2 things, permissions and access. The --privileged flag gives you basically root access. However you still need to give the container “physical” filesystem access to whatever you want to use. Which is why we need to bind-mount things like /dev. Otherwise these directories don’t physically exist in the container filesystem. While --privileged gives you root access in the container, it doesn’t give the container the ability to “break out” and access the host filesystem, except via bind mounts.

As for your other question. There’s two way to ensure container start-up order. Either manually launch Weston and wait till it’s up before you start your dependent container. Or and this is the preferred approach use a docker-compose file. Docker-compose files are useful for orchestrating more than 1 container as you can define dependencies between containers so that they start up in the right order.

As an example here’s the docker-compose.yml we use to start Portainer itself which is a 3 container solution: https://github.com/toradex/torizon-samples/blob/master/debian-container/demonstration/docker-compose.armhf.yml

Notice on line 59, the depends_on argument. This ensures both portainer and weston and started before the kiosk container. More information about docker-compose file syntax can be found here: https://docs.docker.com/compose/compose-file/

Best Regards,
Jeremias

Thank you for clarifying this. I have used docker-compose based on your example configuration. You can find attached the file I’ve used. The problem is that the only way I managed to get it working is by launching a weston container and afterwards launching my container (with GUI) that is also based on a weston image. If I use another base image for my container (e.g., torizon/arm32v7-debian-dev-tools), I get the following errors in the log and the GUI does not start:

Unable to init server: Could not connect: Connection refused
Unable to init server: Could not connect: Connection refused

(main.py:1): Gtk-CRITICAL **: 20:36:03.559: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed

(main.py:1): Gtk-CRITICAL **: 20:36:03.559: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed

(main.py:1): Gtk-CRITICAL **: 20:36:03.560: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed

So, is this normal? In order to display a GUI, I need a weston image as base for my container (in addition to the other weston container that must be launched before this one)?

docker-compose.yml

Oh wait so to clarify, your docker-compose works then correct? It’s just you want to use an alternative base container image?

Well the issue is that you need a container with a proper graphical stack since you’re using creating a graphical application. I’m unsure how familiar you are with weston/wayland graphical stack. But basically Weston is the graphical compositor for Wayland. Meaning there needs to be at least 1 Weston client running, but 1 Weston client can serve multiple Wayland graphical requests. Typically our applications have a Weston base container and then multiple Wayland containers that have the actual graphical application. Or in this case 2 weston containers work too since 1 acts as the Weston client and the other just provides the Wayland protocol. This is because our Weston containers build on top of our wayland containers, so they have both parts of the stack.

When you use a base container like " torizon/arm32v7-debian-dev-tools" there’s no wayland protocol installed there by default, so it can’t communicate with the weston container acting as the compositor. This seems consistent with the errors your application are throwing which seem to complain about no graphical provider being available.

Please refer to this article: https://developer.toradex.com/knowledge-base/debian-container-for-torizon

It has a graphic which shows how are containers are built on top of one another, as well as a link to our github which has the source Dockerfile for those containers so you know what packages/software are built into each container by default. The article also goes more into a bit about the Weston/Wayland graphical stack.

Best Regards,
Jeremias

Thank you. I understand now.

Glad we were able to resolve this.