From 8c7b955bc9ef146742efe3c30570e01ecc18a78a Mon Sep 17 00:00:00 2001 From: Be Date: Wed, 28 Nov 2018 10:39:52 -0600 Subject: [PATCH 1/6] hack around Xlib deadlock adapted code from https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25#note_17248 https://bugs.launchpad.net/mixxx/+bug/1805559 --- build/depends.py | 3 +++ src/mixxx.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/build/depends.py b/build/depends.py index 3760046aac30..31afc68b85b0 100644 --- a/build/depends.py +++ b/build/depends.py @@ -245,7 +245,10 @@ def enabled_modules(build): 'QtTest', 'QtXml', ] + if qt5: + if build.platform_is_linux: + build.env.Append(LIBS = 'Qt5X11Extras') qt_modules.extend([ # Keep alphabetized. 'QtConcurrent', diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 8fbd31469b7c..929a4ed0fdf7 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -81,10 +81,41 @@ #include "preferences/dialog/dlgprefmodplug.h" #endif +#ifdef Q_OS_LINUX +#include +#include +#include +// Xlibint.h predates C++ and defines macros which conflict +// with references to std::max and std::min +#undef max +#undef min +#endif + namespace { const mixxx::Logger kLogger("MixxxMainWindow"); +// hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25 +// https://bugs.launchpad.net/mixxx/+bug/1805559 +#ifdef Q_OS_LINUX +typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*); + +const int NUM_HANDLERS = 256; +WireToErrorType __oldHandlers[NUM_HANDLERS] = {0}; + +Bool __xErrorHandler(Display* display, XErrorEvent* event, xError* error) { + // Call any previous handler first in case it needs to do real work. + auto code = static_cast(event->error_code); + if (__oldHandlers[code] != NULL) { + __oldHandlers[code](display, event, error); + } + + // Always return false so the error does not get passed to the normal + // application defined handler. + return False; +} +#endif + } // anonymous namespace // static @@ -169,6 +200,12 @@ MixxxMainWindow::~MixxxMainWindow() { void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { ScopedTimer t("MixxxMainWindow::initialize"); +#ifdef Q_OS_LINUX + for (auto i = 0; i < NUM_HANDLERS; ++i) { + XESetWireToError(QX11Info::display(), i, &__xErrorHandler); + } +#endif + UserSettingsPointer pConfig = m_pSettingsManager->settings(); Sandbox::initialize(QDir(pConfig->getSettingsPath()).filePath("sandbox.cfg")); From c82b315f7707e6497342fe602be4c075e1d22f31 Mon Sep 17 00:00:00 2001 From: Be Date: Wed, 28 Nov 2018 15:10:38 -0600 Subject: [PATCH 2/6] only hack around Xlib bug when running as an X client Otherwise calling Xlib functions segfaults when running as a Wayland client --- src/mixxx.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 929a4ed0fdf7..7564cdf036bd 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -201,8 +201,11 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { ScopedTimer t("MixxxMainWindow::initialize"); #ifdef Q_OS_LINUX - for (auto i = 0; i < NUM_HANDLERS; ++i) { - XESetWireToError(QX11Info::display(), i, &__xErrorHandler); + // XESetWireToError will segfault if running as a Wayland client + if (pApp->platformName() == QStringLiteral("xcb")) { + for (auto i = 0; i < NUM_HANDLERS; ++i) { + XESetWireToError(QX11Info::display(), i, &__xErrorHandler); + } } #endif From 8fa52d434184fad4197e5c1e8f70e644ed8fffcd Mon Sep 17 00:00:00 2001 From: Be Date: Thu, 29 Nov 2018 06:19:02 -0600 Subject: [PATCH 3/6] use #if defined rather than #ifdef --- src/mixxx.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 7564cdf036bd..b62e303476b0 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -81,7 +81,7 @@ #include "preferences/dialog/dlgprefmodplug.h" #endif -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) #include #include #include @@ -97,7 +97,7 @@ const mixxx::Logger kLogger("MixxxMainWindow"); // hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25 // https://bugs.launchpad.net/mixxx/+bug/1805559 -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*); const int NUM_HANDLERS = 256; @@ -181,7 +181,7 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) setCentralWidget(m_pWidgetParent); show(); -#if defined(Q_WS_X11) +#if defined(Q_OS_LINUX) // In asynchronous X11, the window will be mapped to screen // some time after being asked to show itself on the screen. extern void qt_x11_wait_for_window_manager(QWidget *mainWin); @@ -200,7 +200,7 @@ MixxxMainWindow::~MixxxMainWindow() { void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { ScopedTimer t("MixxxMainWindow::initialize"); -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) // XESetWireToError will segfault if running as a Wayland client if (pApp->platformName() == QStringLiteral("xcb")) { for (auto i = 0; i < NUM_HANDLERS; ++i) { From d60b2878fee778338def60feb8f8351433e7d00b Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 3 Dec 2018 13:32:29 -0600 Subject: [PATCH 4/6] fix #include --- src/mixxx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index b62e303476b0..4b7b5879835d 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -82,7 +82,7 @@ #endif #if defined(Q_OS_LINUX) -#include +#include #include #include // Xlibint.h predates C++ and defines macros which conflict From bec52033b7808cadea66f41cc341495e57baeecb Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 3 Dec 2018 13:32:39 -0600 Subject: [PATCH 5/6] remove call to qt_x11_wait_for_window_manager This was previously guarded by an #ifdef Q_WS_X11, but switching to Q_OS_LINUX caused a link error: /usr/bin/ld: lin64_build/mixxx.o: in function `MixxxMainWindow::MixxxMainWindow(QApplication*, CmdlineArgs const&)': /home/uk/Projects/Mixxx/mixxx/src/mixxx.cpp:187: undefined reference to `qt_x11_wait_for_window_manager(QWidget*)' It turns out that Q_WS_X11 is no longer defined with Qt5, yet it does not seem that building Mixxx without the call to qt_x11_wait_for_window_manager has caused any issues, so I presume it is safe to remove it now. This was the only place in Mixxx where Q_WS_X11 was referenced. --- src/mixxx.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 4b7b5879835d..eb7eb4334590 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -181,12 +181,6 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) setCentralWidget(m_pWidgetParent); show(); -#if defined(Q_OS_LINUX) - // In asynchronous X11, the window will be mapped to screen - // some time after being asked to show itself on the screen. - extern void qt_x11_wait_for_window_manager(QWidget *mainWin); - qt_x11_wait_for_window_manager(this); -#endif pApp->processEvents(); initialize(pApp, args); From 7e5557ad502b2df61ca22867478a10381d2f0731 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 3 Dec 2018 16:50:06 -0600 Subject: [PATCH 6/6] add libqt5x11extras5-dev to Travis dependencies --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d5fc315e9c27..fee31289277c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ addons: - protobuf-compiler - qt5-default - qtscript5-dev + - libqt5x11extras5-dev - scons - vamp-plugin-sdk - qtkeychain-dev