wemeet: fix Wayland crash caused by XSetInputFocus (#459399)

This commit is contained in:
Aleksana
2025-11-26 12:07:16 +00:00
committed by GitHub
2 changed files with 96 additions and 1 deletions
+42 -1
View File
@@ -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 ++ [
+54
View File
@@ -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");
}