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"); +}