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 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..eb7eb4334590 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -81,10 +81,41 @@ #include "preferences/dialog/dlgprefmodplug.h" #endif +#if defined(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 +#if defined(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 @@ -150,12 +181,6 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) setCentralWidget(m_pWidgetParent); show(); -#if defined(Q_WS_X11) - // 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); @@ -169,6 +194,15 @@ MixxxMainWindow::~MixxxMainWindow() { void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { ScopedTimer t("MixxxMainWindow::initialize"); +#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) { + XESetWireToError(QX11Info::display(), i, &__xErrorHandler); + } + } +#endif + UserSettingsPointer pConfig = m_pSettingsManager->settings(); Sandbox::initialize(QDir(pConfig->getSettingsPath()).filePath("sandbox.cfg"));