diff mbox series

[4/4] sandbox: Add support for Wayland

Message ID 20240514105651.225925-4-lautrbach@redhat.com (mailing list archive)
State Accepted
Commit 2c9007f2275a
Delegated to: Petr Lautrbach
Headers show
Series [1/4] sandbox: do not fail without xmodmap | expand

Commit Message

Petr Lautrbach May 14, 2024, 10:56 a.m. UTC
- use XWayland for X application if it's run in Wayland session
- run Wayland apps directly if it's run in Wayland session
- add sandbox -Y option to run run Wayland application

Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
---
 sandbox/sandbox     | 26 ++++++++++++++++++++++++--
 sandbox/sandboxX.sh | 36 ++++++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/sandbox/sandbox b/sandbox/sandbox
index 1e96f93e4a92..e3fd6119ed4d 100644
--- a/sandbox/sandbox
+++ b/sandbox/sandbox
@@ -344,6 +344,10 @@  sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
                           action="callback", callback=self.__x_callback,
                           default=False, help=_("run X application within a sandbox"))
 
+        parser.add_option("-Y", dest="Y_ind",
+                          action="callback", callback=self.__x_callback,
+                          default=False, help=_("run Wayland application within a sandbox"))
+
         parser.add_option("-H", "--homedir",
                           action="callback", callback=self.__validdir,
                           type="string",
@@ -457,6 +461,16 @@  sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
         selinux.chcon(self.__runuserdir, self.__filecon, recursive=True)
         selinux.setfscreatecon(None)
 
+    def __is_wayland_app(self):
+        binary = shutil.which(self.__paths[0])
+        if binary is None:
+            return True
+        output = subprocess.run(['ldd', binary], capture_output=True)
+        for line in str(output.stdout, "utf-8").split('\n'):
+            if line.find("libwayland") != -1:
+                return True
+        return False
+
     def __execute(self):
         try:
             cmds = [SEUNSHARE, "-Z", self.__execcon]
@@ -465,7 +479,7 @@  sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
             if self.__mount:
                 cmds += ["-t", self.__tmpdir, "-h", self.__homedir, "-r", self.__runuserdir]
 
-                if self.__options.X_ind:
+                if self.__options.X_ind or self.__options.Y_ind:
                     if self.__options.dpi:
                         dpi = self.__options.dpi
                     else:
@@ -474,6 +488,9 @@  sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
                         from gi.repository import Gtk
                         dpi = str(Gtk.Settings.get_default().props.gtk_xft_dpi / 1024)
 
+                    if os.environ.get('WAYLAND_DISPLAY') is not None:
+                        cmds += ["-W", os.environ["WAYLAND_DISPLAY"]]
+
                     xmodmapfile = self.__homedir + "/.xmodmap"
                     xd = open(xmodmapfile, "w")
                     try:
@@ -484,7 +501,12 @@  sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
 
                     self.__setup_sandboxrc(self.__options.wm)
 
-                    cmds += ["--", SANDBOXSH, self.__options.windowsize, dpi]
+                    if self.__options.Y_ind or self.__is_wayland_app():
+                        WN = "yes"
+                    else:
+                        WN = "no"
+
+                    cmds += ["--", SANDBOXSH, WN, self.__options.windowsize, dpi]
                 else:
                     cmds += ["--"] + self.__paths
                 return subprocess.Popen(cmds).wait()
diff --git a/sandbox/sandboxX.sh b/sandbox/sandboxX.sh
index eaa500d08143..28169182ce42 100644
--- a/sandbox/sandboxX.sh
+++ b/sandbox/sandboxX.sh
@@ -2,8 +2,9 @@ 
 trap "" TERM
 context=`id -Z | secon -t -l -P`
 export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80`"
-[ -z $1 ] && export SCREENSIZE="1000x700" || export SCREENSIZE="$1"
-[ -z $2 ] && export DPI="96" || export DPI="$2"
+[ -z $1 ] && export WAYLAND_NATIVE="no" || export WAYLAND_NATIVE="$1"
+[ -z $2 ] && export SCREENSIZE="1000x700" || export SCREENSIZE="$2"
+[ -z $3 ] && export DPI="96" || export DPI="$3"
 trap "exit 0" HUP
 
 mkdir -p ~/.config/openbox
@@ -20,16 +21,27 @@  cat > ~/.config/openbox/rc.xml << EOF
 </openbox_config>
 EOF
 
-(/usr/bin/Xephyr -resizeable -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do
-    export DISPLAY=:$D
-    cat > ~/seremote << __EOF
-#!/bin/sh
-DISPLAY=$DISPLAY "\$@"
+if [ "$WAYLAND_NATIVE" == "no" ]; then
+    if [ -z "$WAYLAND_DISPLAY" ]; then
+        DISPLAY_COMMAND='/usr/bin/Xephyr -resizeable -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null'
+    else
+        DISPLAY_COMMAND='/usr/bin/Xwayland -terminate -dpi $DPI -retro -geometry $SCREENSIZE -decorate -displayfd 5 5>&1 2>/dev/null'
+    fi
+    eval $DISPLAY_COMMAND | while read D; do
+        export DISPLAY=:$D
+        cat > ~/seremote << __EOF
+#!/bin/bash -x
+export DISPLAY=$DISPLAY
+export WAYLAND_DISPLAY=$WAYLAND_DISPLAY
+"\$@"
 __EOF
-    chmod +x ~/seremote
+        chmod +x ~/seremote
+        /usr/share/sandbox/start $HOME/.sandboxrc
+        export EXITCODE=$?
+        kill -TERM 0
+        break
+    done
+else
     /usr/share/sandbox/start $HOME/.sandboxrc
-    export EXITCODE=$?
-    kill -TERM 0
-    break
-done
+fi
 exit 0