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