Is the example of x11-glxgears still relevant for creating x11 based snaps with Ubuntu-Frame

Hi everyone. Recently our snap cluemaster-mediadisplay-core faced an issue because of an old approach mir-kiosk-x11-snap with Ubuntu-frame. And we were suggested by @alan_g to use a more recent approach like

OR

Since our snap, is dependent on x11 because of a Qt Wayland bug

qt.qpa.wayland: Wayland does not support QWindow::requestActivate()

We were wondering if the example of x11-glxgears is still relevant to be used as a reference for creating x11 based Qt5 snaps, because on checking out the snapcraft.yaml of x11-glxgears,

name: iot-example-graphical-snap
version: git # just for humans, typically '1.2+git' or '1.3.2'
summary: IoT example - glxgears using X11
description: IoT example - glxgears using X11
confinement: strict
compression: lzo
grade: stable
base: core20

apps:
  iot-example-graphical-snap:
    command-chain: &_command-chain
      - bin/wayland-launch
      - env-setup
      - usr/local/bin/x11_kiosk_launch
    command: &_command usr/bin/glxgears
    plugs: &_plugs
      - opengl
      - wayland
      - network-bind   # For Mir (to serve X11)

  daemon:
    daemon: simple
    restart-delay: 3s
    restart-condition: always
    command-chain: *_command-chain
    command: *_command
    plugs: *_plugs

# This is one of four snippets that relate to providing the userspace graphics needed by your application.
# You can treat this as "magic" so long as you don't need to make changes.
# On the Mir discourse forum there's a lot more detail on [the graphics-core20 Snap interface](https://discourse.ubuntu.com/t/the-graphics-core20-snap-interface/23000) and it's use.
plugs:
  graphics-core20:
    interface: content
    target: $SNAP/graphics
    default-provider: mesa-core20

environment:
  # This is one of four snippets that relate to providing the userspace graphics needed by your application.
  LD_LIBRARY_PATH:    $SNAP/graphics/lib
  LIBGL_DRIVERS_PATH: $SNAP/graphics/dri
  LIBVA_DRIVERS_PATH: $SNAP/graphics/dri
  __EGL_VENDOR_LIBRARY_DIRS: $SNAP/graphics/glvnd/egl_vendor.d
  # Other, generally useful environment settings...
  # XDG config
  XDG_CACHE_HOME:  $SNAP_USER_COMMON/.cache
  XDG_CONFIG_HOME: $SNAP_USER_DATA/.config
  XDG_CONFIG_DIRS: $SNAP/etc/xdg
  # XKB config
  XKB_CONFIG_ROOT: $SNAP/usr/share/X11/xkb

# The `layout` ensures that files can be found by applications where they are expected by the toolkit or application.
layout:
  # This is one of four snippets that relate to providing the userspace graphics needed by your application.
  # These paths (/usr/share/libdrm and /usr/share/drirc.d) are hardcoded in mesa.
  /usr/share/libdrm:  # Needed by mesa-core20 on AMD GPUs
    bind: $SNAP/graphics/libdrm
  /usr/share/drirc.d:  # Used by mesa-core20 for app specific workarounds
    bind: $SNAP/graphics/drirc.d
  # Other, generally useful paths
  /usr/share/fonts:
    bind: $SNAP/usr/share/fonts
  /usr/share/icons:
    bind: $SNAP/usr/share/icons
  /usr/share/sounds:
    bind: $SNAP/usr/share/sounds
  /etc/fonts:
    bind: $SNAP/etc/fonts
  # X11
  /usr/bin/xkbcomp:
    symlink: $SNAP/usr/bin/xkbcomp
  /usr/share/X11:
    bind: $SNAP/usr/share/X11

parts:
  glxgears:
    plugin: nil
    stage-packages:
      - mesa-utils
    stage-snaps: [mir-kiosk-x11] # This adds an X server based on Xwayland
    prime:
      - -hacks/setup-gl # Don't use the gl setup from mir-kiosk-x11, we use graphics-core20

  # Some utility scripts for setting up the Wayland environment
  wayland-launch:
    plugin: dump
    source: wayland-launch
    override-build: |
      # The plugs needed to run Wayland. (wayland-launch checks them, setup.sh connects them)
      # You may add further plugs here if you want these options
      PLUGS="opengl wayland graphics-core20"
      sed --in-place "s/%PLUGS%/$PLUGS/g" $SNAPCRAFT_PART_BUILD/bin/wayland-launch
      sed --in-place "s/%PLUGS%/$PLUGS/g" $SNAPCRAFT_PART_BUILD/bin/setup.sh
      snapcraftctl build
    stage-packages:
      - inotify-tools

  # This is one of four snippets that relate to providing the userspace graphics needed by your application.
  # This ensures that your snap doesn't contain its own copy of the userspace drivers
  cleanup:
    after: [glxgears, wayland-launch]
    plugin: nil
    build-snaps: [ mesa-core20 ]
    override-prime: |
      set -eux
      cd /snap/mesa-core20/current/egl/lib
      find . -type f,l -exec rm -f $SNAPCRAFT_PRIME/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/{} \;
      rm -fr "$SNAPCRAFT_PRIME/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/dri"
      cd "$SNAPCRAFT_PRIME/usr/share"
      rm -rf bug drirc.d glvnd libdrm lintian man

architectures:
  - build-on: amd64
  - build-on: armhf
  - build-on: arm64

I found that it also uses the same mir-kiosk-x11. Maybe is it different from the way we use it?

Here is the snapcraft.yaml for cluemaster-mediadisplay-core

name: cluemaster-mediadisplay-core 
base: core20 
version: '2023.03.21'
summary: Clumaster.io Media Display for Escape Rooms 
description: |
  ClueMaster Media Display is a Dynamic TV Display software for escape rooms.
  It shows escape room countdown timers, visual text messages, video, audio,
  and photo clues.
grade: stable 
confinement: strict 

apps:
  cluemaster-mediadisplay-core:
    daemon: simple
    restart-condition: always
    command-chain:
      - env-setup
    command: usr/local/bin/x11_kiosk_launch $SNAP/bin/desktop-launch $SNAP/bin/prepare-launch $SNAP/cluemaster_display
    environment:
      DISABLE_WAYLAND: 1

  pulseaudio:
    command: bin/pulseaudio
    daemon: simple
    restart-condition: always
    install-mode: enable

  pactl:
    command-chain: [bin/client-wrapper]
    command: usr/bin/pactl

  paplay:
    command-chain: [bin/client-wrapper]
    command: usr/bin/paplay

  parec:
    command-chain: [bin/client-wrapper]
    command: usr/bin/parec

  config:
    command: bin/config

plugs:
  playback:
    interface: audio-playback
  wayland:
  network:
  opengl:
  network-bind:
  shutdown:
  hardware-observe:
  alsa:

slots:
  audio-playback:

parts:
  copy-source-code:
    after: [desktop-qt5]
    plugin: dump
    source: cluemaster_display/
    stage-packages:
      - ffmpeg
      - libass9
      - mpv
      - alsa-base
      - locales
      - libvdpau1
      - i965-va-driver
      - libmpv1
      - va-driver-all
      - vdpau-driver-all
      - mesa-va-drivers
      - libvdpau-va-gl1
      - libglu1-mesa
      - samba-libs
      - git
      - python3-dbus
      - qtwayland5
      - mesa-utils
      - libgl1-mesa-dri
      - python3-pyqt5.qtmultimedia
      - libqt5multimedia5-plugins

    stage:
      - -usr/share/alsa/alsa.conf
      - -usr/share/alsa/cards/HDA-Intel.conf
      - -usr/share/alsa/cards/USB-Audio.conf
      - -usr/share/alsa/cards/aliases.conf
      - -usr/share/alsa/pcm/center_lfe.conf
      - -usr/share/alsa/pcm/default.conf
      - -usr/share/alsa/pcm/dmix.conf
      - -usr/share/alsa/pcm/dsnoop.conf
      - -usr/share/alsa/pcm/front.conf
      - -usr/share/alsa/pcm/hdmi.conf
      - -usr/share/alsa/pcm/iec958.conf
      - -usr/share/alsa/pcm/modem.conf
      - -usr/share/alsa/pcm/rear.conf
      - -usr/share/alsa/pcm/side.conf
      - -usr/share/alsa/pcm/surround21.conf
      - -usr/share/alsa/pcm/surround40.conf
      - -usr/share/alsa/pcm/surround41.conf
      - -usr/share/alsa/pcm/surround50.conf
      - -usr/share/alsa/pcm/surround51.conf
      - -usr/share/alsa/pcm/surround71.conf
      - -README.md


    stage-snaps: [mir-kiosk-x11]

  extras:
    plugin: dump
    source: static/
    organize:
      "prepare-launch": "bin/"

  desktop-qt5:
    source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
    source-subdir: qt
    plugin: make
    make-parameters: ["FLAVOR=qt5"]
    build-packages:
      - build-essential
      - qtbase5-dev
      - dpkg-dev
    stage-packages:
      - libxkbcommon0
      - ttf-ubuntu-font-family
      - dmz-cursor-theme
      - light-themes
      - adwaita-icon-theme
      - gnome-themes-standard
      - shared-mime-info
      - libqt5gui5
      - libgdk-pixbuf2.0-0
      - libqt5svg5 
      - try: [appmenu-qt5]
      - locales-all
      - xdg-user-dirs
      - libdrm2
      - libgbm1
      - libdrm-intel1
      - libdrm-nouveau2
      - libdrm-radeon1
      - libegl1
      - libglapi-mesa
      - libglvnd0
      - libglx0
      - fcitx-frontend-qt5

  pulseaudio-common:
    source: bin
    plugin: dump
    organize:
      client-wrapper: bin/client-wrapper
      config: bin/config
      pulseaudio: bin/pulseaudio
  alsa-lib:
    plugin: autotools
    source: https://github.com/alsa-project/alsa-lib.git
    source-tag: v1.2.5.1
    prime:
      - -usr/include
      - -usr/share/aclocal
      - -usr/lib/lib*.la
      - -usr/lib/pkgconfig
  pulseaudio:
    plugin: meson
    source: https://github.com/pulseaudio/pulseaudio.git
    source-tag: v15.0
    source-depth: 1
    after: [ alsa-lib ]
    build-packages:
      - check
      - doxygen
      - intltool
      - libapparmor-dev
      - libdbus-1-dev
      - libjson-c-dev
      - libglib2.0-dev
      - libspeexdsp-dev
      - libbluetooth-dev
      - libltdl-dev
      - libsndfile1-dev
      - libtdb-dev
      - libudev-dev
      - libasyncns-dev
      - libsbc-dev
      - libsnapd-glib-dev
      - libsoxr-dev
    stage-packages:
      - libapparmor1
      - libasyncns0
      - libbluetooth3
      - libflac8
      - libglib2.0-0
      - libgomp1
      - libjson-c4
      - libltdl7
      - libogg0
      - libsbc1
      - libsnapd-glib1
      - libsndfile1
      - libsoxr0
      - libsoxr-lsr0
      - libspeexdsp1
      - libtdb1
      - libudev1
      - libvorbis0a
      - libvorbisenc2
    meson-parameters:
      - --prefix="/usr"
      - --sysconfdir=/etc
      - --libexec=/usr/lib
      - --libdir=/usr/lib
      - --localstatedir=/var
      - -Dgstreamer="disabled"
      - -Dbluez5-gstreamer="disabled"
      - -Dorc="disabled"
      - -Dgsettings="disabled"
      - -Dadrian-aec="false"
      - -Dgtk="disabled"
      - -Dhal-compat="false"
      - -Dwebrtc-aec="disabled"
      - -Doss-output="disabled"
      - -Djack="disabled"
      - -Dx11="disabled"
      - -Dsystem_user="root"
      - -Dsystem_group="root"
      - -Daccess_group="root"
    override-build: |
      snapcraftctl build
      VER=$(cd $SNAPCRAFT_PART_SRC; git tag|sed 's/^v//')
      snapcraftctl set-version $VER
      mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/applications
    override-prime: |
      snapcraftctl prime
      find usr/share/doc/ -type f,l ! -name copyright | xargs rm -rf
    prime:
      - -usr/include
      - -usr/share/zsh
      - -usr/share/bash-completion
      - -usr/share/man
      - -usr/share/GConf
      - -usr/share/lintian
      - -usr/share/vala
      - -usr/libexec
      - -usr/lib/cmake
      - -usr/lib/pkgconfig
      - -usr/lib/systemd
      - -etc/dconf
  alsa-plugins:
    plugin: autotools
    source: https://github.com/alsa-project/alsa-plugins.git
    source-tag: v1.2.5
    after: [ pulseaudio, alsa-lib ]
    autotools-configure-parameters:
      - --prefix=/usr
      - --with-alsalconfdir=/etc/alsa/conf.d
      - --sysconfdir=/etc/alsa/conf.d
    prime:
      - -usr/lib/alsa-lib/*.la
    override-prime: |
      snapcraftctl prime
      # make links relative
      cd etc/alsa/conf.d
      for link in $(find . -type l); do
        newlink=$(readlink $link|sed 's;^/;../../../;')
        ln -sf $newlink $link
      done
      cd -
  alsa-ucm:
    plugin: dump
    source: https://github.com/alsa-project/alsa-ucm-conf.git
    source-tag: v1.2.5.1
    after: [ alsa-plugins ]
    organize:
      ucm: usr/share/alsa/ucm
      ucm2: usr/share/alsa/ucm2
    prime:
      - -README.md

environment:
  LD_LIBRARY_PATH: "$SNAP/usr/lib/pulseaudio:$SNAP/usr/lib/alsa-lib"
  PULSE_RUNTIME_PATH: /var/run/pulse
  PULSE_STATE_PATH: $SNAP_COMMON/state
  ALSA_CONFIG_UCM: $SNAP/usr/share/alsa/ucm2
  ALSA_CONFIG_TPLG: $SNAP/usr/share/alsa/topology
  ALSA_CONFIG_PATH: $SNAP/usr/share/alsa/alsa.conf
  ALSA_MIXER_SIMPLE: $SNAP/usr/share/alsa/smixer.conf
  ALSA_PLUGIN_DIR: $SNAP/usr/lib/alsa-lib


layout:
  /usr/share/X11:
    bind: $SNAP/usr/share/X11
  /usr/bin/xkbcomp:
    symlink: $SNAP/usr/bin/xkbcomp
  /usr/share/icons:
    bind: $SNAP/usr/share/icons
  /usr/share/fonts:
    bind: $SNAP/usr/share/fonts
  /usr/local/share/fonts:
    bind: $SNAP/usr/local/share/fonts
  /etc/fonts:
    bind: $SNAP/etc/fonts
  /etc/pulse:
    bind: $SNAP/etc/pulse
  /etc/alsa:
    bind: $SNAP/etc/alsa
  /var/lib/pulse:
    bind: $SNAP_DATA
  /usr/lib/pulse-15.0:
    symlink: $SNAP/usr/lib/pulse-15.0
  /usr/lib/alsa-lib:
    bind: $SNAP/usr/lib/alsa-lib
  /usr/share/pulseaudio:
    symlink: $SNAP/usr/share/pulseaudio
  /usr/share/alsa:
    symlink: $SNAP/usr/share/alsa
  /usr/share/applications:
    bind: $SNAP/usr/share/applications

Thanks.

Yes, the usage is different.

Here is an example of the differences in how it is used.

Here is another.

Note that we will be reworkng the examples to cover core22 shortly, which will allow us to drop compatibility with earlier approaches.

1 Like

That is hardly a Qt Wayland bug. Qt cannot steal focus, because Wayland doesn’t allow it. Perhaps your app could work without this?

Hi @alan_g. Thanks for the reply. We tested our app with Wayland, but unfortunately, most of the main features were lost due to Qt not being able to capture focus, that’s the main reason we are going for x11.

Our app uses multiple windows, that require the top focus. These windows are triggered based on API responses and conditions.