From d57d9359eef97be19596e4c67d1e7802f1fd18cb Mon Sep 17 00:00:00 2001 From: Dzming Li Date: Fri, 7 Nov 2025 16:01:35 +0800 Subject: [PATCH] wemeet: fix Wayland crash caused by XSetInputFocus The wemeet application crashes with SIGSEGV when running in pure Wayland mode. The crash occurs when the application calls XSetInputFocus() during audio device initialization, which fails because there is no valid X11 display connection in native Wayland. This patch adds a small LD_PRELOAD library that intercepts XSetInputFocus() calls in Wayland sessions and safely returns success without calling the actual X11 function. --- pkgs/by-name/we/wemeet/package.nix | 43 +++++++++++++++++++- pkgs/by-name/we/wemeet/wemeet-x11-fix.c | 54 +++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 pkgs/by-name/we/wemeet/wemeet-x11-fix.c diff --git a/pkgs/by-name/we/wemeet/package.nix b/pkgs/by-name/we/wemeet/package.nix index e7122a299b35..ab9a0f0d3084 100644 --- a/pkgs/by-name/we/wemeet/package.nix +++ b/pkgs/by-name/we/wemeet/package.nix @@ -126,6 +126,47 @@ let meta.license = lib.licenses.unfree; }; + + # Fix for Wayland crash when XSetInputFocus is called + wemeet-x11-fix = stdenv.mkDerivation { + pname = "wemeet-x11-fix"; + version = "0-unstable-2025-11-07"; + + src = ./wemeet-x11-fix.c; + + dontUnpack = true; + dontWrapQtApps = true; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ + xorg.libX11 + ]; + + buildPhase = '' + runHook preBuild + + $CC $CFLAGS -Wall -Wextra -fPIC -shared \ + -o libwemeet-x11-fix.so $src \ + -ldl -lX11 + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + install -Dm755 ./libwemeet-x11-fix.so $out/lib/libwemeet-x11-fix.so + + runHook postInstall + ''; + + meta = { + description = "Fix for wemeet Wayland XSetInputFocus crash"; + license = lib.licenses.mit; + }; + }; + selectSystem = attrs: attrs.${stdenv.hostPlatform.system} @@ -237,7 +278,7 @@ stdenv.mkDerivation { "--prefix QT_PLUGIN_PATH : $out/app/wemeet/plugins" ]; commonWrapperArgs = baseWrapperArgs ++ [ - "--prefix LD_PRELOAD : ${libwemeetwrap}/lib/libwemeetwrap.so" + "--prefix LD_PRELOAD : ${libwemeetwrap}/lib/libwemeetwrap.so:${wemeet-x11-fix}/lib/libwemeet-x11-fix.so" "--run 'if [[ $XDG_SESSION_TYPE == \"wayland\" ]]; then export LD_PRELOAD=${wemeet-wayland-screenshare}/lib/wemeet/libhook.so\${LD_PRELOAD:+:$LD_PRELOAD}; fi'" ]; xwaylandWrapperArgs = baseWrapperArgs ++ [ diff --git a/pkgs/by-name/we/wemeet/wemeet-x11-fix.c b/pkgs/by-name/we/wemeet/wemeet-x11-fix.c new file mode 100644 index 000000000000..8b53c4e39fcb --- /dev/null +++ b/pkgs/by-name/we/wemeet/wemeet-x11-fix.c @@ -0,0 +1,54 @@ +/* + * wemeet-x11-fix.c + * + * This library intercepts X11 functions that cause crashes in Wayland mode. + * Specifically, it prevents XSetInputFocus from crashing when called in + * pure Wayland environment. + * + * Compile: gcc -shared -fPIC -o libwemeet-x11-fix.so wemeet-x11-fix.c -ldl + * Usage: LD_PRELOAD=./libwemeet-x11-fix.so wemeet + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +// Original XSetInputFocus function pointer +static int (*orig_XSetInputFocus)(Display*, Window, int, Time) = NULL; + +// Hooked XSetInputFocus that safely handles Wayland environment +int XSetInputFocus(Display *display, Window focus, int revert_to, Time time) { + // Check if we're in a Wayland session + const char *session_type = getenv("XDG_SESSION_TYPE"); + const char *wayland_display = getenv("WAYLAND_DISPLAY"); + + if ((session_type && strcmp(session_type, "wayland") == 0) || wayland_display) { + // In pure Wayland, XSetInputFocus can crash due to invalid X11 display + // Just return success and skip the actual call + fprintf(stderr, "wemeet-x11-fix: Blocking XSetInputFocus in Wayland mode\n"); + return Success; + } + + // Load original function if not already loaded + if (!orig_XSetInputFocus) { + orig_XSetInputFocus = dlsym(RTLD_NEXT, "XSetInputFocus"); + if (!orig_XSetInputFocus) { + fprintf(stderr, "wemeet-x11-fix: Failed to load XSetInputFocus\n"); + return BadWindow; + } + } + + // Call original function in X11 mode + return orig_XSetInputFocus(display, focus, revert_to, time); +} + +// Also intercept _XGetRequest to add error handling +static Status (*orig_XGetRequest)(Display*, _Xconst char*, size_t, int) = NULL; + +__attribute__((constructor)) +static void init_x11_fix(void) { + fprintf(stderr, "wemeet-x11-fix: Loaded X11 compatibility fix for Wayland\n"); +}