From efef6abde33a9d4ddd9f90fe969facf69d5df754 Mon Sep 17 00:00:00 2001 From: April & May Date: Wed, 20 Aug 2025 11:11:00 +0800 Subject: [PATCH] fix: fix wrong display render issue when switching VT too quickly When cooperating with DDM, switching VT will not drop DRM FD. This makes treeland still able to draw to the DRM after VT switch, which will cause wrong display rendering when switching VT too quickly. This commit cooperate new treeland-ddm-v1 protocol and expose interface to enable / disable global rendering, which is used in DDM to control render before / after TTY switching, to solve the render issue. --- src/modules/ddm/ddminterfacev1.cpp | 10 ++++++++++ src/seat/helper.cpp | 8 ++++++++ src/seat/helper.h | 2 ++ waylib/src/server/qtquick/woutputrenderwindow.cpp | 9 +++++++++ waylib/src/server/qtquick/woutputrenderwindow.h | 2 ++ 5 files changed, 31 insertions(+) diff --git a/src/modules/ddm/ddminterfacev1.cpp b/src/modules/ddm/ddminterfacev1.cpp index 842c2c6f3d..e8c07b1acd 100644 --- a/src/modules/ddm/ddminterfacev1.cpp +++ b/src/modules/ddm/ddminterfacev1.cpp @@ -36,11 +36,21 @@ static void deactivateSession([[maybe_unused]] struct wl_client *client, [[maybe Helper::instance()->deactivateSession(); } +static void enableRender([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { + Helper::instance()->enableRender(); +} + +static void disableRender([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { + Helper::instance()->disableRender(); +} + static const struct treeland_ddm_interface treeland_ddm_impl { .switch_to_greeter = switchToGreeter, .switch_to_user = switchToUser, .activate_session = activateSession, .deactivate_session = deactivateSession, + .enable_render = enableRender, + .disable_render = disableRender, }; // wayland object binding diff --git a/src/seat/helper.cpp b/src/seat/helper.cpp index 2f8bcc78b4..2e5ad7510b 100644 --- a/src/seat/helper.cpp +++ b/src/seat/helper.cpp @@ -2160,3 +2160,11 @@ void Helper::deactivateSession() { if (m_backend->isSessionActive()) m_backend->deactivateSession(); } + +void Helper::enableRender() { + m_renderWindow->setRenderEnabled(true); +} + +void Helper::disableRender() { + m_renderWindow->setRenderEnabled(false); +} diff --git a/src/seat/helper.h b/src/seat/helper.h index 229cec42e0..7005aeb900 100644 --- a/src/seat/helper.h +++ b/src/seat/helper.h @@ -210,6 +210,8 @@ class Helper : public WSeatEventFilter void activateSession(); void deactivateSession(); + void enableRender(); + void disableRender(); public Q_SLOTS: void activateSurface(SurfaceWrapper *wrapper, Qt::FocusReason reason = Qt::OtherFocusReason); void forceActivateSurface(SurfaceWrapper *wrapper, diff --git a/waylib/src/server/qtquick/woutputrenderwindow.cpp b/waylib/src/server/qtquick/woutputrenderwindow.cpp index 5da70bf688..91b81528ca 100644 --- a/waylib/src/server/qtquick/woutputrenderwindow.cpp +++ b/waylib/src/server/qtquick/woutputrenderwindow.cpp @@ -451,6 +451,7 @@ class Q_DECL_HIDDEN WOutputRenderWindowPrivate : public QQuickWindowPrivate bool componentCompleted = true; bool inRendering = false; + bool renderEnabled = true; QPointer m_renderer; QPointer m_allocator; @@ -1475,6 +1476,9 @@ void WOutputRenderWindowPrivate::doRender(const QList &outputs, { Q_ASSERT(rendererList.isEmpty()); Q_ASSERT(!inRendering); + if (!renderEnabled) + return; + inRendering = true; W_Q(WOutputRenderWindow); @@ -1816,6 +1820,11 @@ bool WOutputRenderWindow::inRendering() const return d->inRendering; } +void WOutputRenderWindow::setRenderEnabled(bool enabled) { + Q_D(WOutputRenderWindow); + d->renderEnabled = enabled; +} + QList> WOutputRenderWindow::paintOrderItemList(QQuickItem *root, std::function filter) { QStack nodes; diff --git a/waylib/src/server/qtquick/woutputrenderwindow.h b/waylib/src/server/qtquick/woutputrenderwindow.h index ca8a56d914..a777319ddd 100644 --- a/waylib/src/server/qtquick/woutputrenderwindow.h +++ b/waylib/src/server/qtquick/woutputrenderwindow.h @@ -55,6 +55,8 @@ class WAYLIB_SERVER_EXPORT WOutputRenderWindow : public QQuickWindow, public QQm WBufferRenderer *currentRenderer() const; bool inRendering() const; + void setRenderEnabled(bool enabled); + static QList> paintOrderItemList(QQuickItem *root, std::function filter); bool disableLayers() const;