diff --git a/src/gui/wayland/waylandidletimer.cpp b/src/gui/wayland/waylandidletimer.cpp index e9f761ca..cc72665e 100644 --- a/src/gui/wayland/waylandidletimer.cpp +++ b/src/gui/wayland/waylandidletimer.cpp @@ -52,13 +52,13 @@ public: }; WaylandIdleTimer::WaylandIdleTimer() - : m_supported{WaylandUtils::hasInterface("ext_idle_notifier_v1")} + : wl_utils(new WaylandUtils), m_supported(wl_utils->hasInterface("ext_idle_notifier_v1")) { if (m_supported) { auto seat = WaylandUtils::seat(); m_notifier.reset(new WaylandIdleNotifier()); #ifdef USE_WAYLAND_INPUT_IDLE_NOTIFY - if (WaylandUtils::hasInterface("ext_idle_notifier_v1", 2)) { + if (wl_utils->hasInterface("ext_idle_notifier_v1", 2)) { m_notification.reset(new WaylandIdleNotification(m_notifier->get_input_idle_notification(0, seat))); } else { m_notification.reset(new WaylandIdleNotification(m_notifier->get_idle_notification(0, seat))); @@ -88,4 +88,6 @@ bool WaylandIdleTimer::isSupported() const { return m_supported; } + #endif + diff --git a/src/gui/wayland/waylandidletimer.h b/src/gui/wayland/waylandidletimer.h index 7a874f36..dd3df7e7 100644 --- a/src/gui/wayland/waylandidletimer.h +++ b/src/gui/wayland/waylandidletimer.h @@ -3,6 +3,7 @@ #ifdef USE_WAYLAND_IDLE_NOTIFY #include "idletimer.h" +#include "waylandutils.h" #include @@ -17,6 +18,7 @@ public: bool isSupported() const override; private: + QScopedPointer wl_utils; bool m_supported; QScopedPointer m_notifier; QScopedPointer m_notification; diff --git a/src/gui/wayland/waylandutils.cpp b/src/gui/wayland/waylandutils.cpp index 72063925..66a5c836 100644 --- a/src/gui/wayland/waylandutils.cpp +++ b/src/gui/wayland/waylandutils.cpp @@ -3,7 +3,6 @@ #include #ifdef USE_WAYLAND -#include #if QT_VERSION < QT_VERSION_CHECK(6, 5 ,0) #include #endif @@ -11,17 +10,9 @@ #include #include -#if QT_VERSION >= QT_VERSION_CHECK(6, 3 ,0) -#include -#else -#include -#endif #endif -namespace WaylandUtils -{ - -bool isWayland() +bool WaylandUtils::isWayland() { if (qGuiApp->platformName() == "wayland") { return true; @@ -39,96 +30,79 @@ bool isWayland() } #ifdef USE_WAYLAND -struct RegistryData { - QString interfaceName; - quint32 version; -}; -class WaylandUtilsHelper { -public: - wl_display* m_display = nullptr; - wl_registry* m_registry = nullptr; - wl_seat *m_seat = nullptr; - - QList m_registerData; - - WaylandUtilsHelper() - { -#if QT_VERSION < QT_VERSION_CHECK(6, 5 ,0) - QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface(); - if (!nativeInterface) { - return; - } - - m_display = static_cast(nativeInterface->nativeResourceForIntegration("wl_display")); - if (!m_display) { - return; - } - - m_seat = static_cast(nativeInterface->nativeResourceForIntegration("m_seat")); - if (!m_seat) { - m_display = nullptr; - return; - } -#else - auto nativeInterface = qGuiApp->nativeInterface(); - if (!nativeInterface) { - return; - } - - m_display = nativeInterface->display(); - m_seat = nativeInterface->seat(); -#endif - - m_registry = wl_display_get_registry(m_display); - if (!m_registry) { - return; - } - - auto global_handler = [](void* data_ptr, wl_registry*, uint32_t name, const char* interface, uint32_t version) { - auto registerData = static_cast*>(data_ptr); - registerData->append({QString::fromLatin1(interface), version}); - }; - - auto global_remover_handler = [](void*, wl_registry*, uint32_t) { }; - - wl_registry_listener registry_listener = { - global_handler, - global_remover_handler - }; - - wl_registry_add_listener(m_registry, ®istry_listener, &m_registerData); - - wl_display_dispatch(m_display); - wl_display_roundtrip(m_display); - } -}; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 3 ,0) -Q_APPLICATION_STATIC(WaylandUtilsHelper, g_helper,) -#else -Q_GLOBAL_STATIC(WaylandUtilsHelper, g_helper) -#endif - -bool hasInterface(const QString &name, quint32 version) +WaylandUtils::WaylandUtils() { - auto it = std::find_if(g_helper->m_registerData.constBegin(), g_helper->m_registerData.constEnd(), [&name, &version](const RegistryData& data){ + wl_display* m_display = nullptr; +#if QT_VERSION < QT_VERSION_CHECK(6, 5 ,0) + QPlatformNativeInterface* nativeInterface = qGuiApp->platformNativeInterface(); + if (!nativeInterface) + return; + + m_display = static_cast(nativeInterface->nativeResourceForIntegration("wl_display")); +#else + auto nativeInterface = qGuiApp->nativeInterface(); + if (!nativeInterface) + return; + + m_display = nativeInterface->display(); +#endif + if (!m_display) + return; + + wl_registry* m_registry = wl_display_get_registry(m_display); + if (!m_registry) + return; + + auto global_handler = [](void* data_ptr, wl_registry*, uint32_t name, const char* interface, uint32_t version) { + auto registerData = static_cast*>(data_ptr); + registerData->append({QString::fromLatin1(interface), version}); + }; + + auto global_remover_handler = [](void*, wl_registry*, uint32_t) { }; + + wl_registry_listener registry_listener = { + global_handler, + global_remover_handler + }; + + wl_registry_add_listener(m_registry, ®istry_listener, &m_registerData); + + wl_display_dispatch(m_display); + wl_display_roundtrip(m_display); + + // HACK: Destroy the registry proxy to indirectly remove the listener + // This way we avoid crashing when the display disappears/changes + wl_proxy_destroy(reinterpret_cast(m_registry)); +} + +wl_seat* WaylandUtils::seat() { +#if QT_VERSION < QT_VERSION_CHECK(6, 5 ,0) + QPlatformNativeInterface* nativeInterface = qGuiApp->platformNativeInterface(); + if (!nativeInterface) + return nullptr; + + wl_seat* s = static_cast(nativeInterface->nativeResourceForIntegration("m_seat")); +#else + auto nativeInterface = qGuiApp->nativeInterface(); + if (!nativeInterface) + return nullptr; + + wl_seat* s = nativeInterface->seat(); +#endif + return s; +} + +bool WaylandUtils::hasInterface(const QString &name, quint32 version) +{ + auto it = std::find_if(m_registerData.constBegin(), m_registerData.constEnd(), [&name, &version](const RegistryData& data){ const bool matched = data.interfaceName == name; if (version == 0) { return matched; } return matched && data.version == version; }); - return it != g_helper->m_registerData.constEnd(); + return it != m_registerData.constEnd(); } -wl_display *display() { - return g_helper->m_display; -} - -wl_seat *seat() { - return g_helper->m_seat; -} #endif - -} // WaylandUtils diff --git a/src/gui/wayland/waylandutils.h b/src/gui/wayland/waylandutils.h index c792c0b8..0364c7a2 100644 --- a/src/gui/wayland/waylandutils.h +++ b/src/gui/wayland/waylandutils.h @@ -6,20 +6,29 @@ #ifdef USE_WAYLAND class wl_display; class wl_seat; +#include #endif -namespace WaylandUtils +class WaylandUtils { -bool isWayland(); +public: + static bool isWayland(); #ifdef USE_WAYLAND -bool hasInterface(const QString &name, quint32 version = 0); + WaylandUtils(); + static wl_seat* seat(); -wl_display *display(); -wl_seat *seat(); + bool hasInterface(const QString& name, quint32 version = 0); + +private: + struct RegistryData { + QString interfaceName; + quint32 version; + }; + QList m_registerData; #endif -} // WaylandUtils +}; // WaylandUtils #endif // WAYLANDUTILS_HPP