diff --git a/app/backend/systemproperties.cpp b/app/backend/systemproperties.cpp index 8026721d..3a71f51f 100644 --- a/app/backend/systemproperties.cpp +++ b/app/backend/systemproperties.cpp @@ -91,7 +91,36 @@ QRect SystemProperties::getNativeResolution(int displayIndex) return monitorNativeResolutions.value(displayIndex); } +class QuerySdlVideoThread : public QThread +{ +public: + QuerySdlVideoThread(SystemProperties* me) : + QThread(nullptr), + m_Me(me) {} + + void run() override + { + m_Me->querySdlVideoInfoInternal(); + } + + SystemProperties* m_Me; +}; + void SystemProperties::querySdlVideoInfo() +{ + if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) { + // Use a separate thread to temporarily initialize SDL + // video to avoid stomping on Qt's X11 and OGL state. + QuerySdlVideoThread thread(this); + thread.start(); + thread.wait(); + } + else { + querySdlVideoInfoInternal(); + } +} + +void SystemProperties::querySdlVideoInfoInternal() { hasHardwareAcceleration = false; @@ -103,7 +132,8 @@ void SystemProperties::querySdlVideoInfo() } // Update display related attributes (max FPS, native resolution, etc). - refreshDisplays(); + // We call the internal variant because we're already in a safe thread context. + refreshDisplaysInternal(); SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_WINDOW_HIDDEN | StreamUtils::getPlatformWindowFlags()); @@ -129,7 +159,36 @@ void SystemProperties::querySdlVideoInfo() SDL_QuitSubSystem(SDL_INIT_VIDEO); } +class RefreshDisplaysThread : public QThread +{ +public: + RefreshDisplaysThread(SystemProperties* me) : + QThread(nullptr), + m_Me(me) {} + + void run() override + { + m_Me->refreshDisplaysInternal(); + } + + SystemProperties* m_Me; +}; + void SystemProperties::refreshDisplays() +{ + if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) { + // Use a separate thread to temporarily initialize SDL + // video to avoid stomping on Qt's X11 and OGL state. + RefreshDisplaysThread thread(this); + thread.start(); + thread.wait(); + } + else { + refreshDisplaysInternal(); + } +} + +void SystemProperties::refreshDisplaysInternal() { if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, diff --git a/app/backend/systemproperties.h b/app/backend/systemproperties.h index 0ee6541a..fcfd4841 100644 --- a/app/backend/systemproperties.h +++ b/app/backend/systemproperties.h @@ -7,6 +7,9 @@ class SystemProperties : public QObject { Q_OBJECT + friend class QuerySdlVideoThread; + friend class RefreshDisplaysThread; + public: SystemProperties(); @@ -33,6 +36,8 @@ signals: private: void querySdlVideoInfo(); + void querySdlVideoInfoInternal(); + void refreshDisplaysInternal(); bool hasHardwareAcceleration; bool rendererAlwaysFullScreen;