wemeet: fix Wayland crash caused by XSetInputFocus (#459399)
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