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.
This commit is contained in:
@@ -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 ++ [
|
||||
|
||||
@@ -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 <dlfcn.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// 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");
|
||||
}
|
||||
Reference in New Issue
Block a user