HOWTO: Run your IoT GUI on your desktop

When developing things it is nice to have all your familiar development tools to hand. And the same is true when snapping applications to run on Ubuntu Frame.

Instead of running everything on an Ubuntu Core device and having to use ssh only to miss some key development tool; Or having to switch to another VT on your development machine and have processes you’re trying to use suspend; Or trying to find another laptop to ssh into your own machine… wouldn’t it be nice to simply have Ubuntu Frame running on a window on your desktop?

It is as easy as 1, 2, 3…

0. Install your snap

We’ll use wpe-webkit-mir-kiosk as an example here, but you can use your own snap, or a different one from the store. The only requirement is that it is intended as a IoT GUI as snaps intended for desktop use may work differently.

snap install wpe-webkit-mir-kiosk
snap connect wpe-webkit-mir-kiosk:wayland

1. Install frame-it

snap install frame-it --classic

Frame-it is a collection of scripts intended to make development and testing with Ubuntu Frame simpler.

  • frame-it.check checks Ubuntu Frame is installed plus options frame-it uses
  • frame-it gnome-calendar will run gnome-calendar using Ubuntu Frame
  • snap set frame-it shell-app=gnome-calendar sets the shell-app option
  • frame-it.shell will run Ubuntu Frame using the shell-app option
  • sudo frame-it.root-on-x11 will run Ubuntu Frame as root using X11

When shell-app is set a login shell is provided from the greeter: Logging into “frame-it” will run Ubuntu Frame using the shell-app option as a user session

2. Run frame-it.check

$ frame-it.check
Checking: Ubuntu Frame installation (needed for all commands)
 . OK . : Ubuntu Frame is installed
Checking: Ubuntu Frame has login-session-control (needed to run a login shell)
 . OK . : ubuntu-frame:login-session-control is connected
Checking: shell-app option (needed for frame-it.shell and to run a login shell)
 WARNING: shell-app not set. Please run the following (with the app you choose):
  snap set frame-it shell-app=...

If you don’t have Ubuntu Frame installed already, Frame-it will prompt you with the commands to install it. Ignore any “WARNING” messages about shell-app for now as that’s an advanced feature we don’t need.

3. Frame-it “your IoT GUI”

There are two ways you can use Frame-it to run your application.

3.1 frame-it

The first simply runs it as the current user (and can also be used for non-snapped applications that use Wayland). This doesn’t test everything that might need testing on an IoT device, but is more convenient for tests of your UI.

frame-it snap run wpe-webkit-mir-kiosk.cog

(If you’re using your own snap, it probably won’t have or need the .cog extension. I don’t know why wpe-webkit-mir-kiosk has that.)

3.2 Running your “daemon”

Normally, when deployed on an IoT device your snap will run as a daemon (which makes the user “root”, not your current user). To test this mode of operation we need to run Ubuntu Frame as root, and start the daemon for your snap.

Running Ubuntu Frame as root requires running one of the Frame-it scripts as root:

sudo frame-it.root-on-x11

Running your snap’s daemon may take a couple of commands. Many IoT GUI snaps don’t try to run their daemons by default unless installed on Ubuntu Core and use a daemon configuration option to control this.

$ snap set wpe-webkit-mir-kiosk daemon=true
$ snap restart wpe-webkit-mir-kiosk.daemon

(If you’re using your own snap, it probably won’t have or need the .daemon extension. I don’t know why wpe-webkit-mir-kiosk has that.)

And that’s it!

Note: Not all snaps need the sudo snap set mir-kiosk-apps daemon=true command, but snaps packaged using mir-kiosk-snap-launch (and run-daemon) default to not running the daemon when not on Ubuntu Core.


Note: On Frame-it being a “classic” snap

It is a classic snap, which gives it full access to your system, but you can review all the scripts to see what they are doing:

$ find /snap/frame-it/current/ -type f -executable
/snap/frame-it/current/frame-it
/snap/frame-it/current/frame-it-check
/snap/frame-it/current/frame-it-root-on-x11
/snap/frame-it/current/frame-it-shell
/snap/frame-it/current/meta/hooks/configure
/snap/frame-it/current/meta/hooks/remove
/snap/frame-it/current/snap/hooks/configure
/snap/frame-it/current/snap/hooks/remove
6 Likes

If you’re running a Wayland desktop, then the default configuration of Xwayland prevents root from connecting.

It is possible workaround to some extent with:

Xwayland -ac :1&
sudo DISPLAY=:1 mir-kiosk

But the Xwayland root window is somewhat annoying.

1 Like

There is an alternative to using --devmode: Edit the apparmor profile directly to add a couple of permissions:

sudoedit /var/lib/snapd/apparmor/profiles/snap.mir-kiosk.mir-kiosk

Just before the closing “}”, add the following lines:

# hacks to allow running as root on desktop
capability dac_read_search,
/run/user/[0-9]*/gdm/Xauthority r,

Then reload:

sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.mir-kiosk.mir-kiosk
1 Like

With the release of Mir 1.6 there’s another workaround for the inability for root to connect to the desktop: run a miral-system-compositor using X11 and use that to host the mir-kiosk compositor:

sudo apt install mir-demos
WAYLAND_DISPLAY=wayland-1 miral-system-compositor&
sudo mkdir -p /run/user/0 && sudo ln -sf /run/user/1000/wayland-1 /run/user/0
env -u WAYLAND_DISPLAY sudo mir-kiosk --wayland-host wayland-1

This has the advantage that the mir-kiosk window behaves normally on the desktop.

Note: Don’t think too hard about what this is doing, it sounds mad: a Mir compositor (mir-kiosk) runs on a second Mir compositor (mir-system-compositor) using Wayland; the latter runs on Xwayland using X11; and, Xwayland runs on GNOME using Wayland.

2 posts were split to a new topic: Making a kiosk question

Hi, Alan

I use the method 1 to test my electron desktop application. All step is ok and thank you your this post. I just want to know how to make mir window full screen?

“Mir-on-X” is meant for testing within a desktop environment. So far, nobody has thought it important to spend time making “fullscreen” work. You can size the window, or request multiple windows:

mir-kiosk --x11-output 600x400:1200x500

2 posts were split to a new topic: Running a kiosk on Ubuntu Classic

5 posts were merged into an existing topic: Running a kiosk on Ubuntu Classic

I’m running into trouble with this…
I’ve got a computer running Ubuntu Desktop 18.04.3 LTS. I am using Method 1 because I assume 18.04.3 is X11, because they switched back to Xorg from Wayland… right?

Anyways, I run the following:

snap install --devmode mir-kiosk
sudo mir-kiosk

And get the orange splash in a “Mir on X” labeled window… I then run:

snap install --edge mir-kiosk-apps
snap connect mir-kiosk-apps:wayland   #this doesn't say anything, but doesn't give errors either.
sudo snap restart mir-kiosk-apps

No errors, but the “Mir on X” window is still black. I can see my cursor move around (same as before), but that’s it.

sudo snap logs -n 50 mir-kiosk
systemd[1]: Started Service for snap application mir-kiosk.daemon

I will post error logs for mir-kiosk-apps next…

2020-01-14T18:27:31Z mir-kiosk-apps.daemon[19920]: + grep -q snap_core= /proc/cmdline
2020-01-14T18:27:31Z mir-kiosk-apps.daemon[19920]: + snapctl get daemon
2020-01-14T18:27:31Z mir-kiosk-apps.daemon[19920]: + [ false = true ]
2020-01-14T18:27:31Z mir-kiosk-apps.daemon[19920]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T18:27:31Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T18:27:31Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T18:52:30Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T18:52:30Z mir-kiosk-apps.daemon[22358]: + grep -q snap_core= /proc/cmdline
2020-01-14T18:52:30Z mir-kiosk-apps.daemon[22358]: + snapctl get daemon
2020-01-14T18:52:30Z mir-kiosk-apps.daemon[22358]: + [ false = true ]
2020-01-14T18:52:30Z mir-kiosk-apps.daemon[22358]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T18:52:30Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T18:52:30Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T18:58:43Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T18:58:43Z mir-kiosk-apps.daemon[23282]: + grep -q snap_core= /proc/cmdline
2020-01-14T18:58:43Z mir-kiosk-apps.daemon[23282]: + snapctl get daemon
2020-01-14T18:58:43Z mir-kiosk-apps.daemon[23282]: + [ false = true ]
2020-01-14T18:58:43Z mir-kiosk-apps.daemon[23282]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T18:58:43Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T18:58:43Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:06Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30003]: + grep -q snap_core= /proc/cmdline
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30003]: + snapctl get daemon
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30003]: + [ false = true ]
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30003]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30003]: error: error running snapctl: snap "mir-kiosk-apps" has "install-snap" change in progress
2020-01-14T19:52:06Z systemd[1]: snap.mir-kiosk-apps.daemon.service: Main process exited, code=exited, status=1/FAILURE
2020-01-14T19:52:06Z systemd[1]: snap.mir-kiosk-apps.daemon.service: Failed with result 'exit-code'.
2020-01-14T19:52:06Z systemd[1]: snap.mir-kiosk-apps.daemon.service: Service hold-off time over, scheduling restart.
2020-01-14T19:52:06Z systemd[1]: snap.mir-kiosk-apps.daemon.service: Scheduled restart job, restart counter is at 1.
2020-01-14T19:52:06Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:06Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30124]: + grep -q snap_core= /proc/cmdline
2020-01-14T19:52:06Z mir-kiosk-apps.daemon[30124]: + snapctl get daemon
2020-01-14T19:52:06Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T19:52:06Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:06Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:52:07Z mir-kiosk-apps.daemon[30183]: + grep -q snap_core= /proc/cmdline
2020-01-14T19:52:07Z mir-kiosk-apps.daemon[30183]: + snapctl get daemon
2020-01-14T19:52:07Z mir-kiosk-apps.daemon[30183]: + [ false = true ]
2020-01-14T19:52:07Z mir-kiosk-apps.daemon[30183]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T19:52:07Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T19:52:07Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:53:01Z systemd[1]: Started Service for snap application mir-kiosk-apps.daemon.
2020-01-14T19:53:01Z mir-kiosk-apps.daemon[30409]: + grep -q snap_core= /proc/cmdline
2020-01-14T19:53:01Z mir-kiosk-apps.daemon[30409]: + snapctl get daemon
2020-01-14T19:53:01Z mir-kiosk-apps.daemon[30409]: + [ false = true ]
2020-01-14T19:53:01Z mir-kiosk-apps.daemon[30409]: + snapctl stop mir-kiosk-apps.daemon
2020-01-14T19:53:01Z systemd[1]: Stopping Service for snap application mir-kiosk-apps.daemon...
2020-01-14T19:53:01Z systemd[1]: Stopped Service for snap application mir-kiosk-apps.daemon.

Any ideas? Thanks for the help.

Thanks for reminding me. Recent changes mean that you need:

sudo snap set mir-kiosk-apps daemon=true

I’ll update the main article.

3 posts were split to a new topic: Problems running Electron app in mir-kiosk on kvm

I tried the steps in the first post, but I get an error when I try fake-kiosk mir-kiosk. Any ideas? I’m in the Ubuntu derivative Pop_os.

Output:

~ ❯ ./fake-kiosk.sh mir-kiosk
+ kiosk=mir-kiosk
+ sudo mir-kiosk --help
+ true
+ sudo cp /run/user/1000/gdm/Xauthority /root/snap/mir-kiosk/current/.Xauthority
+ XAUTHORITY=/root/snap/mir-kiosk/current/.Xauthority exec sudo mir-kiosk
2021/12/11 12:59:22.939255 cmd_run.go:597: WARNING: XAUTHORITY environment value is not a clean path: "/root/snap/mir-kiosk/7805/.Xauthority"
+ mkdir -p /root/snap/mir-kiosk/7805/.config/
+ grep -vE (^vt=|^console-provider=vt|^display-layout=) /var/snap/mir-kiosk/7805/miral-kiosk.config
+ exec /snap/mir-kiosk/7805/bin/run-miral
[2021-12-11 20:59:22.969709] <information> mirserver: Starting
[2021-12-11 20:59:22.974714] < - debug - > mirserver: Not trying logind: "DISPLAY" is set and X need not have claimed the VT
[2021-12-11 20:59:22.974780] < - debug - > mirserver: Not using Linux VT subsystem for session management: Failed to open current VT
[2021-12-11 20:59:22.974873] < - debug - > mirserver: No session management supported
[2021-12-11 20:59:22.976986] <information> VT switch key handler: No VT switching support available: MinimalConsoleServices does not support VT switching
[2021-12-11 20:59:22.979792] <information> mircommon: Loading modules from: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform
[2021-12-11 20:59:22.979812] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/graphics-gbm-kms.so.19
[2021-12-11 20:59:22.979819] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/server-x11.so.19
[2021-12-11 20:59:22.979823] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/input-evdev.so.8
[2021-12-11 20:59:22.990642] < - debug - > gbm-kms: Quirks: checking device with devnode: /dev/dri/card1, driver nvidia
[2021-12-11 20:59:22.990755] <information> mirserver: Found graphics driver: mir:gbm-kms (version 2.5.0) Support priority: 256
[2021-12-11 20:59:23.006182] <information> mirserver: Found graphics driver: mir:x11 (version 2.5.0) Support priority: 192
[2021-12-11 20:59:23.006217] <information> mirserver: Selected driver: mir:gbm-kms (version 2.5.0)
[2021-12-11 20:59:23.006418] < - debug - > gbm-kms: Quirks: checking device with devnode: /dev/dri/card1, driver nvidia
[2021-12-11 20:59:23.006460] <information> gbm-kms: Using DRM device /dev/dri/card1
[2021-12-11 20:59:23.006501] < - debug - > gbm-kms: Quirks: checking device with devnode: /dev/dri/card0, driver i915
[2021-12-11 20:59:23.006579] < -warning- > gbm-kms: Failed to open DRM device node /dev/dri/card0: /build/mir-XggYb6/mir-2.5.0/src/server/console/minimal_console_services.cpp(137): Throw in function virtual std::future<std::unique_ptr<mir::Device> > mir::MinimalConsoleServices::acquire_device(int, int, std::unique_ptr<mir::Device::Observer>)
Dynamic exception type: boost::wrapexcept<std::system_error>
std::exception::what: Failed to acquire DRM master: Operation not permitted

Failed to create /root/.cache/mesa_shader_cache for shader cache (Permission denied)---disabling.
[2021-12-11 20:59:23.784417] <information> mircommon: Loading modules from: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform
[2021-12-11 20:59:23.784456] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/graphics-gbm-kms.so.19
[2021-12-11 20:59:23.784464] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/server-x11.so.19
[2021-12-11 20:59:23.784467] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/input-evdev.so.8
[2021-12-11 20:59:23.785438] < - debug - > gbm-kms: Quirks: checking device with devnode: /dev/dri/card1, driver nvidia
Failed to create /root/.cache/mesa_shader_cache for shader cache (Permission denied)---disabling.
[2021-12-11 20:59:23.844975] <information> gbm-kms: Detected software renderer: llvmpipe (LLVM 12.0.0, 256 bits)
[2021-12-11 20:59:23.845625] < - debug - > gbm-kms: Quirks: checking device with devnode: (null), driver 
[2021-12-11 20:59:23.845666] < - debug - > gbm-kms: Quirks: checking device with devnode: (null), driver 
[2021-12-11 20:59:23.845713] < - debug - > gbm-kms: Quirks: checking device with devnode: /dev/dri/card0, driver i915
Failed to create /root/.cache/mesa_shader_cache for shader cache (Permission denied)---disabling.
[2021-12-11 20:59:23.901985] <information> mirserver: Found graphics driver: mir:gbm-kms (version 2.5.0) Support priority: 256
[2021-12-11 20:59:23.902403] <information> mirserver: Found graphics driver: mir:x11 (version 2.5.0) Support priority: 192
[2021-12-11 20:59:23.902445] <information> mirserver: Selected driver: mir:gbm-kms (version 2.5.0)
[2021-12-11 20:59:24.984725] <information> gbm-kms: DRM device details:
[2021-12-11 20:59:24.984768] <information> gbm-kms: /dev/dri/card1: using driver nvidia-drm [NVIDIA DRM driver] (version: 0.0.0 driver date: 20160202)
[2021-12-11 20:59:24.984917] <information> gbm-kms: 	Output: DisplayPort-4 (disconnected)
[2021-12-11 20:59:24.985011] <information> gbm-kms: 	Output: DisplayPort-5 (disconnected)
[2021-12-11 20:59:24.985025] < -warning- > miral: Display config does not contain layout 'default'
[2021-12-11 20:59:24.985111] <information> miral: Display config:
8>< ---------------------------------------------------
layouts:
# keys here are layout labels (used for atomically switching between them)
# when enabling displays, surfaces should be matched in reverse recency order

  default:                         # the default layout

    cards:
    # a list of cards (currently matched by card-id)

    - card-id: 0
      DisplayPort-1:
        # (disconnected)

      DisplayPort-2:
        # (disconnected)
8>< ---------------------------------------------------
Failed to create /root/.cache/mesa_shader_cache for shader cache (Permission denied)---disabling.
Failed to create /root/.cache/mesa_shader_cache for shader cache (Permission denied)---disabling.
[2021-12-11 20:59:25.004856] <information> mirserver: Using hardware cursor
[2021-12-11 20:59:25.005329] < -warning- > gbm-kms-buffer-allocator: Failed to bind EGL Display to Wayland display, falling back to software buffers: /build/mir-XggYb6/mir-2.5.0/src/platform/graphics/egl_extensions.cpp(92): Throw in function mir::graphics::EGLExtensions::WaylandExtensions::WaylandExtensions(EGLDisplay)
Dynamic exception type: boost::wrapexcept<std::runtime_error>
std::exception::what: EGL display doesn't support EGL_WL_bind_wayland_display

[2021-12-11 20:59:25.005367] <information> gbm-kms-buffer-allocator: Enabled linux-dmabuf import support
[2021-12-11 20:59:25.005492] <information> mircommon: Loading modules from: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform
[2021-12-11 20:59:25.005512] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/graphics-gbm-kms.so.19
[2021-12-11 20:59:25.005524] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/server-x11.so.19
[2021-12-11 20:59:25.005530] <information> mircommon: Loading module: /snap/mir-kiosk/7805/usr/lib/x86_64-linux-gnu/mir/server-platform/input-evdev.so.8
[2021-12-11 20:59:25.055788] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.5.0)
[2021-12-11 20:59:25.056044] <information> mirserver: Mir version 2.5.0
[2021-12-11 20:59:25.076197] <information> mirserver: Initial display configuration:
[2021-12-11 20:59:25.076241] <information> mirserver: * Output 1: DisplayPort disconnected
[2021-12-11 20:59:25.076248] <information> mirserver: * Output 2: DisplayPort disconnected
[2021-12-11 20:59:25.307941] < -warning- > frontend:Wayland: Exception processing Surface::commit() request: /build/mir-XggYb6/mir-2.5.0/src/miral/basic_window_manager.cpp(2334): Throw in function void miral::BasicWindowManager::validate_modification_request(const miral::WindowSpecification&, const miral::WindowInfo&) const
Dynamic exception type: boost::wrapexcept<std::runtime_error>
std::exception::what: width must be positive

error in client communication (pid 324134)
wl_display@1: error 3: Mir internal error processing Surface::commit() request
[2021-12-11 20:59:32.343864] <information> evdev-input: Added /dev/input/event3
[2021-12-11 20:59:32.358176] <information> evdev-input: Added /dev/input/event5
[2021-12-11 20:59:32.361840] <information> evdev-input: Added /dev/input/event8
[2021-12-11 20:59:32.364613] <information> evdev-input: Added /dev/input/event0
[2021-12-11 20:59:32.366539] <information> evdev-input: Added /dev/input/event2
[2021-12-11 20:59:32.366569] <information> evdev-input: Added /dev/input/event1
[2021-12-11 20:59:32.368477] <information> evdev-input: Added /dev/input/event7
[2021-12-11 20:59:32.368516] <information> evdev-input: Added /dev/input/event10
[2021-12-11 20:59:32.368539] <information> evdev-input: Added /dev/input/event11
[2021-12-11 20:59:32.368560] <information> evdev-input: Added /dev/input/event12
[2021-12-11 20:59:32.368597] <information> evdev-input: Added /dev/input/event13
[2021-12-11 20:59:32.368627] <information> evdev-input: Added /dev/input/event6: BisonCam NB Pro
[2021-12-11 20:59:32.370180] <information> evdev-input: Added /dev/input/event28
[2021-12-11 20:59:32.370378] <information> evdev-input: Added /dev/input/event29
[2021-12-11 20:59:32.370396] <information> evdev-input: Added /dev/input/event14
[2021-12-11 20:59:32.370417] <information> evdev-input: Added /dev/input/event15
[2021-12-11 20:59:32.370432] <information> evdev-input: Added /dev/input/event16
[2021-12-11 20:59:32.370446] <information> evdev-input: Added /dev/input/event17
[2021-12-11 20:59:32.370461] <information> evdev-input: Added /dev/input/event18
[2021-12-11 20:59:32.370474] <information> evdev-input: Added /dev/input/event19
[2021-12-11 20:59:32.370488] <information> evdev-input: Added /dev/input/event20
[2021-12-11 20:59:32.370502] <information> evdev-input: Added /dev/input/event21
[2021-12-11 20:59:32.370516] <information> evdev-input: Added /dev/input/event22
[2021-12-11 20:59:32.370531] <information> evdev-input: Added /dev/input/event23
[2021-12-11 20:59:32.370545] <information> evdev-input: Added /dev/input/event24
[2021-12-11 20:59:32.370559] <information> evdev-input: Added /dev/input/event25
[2021-12-11 20:59:32.370572] <information> evdev-input: Added /dev/input/event26
[2021-12-11 20:59:32.370585] <information> evdev-input: Added /dev/input/event27
[2021-12-11 20:59:32.370599] <information> evdev-input: Added /dev/input/event9
[2021-12-11 20:59:32.371972] <information> evdev-input: Added /dev/input/event4
^C[2021-12-11 21:00:09.618899] < - debug - > mirserver: Handling Interrupt from pid=0

The problem is that Mir’s automatic selection of backend has been confused by your hybrid system. There’s an Nvidia card with no outputs connected that it is trying to use. (On my own hybrid system it correctly detects that this should not be used, so I’ve not seen this before.)

This problem can be avoided by manually selecting the backend by adding --platform-display-libs mir:x11 --platform-rendering-libs mir:x11 to the last line of the fake-kiosk script. (I’ve updated the post accordingly.)