From fd842e6bed096982569cb9f2cc5c2e475eda3fd5 Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Tue, 7 Jan 2025 18:37:04 +0200 Subject: [PATCH 1/7] GPU hotplug support - Rebase onto main --- src/managers/eventLoop/EventLoopManager.cpp | 30 ++++++++++++++++----- src/managers/eventLoop/EventLoopManager.hpp | 22 +++++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index f98efc927da..e335d775ed4 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -17,11 +18,12 @@ CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEvent m_sTimers.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); m_sWayland.loop = wlEventLoop; m_sWayland.display = display; + aqEventSources = std::map{}; } CEventLoopManager::~CEventLoopManager() { - for (auto const& eventSource : m_sWayland.aqEventSources) { - wl_event_source_remove(eventSource); + for (auto const& [_, eventSourceData] : aqEventSources) { + wl_event_source_remove(eventSourceData.eventSource); } if (m_sWayland.eventSource) @@ -56,10 +58,8 @@ void CEventLoopManager::enterLoop() { if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0) m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr); - aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); - for (auto const& fd : aqPollFDs) { - m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get())); - } + syncPollFDs(); + m_sListeners.pollFDsChanged = g_pCompositor->m_pAqBackend->events.pollFDsChanged.registerListener([this](std::any d) { syncPollFDs(); }); // if we have a session, dispatch it to get the pending input devices if (g_pCompositor->m_pAqBackend->hasSession()) @@ -144,3 +144,21 @@ void CEventLoopManager::doLater(const std::function& fn) { }, &m_sIdle); } + +void CEventLoopManager::syncPollFDs() { + auto aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); + + for (auto it = aqEventSources.begin(); it != aqEventSources.end();) { + if (std::ranges::all_of(aqPollFDs, [&](SP fd) { return fd->fd != it->first; })) { + wl_event_source_remove(it->second.eventSource); + it = aqEventSources.erase(it); + } else { + ++it; + } + } + + for (auto& fd : aqPollFDs | std::views::filter([&](SP fd) { return !aqEventSources.contains(fd->fd); })) { + auto eventSource = wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get()); + aqEventSources[fd->fd] = {.pollFD = fd, .eventSource = eventSource}; + } +} diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 90402de25b3..56c92cd38af 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "helpers/signal/Signal.hpp" #include "EventLoopTimer.hpp" @@ -36,11 +37,18 @@ class CEventLoopManager { }; private: + // Manages the event sources after AQ pollFDs change. + void syncPollFDs(); + + struct SEventSourceData { + SP pollFD; + wl_event_source* eventSource = nullptr; + }; + struct { - wl_event_loop* loop = nullptr; - wl_display* display = nullptr; - wl_event_source* eventSource = nullptr; - std::vector aqEventSources; + wl_event_loop* loop = nullptr; + wl_display* display = nullptr; + wl_event_source* eventSource = nullptr; } m_sWayland; struct { @@ -49,7 +57,11 @@ class CEventLoopManager { } m_sTimers; SIdleData m_sIdle; - std::vector> aqPollFDs; + std::map aqEventSources; + + struct { + CHyprSignalListener pollFDsChanged; + } m_sListeners; wl_event_source* m_configWatcherInotifySource = nullptr; From 62d6ad82b2b3db493d55505d6a2a10198d8c1c93 Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Fri, 10 Jan 2025 04:01:05 +0200 Subject: [PATCH 2/7] Clang-format --- src/managers/eventLoop/EventLoopManager.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 56c92cd38af..d103d90bede 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -56,8 +56,8 @@ class CEventLoopManager { int timerfd = -1; } m_sTimers; - SIdleData m_sIdle; - std::map aqEventSources; + SIdleData m_sIdle; + std::map aqEventSources; struct { CHyprSignalListener pollFDsChanged; From c2b46bd5a8700576222ec558949a36277358dd2b Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Mon, 20 Jan 2025 18:16:23 +0200 Subject: [PATCH 3/7] Add std::ranges header --- src/managers/eventLoop/EventLoopManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index e335d775ed4..c0adaab9496 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -5,8 +5,9 @@ #include #include - #include +#include + #include #include From dee661ff8acd48b5d6db073124b42102b1d96a9d Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Tue, 21 Jan 2025 02:20:17 +0200 Subject: [PATCH 4/7] Use std::erase_if --- src/managers/eventLoop/EventLoopManager.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index c0adaab9496..a79e656578b 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -149,14 +149,17 @@ void CEventLoopManager::doLater(const std::function& fn) { void CEventLoopManager::syncPollFDs() { auto aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); - for (auto it = aqEventSources.begin(); it != aqEventSources.end();) { - if (std::ranges::all_of(aqPollFDs, [&](SP fd) { return fd->fd != it->first; })) { - wl_event_source_remove(it->second.eventSource); - it = aqEventSources.erase(it); - } else { - ++it; - } - } + std::erase_if(aqEventSources, [&](const auto& item) { + auto const& [fd, eventSourceData] = item; + + // If no pollFD has the same fd, remove this event source + const bool shouldRemove = std::ranges::none_of(aqPollFDs, [&](const auto& pollFD) { return pollFD->fd == fd; }); + + if (shouldRemove) + wl_event_source_remove(eventSourceData.eventSource); + + return shouldRemove; + }); for (auto& fd : aqPollFDs | std::views::filter([&](SP fd) { return !aqEventSources.contains(fd->fd); })) { auto eventSource = wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get()); From 9ac400ffe7c2593edcab5e294c41ae8aac47e4a8 Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Wed, 22 Jan 2025 17:14:58 +0200 Subject: [PATCH 5/7] remove redundant constructor --- src/managers/eventLoop/EventLoopManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index a79e656578b..292d9024fbb 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -19,7 +19,6 @@ CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEvent m_sTimers.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); m_sWayland.loop = wlEventLoop; m_sWayland.display = display; - aqEventSources = std::map{}; } CEventLoopManager::~CEventLoopManager() { From 8a859476442034d4101ccf209ca1b4252efd08f1 Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Wed, 22 Jan 2025 17:29:32 +0200 Subject: [PATCH 6/7] move map header --- src/managers/eventLoop/EventLoopManager.cpp | 1 - src/managers/eventLoop/EventLoopManager.hpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index 292d9024fbb..7ac6d782103 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index d103d90bede..ee1a3c983ec 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -68,4 +69,4 @@ class CEventLoopManager { friend class CSyncTimeline; }; -inline std::unique_ptr g_pEventLoopManager; \ No newline at end of file +inline std::unique_ptr g_pEventLoopManager; From 26a6dfcd99dbc208f8eea700bbc5e982104b7cb8 Mon Sep 17 00:00:00 2001 From: Maroun Deeb Date: Wed, 22 Jan 2025 17:46:16 +0200 Subject: [PATCH 7/7] clang-format --- src/managers/eventLoop/EventLoopManager.cpp | 2 +- src/managers/eventLoop/EventLoopManager.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index 7ac6d782103..4021c1717d7 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -153,7 +153,7 @@ void CEventLoopManager::syncPollFDs() { // If no pollFD has the same fd, remove this event source const bool shouldRemove = std::ranges::none_of(aqPollFDs, [&](const auto& pollFD) { return pollFD->fd == fd; }); - if (shouldRemove) + if (shouldRemove) wl_event_source_remove(eventSourceData.eventSource); return shouldRemove; diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index ee1a3c983ec..e1c243d3bfd 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -64,7 +64,7 @@ class CEventLoopManager { CHyprSignalListener pollFDsChanged; } m_sListeners; - wl_event_source* m_configWatcherInotifySource = nullptr; + wl_event_source* m_configWatcherInotifySource = nullptr; friend class CSyncTimeline; };