From bcab5d15187e193388e98df8d66af24ec8f8c632 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sat, 10 Nov 2018 21:52:42 +0000 Subject: [PATCH] Workaround the incompatibility between DRI2 and xcb When using DRI2, Mesa uses XESetWireToEvent to hook into Xlib's event handling loop, so it can get notified when certain DRI2 event happens, which is crucial to the normal functioning of GLX. When xcb is owning the event queue (meaning libxcb is doing all the event handling), those functions registered by Mesa will never be called, thus GLX will malfunction, leading to screen flickers or visual artifacts. This commit uses a hack from Qt to manually call those functions in compton. Signed-off-by: Yuxuan Shui --- src/compton.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/compton.c b/src/compton.c index 13cf52e..4ff426c 100644 --- a/src/compton.c +++ b/src/compton.c @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -28,6 +30,8 @@ #include "config.h" #include "diagnostic.h" +#define auto __auto_type + static void finish_destroy_win(session_t *ps, win **_w); @@ -3236,6 +3240,28 @@ ev_handle(session_t *ps, xcb_generic_event_t *ev) { } #endif + // Check if a custom XEvent constructor was registered in xlib for this event + // type, and call it discarding the constructed XEvent if any. XESetWireToEvent + // might be used by libraries to intercept messages from the X server e.g. the + // OpenGL lib waiting for DRI2 events. + + // XXX This exists to workaround compton issue #33, #34, #47 + // For even more details, see: + // https://bugs.freedesktop.org/show_bug.cgi?id=35945 + // https://lists.freedesktop.org/archives/xcb/2011-November/007337.html + auto proc = XESetWireToEvent(ps->dpy, ev->response_type, 0); + if (proc) { + XESetWireToEvent(ps->dpy, ev->response_type, proc); + XEvent dummy; + + // Stop Xlib from complaining about lost sequence numbers. + // proc might also just be Xlib internal event processing functions, and + // because they probably won't see all X replies, they will complain about + // missing sequence numbers. + ev->sequence = LastKnownRequestProcessed(ps->dpy); + proc(ps->dpy, &dummy, (xEvent *)ev); + } + // XXX redraw needs to be more fine grained queue_redraw(ps);