Compare commits

...

2 Commits

Author SHA1 Message Date
9fe00051e0 debug++ 2024-04-08 11:49:36 +01:00
c51ab381da deferred apply
When we get a configure event defer applying it until all pending
callbacks are processsed. This ensures we only only process configure
events that match the last thing we requested.
2024-04-08 11:42:08 +01:00
2 changed files with 40 additions and 15 deletions

View File

@ -67,13 +67,15 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
});
setDesiredSize(window->windowContentGeometry().size());
requestWaylandSync();
}
QWaylandLayerSurface::~QWaylandLayerSurface()
{
if (m_waitForSyncCallback) {
wl_callback_destroy(m_waitForSyncCallback);
for (auto syncCallback: m_waitForSyncCallbacks) {
wl_callback_destroy(syncCallback);
}
m_waitForSyncCallbacks.clear();
destroy();
}
@ -86,9 +88,17 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_closed()
void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height)
{
qDebug() << "got configure";
ack_configure(serial);
m_pendingSize = QSize(width, height);
// because configure lacks a way to match it up with our resize requests
// we apply it only when our callback sync is complete
if (!m_waitForSyncCallbacks.isEmpty()) {
m_hasPendingConfigureToApply = true;
return;
}
if (!m_configured) {
m_configured = true;
applyConfigure();
@ -98,6 +108,8 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint
// are not painting to the window.
window()->applyConfigureWhenPossible();
}
qDebug() << "end got confiure";
}
void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *popup)
@ -114,6 +126,7 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po
void QWaylandLayerSurface::applyConfigure()
{
m_configuring = true;
qDebug() << "resizing panel to " << m_pendingSize;
window()->resizeFromApplyConfigure(m_pendingSize);
m_configuring = false;
}
@ -130,6 +143,7 @@ void QWaylandLayerSurface::setDesiredSize(const QSize &size)
if (verticallyConstrained) {
effectiveSize.setHeight(0);
}
qDebug() << "requesting size " << effectiveSize;
set_size(effectiveSize.width(), effectiveSize.height());
}
@ -229,27 +243,38 @@ const wl_callback_listener QWaylandLayerSurface::syncCallbackListener = {
Q_UNUSED(time);
wl_callback_destroy(callback);
QWaylandLayerSurface *layerSurface = static_cast<QWaylandLayerSurface *>(data);
layerSurface->m_waitForSyncCallback = nullptr;
layerSurface->sendExpose();
layerSurface->m_waitForSyncCallbacks.removeOne(callback);
layerSurface->handleWaylandSyncDone();
}
};
void QWaylandLayerSurface::requestWaylandSync()
{
if (m_waitForSyncCallback) {
return;
}
m_waitForSyncCallback = wl_display_sync(m_window->display()->wl_display());
wl_callback_add_listener(m_waitForSyncCallback, &syncCallbackListener, this);
auto syncCallback = wl_display_sync(m_window->display()->wl_display());
m_waitForSyncCallbacks.append(syncCallback);
wl_callback_add_listener(syncCallback, &syncCallbackListener, this);
}
void QWaylandLayerSurface::handleWaylandSyncDone()
{
if (!window()->isExposed()) {
qDebug() << "handle sync done";
if (!window()->window()->isVisible() || !m_waitForSyncCallbacks.isEmpty()) {
return;
}
sendExpose();
if (m_hasPendingConfigureToApply) {
m_hasPendingConfigureToApply = false;
if (!m_configured) {
m_configured = true;
applyConfigure();
sendExpose();
} else {
// Later configures are resizes, so we have to queue them up for a time when we
// are not painting to the window.
window()->applyConfigureWhenPossible();
}
}
qDebug() << "end handle sync done";
}
void QWaylandLayerSurface::sendExpose()

View File

@ -30,7 +30,7 @@ public:
bool isExposed() const override
{
return m_configured && !m_waitForSyncCallback;
return m_configured && m_waitForSyncCallbacks.isEmpty();
}
void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override;
@ -64,11 +64,11 @@ private:
bool m_configured = false;
bool m_configuring = false;
bool m_hasPendingConfigureToApply = false;
static const wl_callback_listener syncCallbackListener;
struct wl_callback *m_waitForSyncCallback = nullptr;
QList<struct wl_callback*> m_waitForSyncCallbacks;
};
}
#endif