mirror of
https://invent.kde.org/plasma/layer-shell-qt.git
synced 2025-05-28 02:50:21 -04:00
Port to asynchronous roundtrip
When a resize is driven client side we wait for the compositor to have a chance to reconfigure us before submitting the next frame. Using a blocking round trip caused an issue. Instead block isExposed and trigger an expose event whilst a sync is in progress.
This commit is contained in:
parent
697c747c58
commit
17be1332cf
@ -79,6 +79,9 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
|
|||||||
|
|
||||||
QWaylandLayerSurface::~QWaylandLayerSurface()
|
QWaylandLayerSurface::~QWaylandLayerSurface()
|
||||||
{
|
{
|
||||||
|
if (m_waitForSyncCallback) {
|
||||||
|
wl_callback_destroy(m_waitForSyncCallback);
|
||||||
|
}
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,11 +100,7 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint
|
|||||||
if (!m_configured) {
|
if (!m_configured) {
|
||||||
m_configured = true;
|
m_configured = true;
|
||||||
window()->resizeFromApplyConfigure(m_pendingSize);
|
window()->resizeFromApplyConfigure(m_pendingSize);
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
|
sendExpose();
|
||||||
window()->handleExpose(QRect(QPoint(), m_pendingSize));
|
|
||||||
#else
|
|
||||||
window()->sendRecursiveExposeEvent();
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
// Later configures are resizes, so we have to queue them up for a time when we
|
// Later configures are resizes, so we have to queue them up for a time when we
|
||||||
// are not painting to the window.
|
// are not painting to the window.
|
||||||
@ -161,6 +160,11 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
|
|||||||
|
|
||||||
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
||||||
{
|
{
|
||||||
|
// if we are setting it to the last size we were configured at, we don't need to do anything
|
||||||
|
if (geometry.size() == m_pendingSize && !m_waitForSyncCallback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const bool horizontallyConstrained = m_interface->anchors().testFlags({Window::AnchorLeft, Window::AnchorRight});
|
const bool horizontallyConstrained = m_interface->anchors().testFlags({Window::AnchorLeft, Window::AnchorRight});
|
||||||
const bool verticallyConstrained = m_interface->anchors().testFlags({Window::AnchorTop, Window::AnchorBottom});
|
const bool verticallyConstrained = m_interface->anchors().testFlags({Window::AnchorTop, Window::AnchorBottom});
|
||||||
|
|
||||||
@ -172,7 +176,7 @@ void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
|||||||
size.setHeight(0);
|
size.setHeight(0);
|
||||||
}
|
}
|
||||||
set_size(size.width(), size.height());
|
set_size(size.width(), size.height());
|
||||||
wl_display_roundtrip(m_window->display()->wl_display());
|
requestWaylandSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWaylandLayerSurface::requestActivate()
|
bool QWaylandLayerSurface::requestActivate()
|
||||||
@ -221,7 +225,43 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
|
|||||||
Q_EMIT window()->xdgActivationTokenCreated(token);
|
Q_EMIT window()->xdgActivationTokenCreated(token);
|
||||||
});
|
});
|
||||||
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, tokenProvider, &QObject::deleteLater);
|
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, tokenProvider, &QObject::deleteLater);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wl_callback_listener QWaylandLayerSurface::syncCallbackListener = {
|
||||||
|
.done = [](void *data, struct wl_callback *callback, uint32_t time){
|
||||||
|
Q_UNUSED(time);
|
||||||
|
wl_callback_destroy(callback);
|
||||||
|
QWaylandLayerSurface *layerSurface = static_cast<QWaylandLayerSurface *>(data);
|
||||||
|
layerSurface->m_waitForSyncCallback = nullptr;
|
||||||
|
layerSurface->sendExpose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandLayerSurface::handleWaylandSyncDone()
|
||||||
|
{
|
||||||
|
if (!window()->isExposed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendExpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandLayerSurface::sendExpose()
|
||||||
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
|
||||||
|
window()->handleExpose(QRect(QPoint(), m_pendingSize));
|
||||||
|
#else
|
||||||
|
window()->sendRecursiveExposeEvent();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
|
|
||||||
bool isExposed() const override
|
bool isExposed() const override
|
||||||
{
|
{
|
||||||
return m_configured;
|
return m_configured && !m_waitForSyncCallback;
|
||||||
}
|
}
|
||||||
void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override;
|
void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override;
|
||||||
|
|
||||||
@ -49,6 +49,9 @@ public:
|
|||||||
void requestXdgActivationToken(quint32 serial) override;
|
void requestXdgActivationToken(quint32 serial) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void requestWaylandSync();
|
||||||
|
void handleWaylandSyncDone();
|
||||||
|
void sendExpose();
|
||||||
void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override;
|
void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override;
|
||||||
void zwlr_layer_surface_v1_closed() override;
|
void zwlr_layer_surface_v1_closed() override;
|
||||||
|
|
||||||
@ -57,7 +60,11 @@ private:
|
|||||||
QtWaylandClient::QWaylandWindow *m_window;
|
QtWaylandClient::QWaylandWindow *m_window;
|
||||||
QSize m_pendingSize;
|
QSize m_pendingSize;
|
||||||
QString m_activationToken;
|
QString m_activationToken;
|
||||||
|
|
||||||
bool m_configured = false;
|
bool m_configured = false;
|
||||||
|
|
||||||
|
static const wl_callback_listener syncCallbackListener;
|
||||||
|
struct wl_callback *m_waitForSyncCallback = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user