Unverified Commit 660a9c0a authored by Weijia Wang's avatar Weijia Wang Committed by GitHub
Browse files

Merge pull request #228272 from quentinmit/xquartz

xquartz, xorg.xorgserver: Fix broken xquartz package
parents 42ef3dd2 65601cbb
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
This patch makes it possible (and necessary) to specify the default
shell, xterm client, and startx script from environment variables. These
defaults are used when launching the XQuartz.app, which in turn needs to know
how to start the X server. `startx' comes from the `xinit' package,
which also has a dependency on `xorg-server', so we can't hardcode
sane defaults. If the environment variables are specified, they
override any value in the preferences settings.

When developing an installable package for XQuartz/XQuartz.app, we'll
need to set an `LSEnvironment' entry in the plist for the XQuartz.app.
(See stub.patch for more details.).

diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index de82e2280..da58a5d44 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -76,8 +76,6 @@ extern int noPanoramiXExtension;
 extern Bool noCompositeExtension;
 #endif
 
-#define DEFAULT_CLIENT X11BINDIR "/xterm"
-#define DEFAULT_STARTX X11BINDIR "/startx -- " X11BINDIR "/Xquartz"
 #define DEFAULT_SHELL  "/bin/sh"
 
 #define _STRINGIZE(s) #s
@@ -108,7 +106,7 @@ server_main(int argc, char **argv, char **envp);
 static int
 execute(const char *command);
 static char *
-command_from_prefs(const char *key, const char *default_value);
+command_from_prefs(const char *key, const char *env_name, const char *default_value);
 
 static char *pref_app_to_run;
 static char *pref_login_shell;
@@ -669,14 +667,19 @@ main(int argc, char **argv, char **envp)
         pid_t child1, child2;
         int status;
 
-        pref_app_to_run = command_from_prefs("app_to_run", DEFAULT_CLIENT);
+        pref_app_to_run = command_from_prefs("app_to_run",
+                                             "XQUARTZ_DEFAULT_CLIENT",
+                                             NULL);
         assert(pref_app_to_run);
 
-        pref_login_shell = command_from_prefs("login_shell", DEFAULT_SHELL);
+        pref_login_shell = command_from_prefs("login_shell",
+                                              "XQUARTZ_DEFAULT_SHELL",
+                                              DEFAULT_SHELL);
         assert(pref_login_shell);
 
         pref_startx_script = command_from_prefs("startx_script",
-                                                DEFAULT_STARTX);
+                                                "XQUARTZ_DEFAULT_STARTX",
+                                                NULL);
         assert(pref_startx_script);
 
         /* Do the fork-twice trick to avoid having to reap zombies */
@@ -753,7 +756,7 @@ execute(const char *command)
 }
 
 static char *
-command_from_prefs(const char *key, const char *default_value)
+command_from_prefs(const char *key, const char *env_name, const char *default_value)
 {
     char *command = NULL;
 
@@ -763,6 +766,17 @@ command_from_prefs(const char *key, const char *default_value)
     if (!key)
         return NULL;
 
+    if (env_name != NULL) {
+        command = getenv(env_name);
+        if (command != NULL) {
+            return strdup(command);
+        }
+    }
+
+    if (!default_value) {
+        return NULL;
+    }
+
     cfKey = CFStringCreateWithCString(NULL, key, kCFStringEncodingASCII);
 
     if (!cfKey)
+61 −0
Original line number Diff line number Diff line
When the X / Xquartz server initializes, it starts the XQuartz.app and
hands-off the display FD. To start the XQuartz.app, Xquartz normally uses some
system calls to get the path of the application by app bundle id, and then
executes the Contents/MacOS/X11 script contained inside, which in turn executes
Contents/MacOS/X11.bin (the actual app).

This patch replaces that discovery technique with a simple call to
`getenv' and a hardcoded default. In order to make Xquartz work if the
app is moved, we'll need another wrapper that sets the `XQUARTZ_X11'
environment variable to point to the `X11' script.

diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index 83252e805..f1974215b 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -52,7 +52,6 @@
 
 #include "launchd_fd.h"
 
-static CFURLRef x11appURL;
 static FSRef x11_appRef;
 static pid_t x11app_pid = 0;
 aslclient aslc;
@@ -60,29 +59,21 @@ aslclient aslc;
 static void
 set_x11_path(void)
 {
-    OSStatus osstatus = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(kX11AppBundleId),
-                                                 nil, &x11_appRef, &x11appURL);
+    unsigned char *xquartzApp = getenv("XQUARTZ_APP");
+    if (!xquartzApp) {
+        xquartzApp = "@XQUARTZ_APP@";
+    }
+
+    OSStatus osstatus = FSPathMakeRef(xquartzApp, &x11_appRef, NULL);
 
     switch (osstatus) {
     case noErr:
-        if (x11appURL == NULL) {
-            asl_log(aslc, NULL, ASL_LEVEL_ERR,
-                    "Xquartz: Invalid response from LSFindApplicationForInfo(%s)",
-                    kX11AppBundleId);
-            exit(1);
-        }
         break;
 
-    case kLSApplicationNotFoundErr:
-        asl_log(aslc, NULL, ASL_LEVEL_ERR,
-                "Xquartz: Unable to find application for %s",
-                kX11AppBundleId);
-        exit(10);
-
     default:
         asl_log(aslc, NULL, ASL_LEVEL_ERR,
-                "Xquartz: Unable to find application for %s, error code = %d",
-                kX11AppBundleId, (int)osstatus);
+                "Xquartz: Unable to find FSRef for %s, error code = %d",
+                xquartzApp, (int)osstatus);
         exit(11);
     }
 }
+9 −1
Original line number Diff line number Diff line
{ abiCompat ? null,
  callPackage,
  lib, stdenv, makeWrapper, fetchurl, fetchpatch, fetchFromGitLab, buildPackages,
  lib, stdenv, makeWrapper, fetchurl, fetchpatch, fetchFromGitLab, buildPackages, substitute,
  automake, autoconf, libiconv, libtool, intltool,
  freetype, tradcpp, fontconfig, meson, ninja, ed, fontforge,
  libGL, spice-protocol, zlib, libGLU, dbus, libunwind, libdrm, netbsd,
@@ -763,6 +763,11 @@ self: super:
            sha256 = "0zm9g0g1jvy79sgkvy0rjm6ywrdba2xjd1nsnjbxjccckbr6i396";
            name = "revert-fb-changes-2.patch";
          })
          ./darwin/bundle_main.patch
          (substitute {
            src = ./darwin/stub.patch;
            replacements = ["--subst-var-by" "XQUARTZ_APP" "${placeholder "out"}/Applications/XQuartz.app"];
          })
        ];

        configureFlags = [
@@ -774,6 +779,9 @@ self: super:
          "--with-apple-applications-dir=\${out}/Applications"
          "--with-bundle-id-prefix=org.nixos.xquartz"
          "--with-sha1=CommonCrypto"
          "--with-xkb-bin-directory=${xorg.xkbcomp}/bin"
          "--with-xkb-path=${xorg.xkeyboardconfig}/share/X11/xkb"
          "--with-xkb-output=$out/share/X11/xkb/compiled"
          "--without-dtrace" # requires Command Line Tools for Xcode
        ];
        preConfigure = ''
+7 −0
Original line number Diff line number Diff line
#!@shell@

export PATH=@PATH@:$PATH

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap

# Fix ridiculously slow key repeat.
@XSET@ r rate

# merge in defaults and keymaps

if [ -f "$userresources" ]; then
    if [ -x /usr/bin/cpp ] ; then
        @XRDB@ -merge "$userresources"
    else
        @XRDB@ -nocpp -merge "$userresources"
    fi
fi

if [ -f "$usermodmap" ]; then
    @XMODMAP@ "$usermodmap"
fi

fontpath="@SYSTEM_FONTS@"
[ -e "$HOME"/.fonts/fonts.dir ] && fontpath="$fontpath,$HOME/.fonts"
[ -e "$HOME"/Library/Fonts/fonts.dir ] && fontpath="$fontpath,$HOME/Library/Fonts"
@@ -29,12 +5,3 @@ fontpath="@SYSTEM_FONTS@"
[ -e /System/Library/Fonts/fonts.dir ] && fontpath="$fontpath,/System/Library/Fonts"
@XSET@ fp= "$fontpath"
unset fontpath

if [ -d "${HOME}/.xinitrc.d" ] ; then
    for f in "${HOME}"/.xinitrc.d/*.sh ; do
        [ -x "$f" ] && . "$f"
    done
    unset f
fi

exec @QUARTZ_WM@
+6 −0
Original line number Diff line number Diff line
if [ -d "${HOME}/.xinitrc.d" ] ; then
    for f in "${HOME}"/.xinitrc.d/*.sh ; do
        [ -x "$f" ] && . "$f"
    done
    unset f
fi
Loading