While experimenting with SDL 3 and poking its pre-init simple GUI message box support, I found out that version 3.4.8, rather than doing the simplistic X thing that I remember it doing before, invokes Zenity on my Arch Linux system. (A skim of the SDL source code suggests that if there's no Zenity, it still falls back to legacy X primitives on X, but fails completely on Wayland.) Seems basically reasonable, right?
Unfortunately, Zenity 4.2.2 on this (somewhat old) machine has a bit of an issue with startup time:
% time zenity --error --title="Oops" --text="Uh oh." # zenity --error --title="Oops" --text="Uh oh.": user=1195ms sys=152ms wall=3040ms mem=115k
That's a full second of CPU time just to show a dialog box, and it does feel like about that long of a delay between hitting Return and seeing the message on the screen. Definitely an interactive flow killer. Let's also see what ldd says about what it's loading:
% ldd /usr/bin/zenity |cut -d' ' -f1 linux-vdso.so.1 libadwaita-1.so.0 libgtk-4.so.1 libpango-1.0.so.0 libgio-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 libgcc_s.so.1 libc.so.6 libfribidi.so.0 libgraphene-1.0.so.0 libappstream.so.5 libm.so.6 libgmodule-2.0.so.0 libpangocairo-1.0.so.0 libcairo.so.2 libharfbuzz.so.0 libharfbuzz-subset.so.0 libcairo-gobject.so.2 libfontconfig.so.1 libgdk_pixbuf-2.0.so.0 libepoxy.so.0 libgstplay-1.0.so.0 libgstvideo-1.0.so.0 libgstreamer-1.0.so.0 libgstgl-1.0.so.0 libgstallocators-1.0.so.0 libXi.so.6 libX11.so.6 libpangoft2-1.0.so.0 libcloudproviders.so.0 libtinysparql-3.0.so.0 libvulkan.so.1 libpng16.so.16 libtiff.so.6 libjpeg.so.8 libxkbcommon.so.0 libwayland-client.so.0 libwayland-egl.so.1 libXext.so.6 libXcursor.so.1 libXdamage.so.1 libXfixes.so.3 libXrandr.so.2 libXinerama.so.1 libcairo-script-interpreter.so.2 libcups.so.2 libcolord.so.2 libthai.so.0 libz.so.1 libmount.so.1 libffi.so.8 libpcre2-8.so.0 /lib64/ld-linux-x86-64.so.2 libcurl.so.4 libxmlb.so.2 libxml2.so.16 libfyaml.so.0 libsystemd.so.0 libzstd.so.1 libstemmer.so.0 libfreetype.so.6 libXrender.so.1 libxcb.so.1 libxcb-render.so.0 libxcb-shm.so.0 libpixman-1.so.0 libgraphite2.so.3 libexpat.so.1 libglycin-2.so.0 libgsttag-1.0.so.0 libgstpbutils-1.0.so.0 libgstbase-1.0.so.0 liborc-0.4.so.0 libunwind.so.8 libdw.so.1 libEGL.so.1 libGLX.so.0 libwayland-cursor.so.0 libX11-xcb.so.1 libgudev-1.0.so.0 libdrm.so.2 libgbm.so.1 libjson-glib-1.0.so.0 libsqlite3.so.0 libdeflate.so.0 libjbig.so.2.1 liblzma.so.5 libwebp.so.7 liblzo2.so.2 libavahi-common.so.3 libavahi-client.so.3 libgnutls.so.30 liblcms2.so.2 libudev.so.1 libdatrie.so.1 libblkid.so.1 libnghttp3.so.9 libngtcp2_crypto_ossl.so.0 libngtcp2.so.16 libnghttp2.so.14 libidn2.so.0 libssh2.so.1 libpsl.so.5 libssl.so.3 libcrypto.so.3 libgssapi_krb5.so.2 libbrotlidec.so.1 libicuuc.so.78 libbz2.so.1.0 libXau.so.6 libXdmcp.so.6 libseccomp.so.2 libgstaudio-1.0.so.0 libelf.so.1 libGLdispatch.so.0 libsharpyuv.so.0 libdbus-1.so.3 libleancrypto.so.1 libp11-kit.so.0 libunistring.so.5 libtasn1.so.6 libhogweed.so.7 libnettle.so.9 libgmp.so.10 libbrotlienc.so.1 libkrb5.so.3 libk5crypto.so.3 libcom_err.so.2 libkrb5support.so.0 libkeyutils.so.1 libresolv.so.2 libbrotlicommon.so.1 libicudata.so.78 libstdc++.so.6
wc -l says that's 135 mappings. This is easy to overinterpret—code being mapped into memory doesn't mean it's doing anything other than more-or-less cheaply sitting there just in case, and timing zenity --help confirms that the initial CPU suck isn't coming from the dynamic loader—but it's a decent enough proxy metric for exploding coordination and integration complexity that it still makes me cringe some.
Running it under strace -f shows 43 underlying clone calls and two separate execs of bwrap along with an exec of glycin-svg… I assume the sandboxing is for the SVG loader, so is that being used to display the error icon? It doesn't happen if I run zenity --text-info instead, which doesn't use an icon, though the overall CPU usage remains similar, so that's not the bottleneck.
I briefly tried running it under ltrace, but it either dumped core or didn't produce any trace output depending on what filters I set; I assume it doesn't have enough information to reconstruct the library calls here.
Out of curiosity, I also tried timing Yad, which describes itself as a fork of Zenity and which notably seems to use GTK+ 3 instead of GTK+ 4. With Yad, the user CPU time for a basic dialog looks closer to 200 ms, which still feels a little iffy but is overall much more reasonable. Funnily (though not unexpectedly), the ldd output is 146 lines and strace shows 66 clone calls—but something somewhere in that stack is much more efficient.
I guess it makes sense to expect Zenity to be more mainline in availability than one of its forks, in an XDG-ish environment… that said, looking at the source for SDL_Zenity_ShowMessageBox, I also see:
/* https://gitlab.gnome.org/GNOME/zenity/-/commit/c686bdb1b45e95acf010efd9ca0c75527fbb4dea * This commit removed --icon-name without adding a deprecation notice. * We need to handle it gracefully, otherwise no message box will be shown. */
(The commit in question is from 2022, and a skim of the diff does say it changed "icon-name" to "icon" in a few key places.)
Hmm. Bleh. Gee, I dunno. I don't think I'm going to go further down this rabbit hole today, but this is all making me kind of sad.