diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 8b4ba0ee..e34aa54b 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -4,6 +4,7 @@ #include "../protocols/PointerGestures.hpp" #include "../protocols/FractionalScale.hpp" #include "../protocols/core/Compositor.hpp" +#include "eventLoop/EventLoopManager.hpp" #include "SeatManager.hpp" #include #include @@ -139,8 +140,8 @@ CPointerManager::CPointerManager() { onMonitorLayoutChange(); - PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { onMonitorLayoutChange(); }, nullptr); - PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { onMonitorLayoutChange(); }, nullptr); + PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); + PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); PMONITOR->events.destroy.registerStaticListener( [this](void* owner, std::any data) { if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index 1193ffb8..e2d72f22 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -86,4 +86,25 @@ void CEventLoopManager::nudgeTimers() { itimerspec ts = {.it_value = now}; timerfd_settime(m_sTimers.timerfd, TFD_TIMER_ABSTIME, &ts, nullptr); -} \ No newline at end of file +} + +void CEventLoopManager::doLater(const std::function& fn) { + m_sIdle.fns.emplace_back(fn); + + if (m_sIdle.eventSource) + return; + + m_sIdle.eventSource = wl_event_loop_add_idle( + m_sWayland.loop, + [](void* data) { + auto IDLE = (CEventLoopManager::SIdleData*)data; + auto cpy = IDLE->fns; + IDLE->fns.clear(); + IDLE->eventSource = nullptr; + for (auto& c : cpy) { + if (c) + c(); + } + }, + &m_sIdle); +} diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 7a4fa19e..77e57513 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -23,6 +23,14 @@ class CEventLoopManager { // recalculates timers void nudgeTimers(); + // schedules a function to run later, aka in a wayland idle event. + void doLater(const std::function& fn); + + struct SIdleData { + wl_event_source* eventSource = nullptr; + std::vector> fns; + }; + private: struct { wl_event_loop* loop = nullptr; @@ -34,6 +42,8 @@ class CEventLoopManager { std::vector> timers; int timerfd = -1; } m_sTimers; + + SIdleData m_sIdle; }; inline std::unique_ptr g_pEventLoopManager; \ No newline at end of file