From 659c41687926db606dee8db9079d3a7466e137aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 24 Feb 2015 10:54:28 +0100 Subject: [PATCH] [wayland] Handle damage events from SurfaceInterface On Wayland we get the damage from the SurfaceInterface instead of using a damage handle. This change ensures that the damage handle interaction is only used on platform X11, while on Wayland we get the damage from the SurfaceInterface directly. --- client.cpp | 9 +++++++++ client.h | 1 + composite.cpp | 16 ++++++++++++---- toplevel.cpp | 29 +++++++++++++++++++++++++++++ toplevel.h | 6 +----- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/client.cpp b/client.cpp index f711b6bf49..2c42de992c 100644 --- a/client.cpp +++ b/client.cpp @@ -2455,6 +2455,15 @@ void Client::setDecoratedClient(QPointer< Decoration::DecoratedClientImpl > clie m_decoratedClient = client; } +void Client::addDamage(const QRegion &damage) +{ + if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead + if (syncRequest.counter == XCB_NONE) // cannot detect complete redraw, consider done now + setReadyForPainting(); + } + Toplevel::addDamage(damage); +} + } // namespace #include "client.moc" diff --git a/client.h b/client.h index 5491004133..1346947af3 100644 --- a/client.h +++ b/client.h @@ -740,6 +740,7 @@ private: protected: virtual void debug(QDebug& stream) const; virtual bool shouldUnredirect() const; + void addDamage(const QRegion &damage) override; private Q_SLOTS: void delayedSetShortcut(); diff --git a/composite.cpp b/composite.cpp index 6b78eed664..7c67b12700 100644 --- a/composite.cpp +++ b/composite.cpp @@ -898,8 +898,10 @@ bool Toplevel::setupCompositing() if (damage_handle != XCB_NONE) return false; - damage_handle = xcb_generate_id(connection()); - xcb_damage_create(connection(), damage_handle, frameId(), XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY); + if (kwinApp()->operationMode() == Application::OperationModeX11) { + damage_handle = xcb_generate_id(connection()); + xcb_damage_create(connection(), damage_handle, frameId(), XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY); + } damage_region = QRegion(0, 0, width(), height()); effect_window = new EffectWindowImpl(this); @@ -920,7 +922,7 @@ bool Toplevel::setupCompositing() void Toplevel::finishCompositing(ReleaseReason releaseReason) { - if (damage_handle == XCB_NONE) + if (kwinApp()->operationMode() == Application::OperationModeX11 && damage_handle == XCB_NONE) return; Compositor::self()->checkUnredirect(true); if (effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data @@ -928,7 +930,8 @@ void Toplevel::finishCompositing(ReleaseReason releaseReason) delete effect_window; } - if (releaseReason != ReleaseReason::Destroyed) { + if (kwinApp()->operationMode() == Application::OperationModeX11 && + releaseReason != ReleaseReason::Destroyed) { xcb_damage_destroy(connection(), damage_handle); } @@ -981,6 +984,11 @@ bool Toplevel::resetAndFetchDamage() if (!m_isDamaged) return false; + if (kwinApp()->operationMode() != Application::OperationModeX11) { + m_isDamaged = false; + return true; + } + xcb_connection_t *conn = connection(); // Create a new region and copy the damage region to it, diff --git a/toplevel.cpp b/toplevel.cpp index c8fcf39edb..1423be82c4 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -31,6 +31,10 @@ along with this program. If not, see . #include "shadow.h" #include "xcbutils.h" +#if HAVE_WAYLAND +#include +#endif + #include namespace KWin @@ -474,6 +478,31 @@ void Toplevel::sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeySt Q_UNUSED(state) } +#if HAVE_WAYLAND +void Toplevel::setSurface(KWayland::Server::SurfaceInterface *surface) +{ + if (m_surface == surface) { + return; + } + using namespace KWayland::Server; + if (m_surface) { + disconnect(m_surface, &SurfaceInterface::damaged, this, &Toplevel::addDamage); + } + m_surface = surface; + connect(m_surface, &SurfaceInterface::damaged, this, &Toplevel::addDamage); +} +#endif + +void Toplevel::addDamage(const QRegion &damage) +{ + m_isDamaged = true; + damage_region += damage; + repaints_region += damage; + for (const QRect &r : damage.rects()) { + emit damaged(this, r); + } +} + } // namespace #include "toplevel.moc" diff --git a/toplevel.h b/toplevel.h index 1ec0d129dc..78f7ae786d 100644 --- a/toplevel.h +++ b/toplevel.h @@ -441,6 +441,7 @@ protected: virtual void clientMessageEvent(xcb_client_message_event_t *e); void discardWindowPixmap(); void addDamageFull(); + virtual void addDamage(const QRegion &damage); Xcb::Property fetchWmClientLeader() const; void readWmClientLeader(Xcb::Property &p); void getWmClientLeader(); @@ -740,11 +741,6 @@ inline KWayland::Server::SurfaceInterface *Toplevel::surface() const { return m_surface; } - -inline void Toplevel::setSurface(KWayland::Server::SurfaceInterface *surface) -{ - m_surface = surface; -} #endif template