summaryrefslogtreecommitdiff
path: root/src/managers/eventLoop
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-30 20:41:55 +0100
committerGitHub <noreply@github.com>2026-04-30 20:41:55 +0100
commit450d8a0bf703f3ec460d367f38d61b5966daf8fe (patch)
tree3650fcfce70e2118b459c993dee009bbf5da4ea7 /src/managers/eventLoop
parentcfb2deb6644cc2ce474bc8f5feb96d0768768441 (diff)
xdg-shell: queue state updates for toplevel (#14227)
ref https://github.com/hyprwm/Hyprland/discussions/14224
Diffstat (limited to 'src/managers/eventLoop')
-rw-r--r--src/managers/eventLoop/EventLoopManager.cpp38
-rw-r--r--src/managers/eventLoop/EventLoopManager.hpp19
2 files changed, 48 insertions, 9 deletions
diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp
index 03a8d7c9..6c661a6f 100644
--- a/src/managers/eventLoop/EventLoopManager.cpp
+++ b/src/managers/eventLoop/EventLoopManager.cpp
@@ -16,6 +16,17 @@ using namespace Hyprutils::OS;
#define TIMESPEC_NSEC_PER_SEC 1000000000L
+static uint64_t LAST_DO_LATER_SEQ = 1;
+
+SEventLoopDoLaterLock::SEventLoopDoLaterLock(uint64_t seq_) : seq(seq_) {
+ ;
+}
+
+SEventLoopDoLaterLock::~SEventLoopDoLaterLock() {
+ if (g_pEventLoopManager && seq > 0)
+ g_pEventLoopManager->removeDoLater(seq);
+}
+
CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEventLoop) {
m_timers.timerfd = CFileDescriptor{timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC)};
m_wayland.loop = wlEventLoop;
@@ -201,11 +212,13 @@ void CEventLoopManager::nudgeTimers() {
timerfd_settime(m_timers.timerfd.get(), TFD_TIMER_ABSTIME, &ts, nullptr);
}
-void CEventLoopManager::doLater(const std::function<void()>& fn) {
- m_idle.fns.emplace_back(fn);
+uint64_t CEventLoopManager::doLater(const std::function<void()>& fn) {
+ const uint64_t NEW_SEQ = ++LAST_DO_LATER_SEQ;
+
+ m_idle.fns.emplace_back(std::make_pair<>(NEW_SEQ, fn));
if (m_idle.eventSource)
- return;
+ return NEW_SEQ;
m_idle.eventSource = wl_event_loop_add_idle(
m_wayland.loop,
@@ -215,11 +228,26 @@ void CEventLoopManager::doLater(const std::function<void()>& fn) {
IDLE->fns.clear();
IDLE->eventSource = nullptr;
for (auto& f : fns) {
- if (f)
- f();
+ if (f.second)
+ f.second();
}
},
&m_idle);
+
+ return NEW_SEQ;
+}
+
+void CEventLoopManager::removeDoLater(uint64_t seq) {
+ std::erase_if(m_idle.fns, [&seq](const auto& e) { return e.first == seq; });
+
+ if (m_idle.fns.empty() && m_idle.eventSource) {
+ wl_event_source_remove(m_idle.eventSource);
+ m_idle.eventSource = nullptr;
+ }
+}
+
+UP<SEventLoopDoLaterLock> CEventLoopManager::doLaterLock(const std::function<void()>& fn) {
+ return makeUnique<SEventLoopDoLaterLock>(doLater(fn));
}
void CEventLoopManager::doOnReadable(CFileDescriptor fd, std::function<void()>&& fn) {
diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp
index 7999dc59..64673455 100644
--- a/src/managers/eventLoop/EventLoopManager.hpp
+++ b/src/managers/eventLoop/EventLoopManager.hpp
@@ -14,6 +14,13 @@ namespace Aquamarine {
struct SPollFD;
};
+struct SEventLoopDoLaterLock {
+ SEventLoopDoLaterLock(uint64_t seq);
+ ~SEventLoopDoLaterLock();
+
+ uint64_t seq = 0;
+};
+
class CEventLoopManager {
public:
CEventLoopManager(wl_display* display, wl_event_loop* wlEventLoop);
@@ -30,12 +37,16 @@ class CEventLoopManager {
// schedules a recalc of the timers
void scheduleRecalc();
- // schedules a function to run later, aka in a wayland idle event.
- void doLater(const std::function<void()>& fn);
+ // schedules a function to run later, aka in a wayland idle event. Returns a sequence which can be used to remove it.
+ uint64_t doLater(const std::function<void()>& fn);
+ void removeDoLater(uint64_t seq);
+
+ // automatically cleaned up doLater instance
+ [[nodiscard]] UP<SEventLoopDoLaterLock> doLaterLock(const std::function<void()>& fn);
struct SIdleData {
- wl_event_source* eventSource = nullptr;
- std::vector<std::function<void()>> fns;
+ wl_event_source* eventSource = nullptr;
+ std::vector<std::pair<uint64_t, std::function<void()>>> fns;
};
struct SReadableWaiter {