66#include " core/Output.hpp"
77#include < aquamarine/output/Output.hpp>
88
9- CQueuedPresentationData::CQueuedPresentationData (SP surf) : m_surface(surf) {
9+ CQueuedPresentationData::CQueuedPresentationData (SP surf, std::vector<WP > feedbacks) :
10+ m_surface(surf), m_feedbacks(std::move(feedbacks)) {
1011 ;
1112}
1213
@@ -76,9 +77,23 @@ void CPresentationFeedback::sendQueued(WP data, const t
7677 m_done = true ;
7778}
7879
80+ void CPresentationFeedback::sendDiscarded () {
81+ if (m_done)
82+ return ;
83+
84+ m_resource->sendDiscarded ();
85+ m_done = true ;
86+ }
87+
7988CPresentationProtocol::CPresentationProtocol (const wl_interface* iface, const int & ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
80- static auto P = Event::bus ()->m_events .monitor .removed .listen (
81- [this ](PHLMONITOR mon) { std::erase_if (m_queue, [mon](const auto & other) { return !other->m_surface || other->m_monitor == mon; }); });
89+ static auto P = Event::bus ()->m_events .monitor .removed .listen ([this ](PHLMONITOR mon) {
90+ for (auto & data : m_queue) {
91+ if (!data->m_surface || data->m_monitor == mon)
92+ discardFeedbacks (data->m_feedbacks );
93+ }
94+
95+ std::erase_if (m_queue, [mon](const auto & other) { return !other->m_surface || other->m_monitor == mon; });
96+ });
8297}
8398
8499void CPresentationProtocol::bindManager (wl_client* client, void * data, uint32_t ver, uint32_t id) {
@@ -95,33 +110,40 @@ void CPresentationProtocol::onManagerResourceDestroy(wl_resource* res) {
95110}
96111
97112void CPresentationProtocol::destroyResource (CPresentationFeedback* feedback) {
113+ feedback->m_done = true ;
98114 std::erase_if (m_feedbacks, [&](const auto & other) { return other.get () == feedback; });
99115}
100116
101117void CPresentationProtocol::onGetFeedback (CWpPresentation* pMgr, wl_resource* surf, uint32_t id) {
102118 const auto CLIENT = pMgr->client ();
103119 const auto & RESOURCE =
104- m_feedbacks.emplace_back (makeUnique(makeUnique(CLIENT , pMgr->version (), id), CWLSurfaceResource::fromResource (surf))). get () ;
120+ m_feedbacks.emplace_back (makeUnique(makeUnique(CLIENT , pMgr->version (), id), CWLSurfaceResource::fromResource (surf)));
105121
106122 if UNLIKELY (!RESOURCE ->good ()) {
107123 pMgr->noMemory ();
108124 m_feedbacks.pop_back ();
109125 return ;
110126 }
127+
128+ if (const auto SURFACE = CWLSurfaceResource::fromResource (surf); SURFACE )
129+ SURFACE ->m_pending .presentationFeedbacks .emplace_back (RESOURCE );
111130}
112131
113132void CPresentationProtocol::onPresented (PHLMONITOR pMonitor, const timespec& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
114- for (auto const & feedback : m_feedbacks) {
115- if (!feedback->m_surface )
133+ for (auto const & data : m_queue) {
134+ if (!data->m_surface || !data->m_monitor ) {
135+ discardFeedbacks (data->m_feedbacks );
116136 continue ;
137+ }
117138
118- for (auto const & data : m_queue) {
119- if (!data->m_surface || data->m_surface != feedback->m_surface || (data->m_monitor && data->m_monitor != pMonitor))
139+ if (data->m_monitor != pMonitor)
140+ continue ;
141+
142+ for (auto const & feedback : data->m_feedbacks ) {
143+ if (!feedback || feedback->m_done )
120144 continue ;
121145
122146 feedback->sendQueued (data, when, untilRefreshNs, seq, reportedFlags);
123- feedback->m_done = true ;
124- break ;
125147 }
126148 }
127149
@@ -147,6 +169,33 @@ void CPresentationProtocol::queueData(UP&& data) {
147169 m_queue.emplace_back (std::move (data));
148170}
149171
172+ void CPresentationProtocol::discardFeedbacks (std::vector<WP >& feedbacks) {
173+ for (auto const & feedback : feedbacks) {
174+ if (!feedback || feedback->m_done )
175+ continue ;
176+
177+ feedback->sendDiscarded ();
178+ }
179+
180+ feedbacks.clear ();
181+ std::erase_if (m_feedbacks, [](const auto & other) { return !other->m_surface || other->m_done ; });
182+ }
183+
184+ void CPresentationProtocol::discardFeedbacksForSurface (WP surface) {
185+ if (!surface)
186+ return ;
187+
188+ for (auto const & feedback : m_feedbacks) {
189+ if (feedback->m_surface != surface)
190+ continue ;
191+
192+ feedback->sendDiscarded ();
193+ }
194+
195+ std::erase_if (m_queue, [surface](const auto & other) { return !other->m_surface || other->m_surface == surface; });
196+ std::erase_if (m_feedbacks, [](const auto & other) { return !other->m_surface || other->m_done ; });
197+ }
198+
150199bool CPresentationProtocol::hasPendingFeedbacks () const {
151200 return !m_feedbacks.empty ();
152201}
0 commit comments