diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..549a195
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+*
+!data/
diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml
new file mode 100644
index 0000000..3adff45
--- /dev/null
+++ b/.github/workflows/common.yml
@@ -0,0 +1,101 @@
+concurrency: ${{ github.workflow }}/${{ github.ref }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ push:
+ description: "Push built image"
+ default: true
+ required: false
+ type: boolean
+
+ workflow_call:
+ inputs:
+ push:
+ description: "Push built image"
+ default: true
+ required: false
+ type: boolean
+
+jobs:
+ build-test:
+ runs-on: ubuntu-24.04
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - image: fedora-39
+ dockerfile: fedora.dockerfile
+
+ - image: fedora-40
+ dockerfile: fedora.dockerfile
+
+ - image: debian-12
+ dockerfile: debian.dockerfile
+
+ - image: debian-13
+ dockerfile: debian.dockerfile
+
+ - image: ubuntu-24.04
+ dockerfile: debian.dockerfile
+
+ - image: archlinux
+ dockerfile: archlinux.dockerfile
+
+ - image: opensuse-tumbleweed
+ dockerfile: suse.dockerfile
+
+ - image: opensuse-leap-15.6
+ dockerfile: suse.dockerfile
+
+ timeout-minutes: 15
+ env:
+ IMAGE: ghcr.io/${{ github.repository }}/${{ matrix.image }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.repository_owner }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - id: docker_meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.IMAGE }}
+
+ - id: docker_build
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ${{ matrix.dockerfile }}
+ build-args: |
+ base_image=${{ matrix.image }}
+ pull: true
+ push: ${{ inputs.push }}
+ tags: ${{ steps.docker_meta.outputs.tags }}
+ labels: ${{ steps.docker_meta.outputs.labels }}
+ annotations: ${{ steps.docker_meta.outputs.annotations }}
+ cache-from: |
+ ${{ steps.docker_meta.outputs.tags }}
+ ${{ env.IMAGE }}:master
+ cache-to: type=inline
+
+ - run: podman pull docker-daemon:${{ steps.docker_build.outputs.imageid }} | tee .podman-image-id
+
+ - id: gnome-session-x11
+ name: Test gnome-session-x11
+ run: test/test-x11.sh $(cat .podman-image-id)
+
+ - id: gnome-session-wayland
+ name: Test gnome-session-wayland
+ run: test/test-wayland.sh $(cat .podman-image-id)
+
+ - name: Upload screenshot
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ matrix.image }}-screenshots
+ path: test/*.png
+ if: ${{ always() }}
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
new file mode 100644
index 0000000..a092bd2
--- /dev/null
+++ b/.github/workflows/master.yml
@@ -0,0 +1,23 @@
+name: master
+
+on:
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - renovate.json
+ - README.md
+ - LICENSE
+
+permissions:
+ packages: write
+
+jobs:
+ ci:
+ uses: ./.github/workflows/common.yml
+ tag:
+ needs: ci
+ uses: ./.github/workflows/tag.yml
+ permissions:
+ contents: write
+ actions: write
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 0000000..18ee3b3
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,15 @@
+name: pr
+
+on:
+ pull_request:
+ paths-ignore:
+ - renovate.json
+ - README.md
+ - LICENSE
+
+jobs:
+ ci:
+ if: ${{ github.event.pull_request.base.repo.node_id != github.event.pull_request.head.repo.node_id }}
+ uses: ./.github/workflows/common.yml
+ with:
+ push: false
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
new file mode 100644
index 0000000..099b1ce
--- /dev/null
+++ b/.github/workflows/push.yml
@@ -0,0 +1,20 @@
+name: push
+
+on:
+ workflow_dispatch:
+ push:
+ branches-ignore:
+ - master
+ tags:
+ - "*"
+ paths-ignore:
+ - renovate.json
+ - README.md
+ - LICENSE
+
+permissions:
+ packages: write
+
+jobs:
+ ci:
+ uses: ./.github/workflows/common.yml
diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml
new file mode 100644
index 0000000..8f6eac6
--- /dev/null
+++ b/.github/workflows/tag.yml
@@ -0,0 +1,20 @@
+on:
+ workflow_call:
+ workflow_dispatch:
+
+jobs:
+ tag:
+ runs-on: ubuntu-latest
+ steps:
+ - id: tag
+ uses: ddterm/autotag@2023.11.18.1
+
+ - uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.actions.createWorkflowDispatch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ workflow_id: 'push.yml',
+ ref: '${{ steps.tag.outputs.ref }}',
+ })
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e708454
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2021 Aleksandr Mezin
+Copyright (c) 2021 Simon Schneegans
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/archlinux.dockerfile b/archlinux.dockerfile
new file mode 100644
index 0000000..98b641b
--- /dev/null
+++ b/archlinux.dockerfile
@@ -0,0 +1,26 @@
+FROM docker.io/library/archlinux:latest@sha256:649f22ffe44950a2fbdd7b4f3ad7eaf1ae017d60360f857ba1b07902121824d4
+
+RUN pacman -Rdd --noconfirm dbus-broker-units \
+ && pacman -Syu --noconfirm \
+ dbus-daemon-units \
+ gnome-shell \
+ vte3 \
+ vte4 \
+ xorg-server-xvfb \
+ xorg-xinit \
+ mesa \
+ packagekit \
+ gdm \
+ wl-clipboard \
+ libhandy \
+ && pacman -Scc --noconfirm
+
+COPY data /
+
+RUN systemctl set-default multi-user.target && \
+ systemctl mask systemd-oomd low-memory-monitor rtkit-daemon udisks2 && \
+ useradd -m -U -G users,adm gnomeshell && \
+ truncate --size 0 /etc/machine-id && \
+ dconf update
+
+CMD [ "/sbin/init" ]
diff --git a/data/etc/dbus-1/session.d/insecure.conf b/data/etc/dbus-1/session.d/insecure.conf
new file mode 100644
index 0000000..9930c9b
--- /dev/null
+++ b/data/etc/dbus-1/session.d/insecure.conf
@@ -0,0 +1,7 @@
+
+
+
+ ANONYMOUS
+
+
diff --git a/data/etc/systemd/journald.conf b/data/etc/systemd/journald.conf
new file mode 100644
index 0000000..c6e48ce
--- /dev/null
+++ b/data/etc/systemd/journald.conf
@@ -0,0 +1,31 @@
+[Journal]
+Storage=volatile
+Compress=no
+Seal=no
+#SplitMode=uid
+#SyncIntervalSec=5m
+#RateLimitIntervalSec=30s
+#RateLimitBurst=10000
+#SystemMaxUse=
+#SystemKeepFree=
+#SystemMaxFileSize=
+#SystemMaxFiles=100
+#RuntimeMaxUse=
+#RuntimeKeepFree=
+#RuntimeMaxFileSize=
+#RuntimeMaxFiles=100
+#MaxRetentionSec=
+#MaxFileSec=1month
+ForwardToSyslog=no
+ForwardToKMsg=no
+ForwardToConsole=yes
+ForwardToWall=no
+TTYPath=/dev/console
+#MaxLevelStore=debug
+#MaxLevelSyslog=debug
+#MaxLevelKMsg=notice
+MaxLevelConsole=debug
+#MaxLevelWall=emerg
+#LineMax=48K
+ReadKMsg=no
+Audit=no
diff --git a/data/etc/systemd/system/systemd-logind.service.d/override.conf b/data/etc/systemd/system/systemd-logind.service.d/override.conf
new file mode 100644
index 0000000..b51859a
--- /dev/null
+++ b/data/etc/systemd/system/systemd-logind.service.d/override.conf
@@ -0,0 +1,3 @@
+# Required to make systemd-logind work
+[Service]
+ProtectHostname=no
diff --git a/data/etc/systemd/system/upower.service.d/override.conf b/data/etc/systemd/system/upower.service.d/override.conf
new file mode 100644
index 0000000..6b4d3e0
--- /dev/null
+++ b/data/etc/systemd/system/upower.service.d/override.conf
@@ -0,0 +1,2 @@
+[Service]
+PrivateUsers=no
diff --git a/debian.dockerfile b/debian.dockerfile
new file mode 100644
index 0000000..6a32b07
--- /dev/null
+++ b/debian.dockerfile
@@ -0,0 +1,31 @@
+ARG base_image=ubuntu-24.04
+
+FROM docker.io/library/debian:12@sha256:aadf411dc9ed5199bc7dab48b3e6ce18f8bbee4f170127f5ff1b75cd8035eb36 AS debian-12
+FROM docker.io/library/debian:trixie@sha256:0c75aed52e3a564e27c3aaba51b0a7e59ac21dd09abcb25f2fe0b9b37c8f7e01 AS debian-13
+FROM docker.io/library/ubuntu:24.04@sha256:8a37d68f4f73ebf3d4efafbcf66379bf3728902a8038616808f04e34a9ab63ee AS ubuntu-24.04
+
+FROM ${base_image}
+
+RUN apt-get update -y && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+ gnome-session \
+ gjs \
+ dbus-user-session \
+ gdm3 \
+ gir1.2-vte-2.91 \
+ gir1.2-vte-3.91 \
+ xvfb \
+ packagekit \
+ gir1.2-packagekitglib-1.0 \
+ wl-clipboard \
+ gir1.2-handy-1
+
+COPY data /
+
+RUN systemctl set-default multi-user.target && \
+ systemctl mask systemd-oomd low-memory-monitor rtkit-daemon udisks2 && \
+ useradd -m -U -G users,adm gnomeshell && \
+ truncate --size 0 /etc/machine-id && \
+ dconf update
+
+CMD [ "/sbin/init" ]
diff --git a/fedora.dockerfile b/fedora.dockerfile
new file mode 100644
index 0000000..3a6b564
--- /dev/null
+++ b/fedora.dockerfile
@@ -0,0 +1,32 @@
+ARG base_image=fedora-40
+
+FROM docker.io/library/fedora:39@sha256:2922a1237abbb7f8517018e4f5d7a82a618f6ec09f386799e8595f9e1c39f021 AS fedora-39
+FROM docker.io/library/fedora:40@sha256:5ce8497aeea599bf6b54ab3979133923d82aaa4f6ca5ced1812611b197c79eb0 AS fedora-40
+
+FROM ${base_image}
+
+RUN dnf install -y --nodocs --setopt install_weak_deps=False \
+ gnome-session-xsession \
+ gnome-extensions-app \
+ gjs \
+ gdm \
+ vte291 \
+ vte291-gtk4 \
+ xorg-x11-server-Xvfb \
+ mesa-dri-drivers \
+ wl-clipboard \
+ PackageKit \
+ PackageKit-glib \
+ libhandy \
+ && dnf clean all -y
+
+COPY data /
+
+RUN systemctl set-default multi-user.target && \
+ systemctl mask systemd-oomd low-memory-monitor rtkit-daemon udisks2 && \
+ adduser -m -U -G users,adm gnomeshell && \
+ chmod u+rw /etc/shadow && \
+ truncate --size 0 /etc/machine-id && \
+ dconf update
+
+CMD [ "/sbin/init" ]
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..a54b838
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [
+ "config:recommended",
+ ":maintainLockFilesWeekly",
+ "npm:unpublishSafe"
+ ],
+ "packageRules": [
+ {
+ "matchCategories": [
+ "docker"
+ ],
+ "pinDigests": true
+ },
+ {
+ "matchPackagePatterns": [
+ "opensuse/tumbleweed$"
+ ],
+ "extends": [
+ "schedule:automergeWeekly"
+ ]
+ },
+ {
+ "excludePackagePatterns": [
+ "opensuse/tumbleweed$"
+ ],
+ "extends": [
+ "schedule:automergeDaily"
+ ]
+ }
+ ],
+ "dockerfile": {
+ "fileMatch": [
+ "(^|/|\\.)dockerfile$"
+ ],
+ "major": {
+ "enabled": false
+ },
+ "minor": {
+ "enabled": false
+ },
+ "patch": {
+ "enabled": false
+ },
+ "groupName": "Base images"
+ },
+ "automerge": true,
+ "customManagers": [
+ {
+ "customType": "regex",
+ "fileMatch": [
+ "^\\.github/workflows/.+\\.ya?ml"
+ ],
+ "matchStrings": [
+ "#\\s*renovate:\\s+datasource=(?[^\\s]+)\\s+depName=(?[^\\s]+)(\\s+(lookupName|packageName)=(?[^\\s]+))?(\\s+versioning=(?[^\\s]+))?\\n\\s*\\w+\\s*:\\s*[\"']?(?[^\\s\"']+)[\"']?(\\s|$)"
+ ]
+ }
+ ]
+}
diff --git a/suse.dockerfile b/suse.dockerfile
new file mode 100644
index 0000000..b9190d0
--- /dev/null
+++ b/suse.dockerfile
@@ -0,0 +1,32 @@
+ARG base_image=opensuse-tumbleweed
+
+FROM docker.io/opensuse/tumbleweed:latest@sha256:cef34da5c8f8c68d551054f1e1d3d5c5d3adf01684e925db6cccd448342954f9 AS opensuse-tumbleweed
+FROM docker.io/opensuse/leap:15.6@sha256:b92aba5f8413624d1a4b671dff4858e454fcbe5e38dff1880cc48241750c2e8e AS opensuse-leap-15.6
+
+FROM ${base_image}
+
+RUN zypper --non-interactive install --no-recommends \
+ systemd-sysvinit \
+ xorg-x11-server-Xvfb \
+ gjs \
+ gdm \
+ gnome-session-wayland \
+ gnome-extensions \
+ gtk3-metatheme-adwaita \
+ typelib-1_0-Vte-2.91 \
+ typelib-1_0-Vte-3_91 \
+ PackageKit \
+ typelib-1_0-PackageKitGlib-1_0 \
+ typelib-1_0-Handy-1_0 \
+ wl-clipboard \
+ && zypper clean --all
+
+COPY data /
+
+RUN systemctl set-default multi-user.target && \
+ systemctl mask systemd-oomd low-memory-monitor rtkit-daemon udisks2 && \
+ useradd -m -U -G users gnomeshell && \
+ truncate --size 0 /etc/machine-id && \
+ dconf update
+
+CMD [ "/sbin/init" ]
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..b44ef38
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1 @@
+/*.png
diff --git a/test/test-wayland.sh b/test/test-wayland.sh
new file mode 100755
index 0000000..1b218fd
--- /dev/null
+++ b/test/test-wayland.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+
+if [[ $# != 1 ]]; then
+ echo "Usage: $0 image-name" >&2
+ exit 1
+fi
+
+SCRIPT_DIR=$(CDPATH="" cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
+
+function shutdown {
+ podman exec "$CID" systemctl list-units --failed || true
+ podman rm -f "$CID"
+}
+
+SHARED_DIR="$(mktemp -d)"
+
+ENV_VARS=(
+ "XDG_RUNTIME_DIR=${SHARED_DIR}/runtime"
+ "XDG_CONFIG_HOME=${SHARED_DIR}/config"
+ "XDG_CACHE_HOME=${SHARED_DIR}/cache"
+ "XDG_STATE_HOME=${SHARED_DIR}/state"
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=${SHARED_DIR}/runtime/bus"
+ "NO_AT_BRIDGE=1"
+ "GTK_A11Y=none"
+)
+
+mkdir -p "${SHARED_DIR}/runtime" "${SHARED_DIR}/config" "${SHARED_DIR}/cache" "${SHARED_DIR}/state"
+chmod 0700 "${SHARED_DIR}/runtime" "${SHARED_DIR}/config" "${SHARED_DIR}/cache" "${SHARED_DIR}/state"
+
+set -ex
+
+CAPS="SYS_ADMIN,SYS_NICE,SYS_PTRACE,SETPCAP,NET_RAW,NET_BIND_SERVICE,IPC_LOCK"
+CID="$(podman create --log-driver=none --tty --cap-add="$CAPS" --security-opt=label=disable --user=0 --userns=keep-id:uid=1000,gid=1000 -v "$SHARED_DIR:$SHARED_DIR" "$1")"
+
+trap shutdown EXIT
+
+podman start --attach --sig-proxy=false "$CID" &
+podman wait --condition=running "$CID"
+podman exec "$CID" busctl --watch-bind=true status
+podman exec "$CID" systemctl is-system-running --wait
+
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" dbus-daemon --session --nopidfile --syslog --fork "--address=unix:path=${SHARED_DIR}/runtime/bus"
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" busctl --user --watch-bind=true status
+env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Peer.Ping
+
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" gnome-shell --wayland --headless --sm-disable --unsafe-mode --virtual-monitor 1600x960 &
+
+while ! env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep '"org.gnome.Shell.Screenshot"'
+do
+ sleep 1
+done
+
+while env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.gnome.Shell /org/gnome/Shell org.gnome.Shell.Eval 'string:Main.layoutManager._startingUp' | grep 'string "true"'
+do
+ sleep 1
+done
+
+env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.gnome.Shell.Screenshot /org/gnome/Shell/Screenshot org.gnome.Shell.Screenshot.Screenshot 'boolean:true' 'boolean:false' "string:${SHARED_DIR}/screenshot-wayland.png"
+cp "${SHARED_DIR}/screenshot-wayland.png" "${SCRIPT_DIR}/"
diff --git a/test/test-x11.sh b/test/test-x11.sh
new file mode 100755
index 0000000..40b5efd
--- /dev/null
+++ b/test/test-x11.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+if [[ $# != 1 ]]; then
+ echo "Usage: $0 image-name" >&2
+ exit 1
+fi
+
+SCRIPT_DIR=$(CDPATH="" cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
+
+function shutdown {
+ podman exec "$CID" systemctl list-units --failed || true
+ podman rm -f "$CID"
+}
+
+SHARED_DIR="$(mktemp -d)"
+
+ENV_VARS=(
+ "XDG_RUNTIME_DIR=${SHARED_DIR}/runtime"
+ "XDG_CONFIG_HOME=${SHARED_DIR}/config"
+ "XDG_CACHE_HOME=${SHARED_DIR}/cache"
+ "XDG_STATE_HOME=${SHARED_DIR}/state"
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=${SHARED_DIR}/runtime/bus"
+ "NO_AT_BRIDGE=1"
+ "GTK_A11Y=none"
+ "DISPLAY=:99"
+)
+
+mkdir -p "${SHARED_DIR}/runtime" "${SHARED_DIR}/config" "${SHARED_DIR}/cache" "${SHARED_DIR}/state"
+chmod 0700 "${SHARED_DIR}/runtime" "${SHARED_DIR}/config" "${SHARED_DIR}/cache" "${SHARED_DIR}/state"
+
+set -ex
+
+CAPS="SYS_ADMIN,SYS_NICE,SYS_PTRACE,SETPCAP,NET_RAW,NET_BIND_SERVICE,IPC_LOCK"
+CID="$(podman create --log-driver=none --tty --cap-add="$CAPS" --security-opt=label=disable --user=0 --userns=keep-id:uid=1000,gid=1000 -v "$SHARED_DIR:$SHARED_DIR" "$1")"
+
+trap shutdown EXIT
+
+podman start --attach --sig-proxy=false "$CID" &
+podman wait --condition=running "$CID"
+podman exec "$CID" busctl --watch-bind=true status
+podman exec "$CID" systemctl is-system-running --wait
+
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" dbus-daemon --session --nopidfile --syslog --fork "--address=unix:path=${SHARED_DIR}/runtime/bus"
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" busctl --user --watch-bind=true status
+env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Peer.Ping
+
+mkfifo "${SHARED_DIR}/display_pipe"
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" bash -c "Xvfb -screen 0 1600x960x24 -nolisten tcp -displayfd 3 :99 3>'${SHARED_DIR}/display_pipe'" &
+
+read -r DISPLAY_NUMBER <"${SHARED_DIR}/display_pipe"
+test ":$DISPLAY_NUMBER" = ":99"
+
+podman exec --user=1000 "${ENV_VARS[@]/#/--env=}" "$CID" gnome-shell --x11 --sm-disable --unsafe-mode &
+
+while ! env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep '"org.gnome.Shell.Screenshot"'
+do
+ sleep 1
+done
+
+while env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.gnome.Shell /org/gnome/Shell org.gnome.Shell.Eval 'string:Main.layoutManager._startingUp' | grep 'string "true"'
+do
+ sleep 1
+done
+
+env "${ENV_VARS[@]}" dbus-send --session --print-reply --dest=org.gnome.Shell.Screenshot /org/gnome/Shell/Screenshot org.gnome.Shell.Screenshot.Screenshot 'boolean:true' 'boolean:false' "string:${SHARED_DIR}/screenshot-x11.png"
+cp "${SHARED_DIR}/screenshot-x11.png" "${SCRIPT_DIR}/"