diff --git a/scene.cpp b/scene.cpp index d862da18b8..b01d225b0a 100644 --- a/scene.cpp +++ b/scene.cpp @@ -778,6 +778,13 @@ Scene::Window::Window(Toplevel *client, QObject *parent) this, &Window::discardPixmap); connect(surface, &KWaylandServer::SurfaceInterface::surfaceToBufferMatrixChanged, this, &Window::discardQuads); + + connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceCommitted, this, [this](KWaylandServer::SubSurfaceInterface *subsurface) { + handleSurfaceCommitted(subsurface->surface()); + }); + connect(surface, &KWaylandServer::SurfaceInterface::committed, this, [this, surface]() { + handleSurfaceCommitted(surface); + }); } connect(toplevel, &Toplevel::screenScaleChanged, this, &Window::discardQuads); @@ -1218,6 +1225,27 @@ void Scene::Window::reallocRepaints() m_repaints.fill(infiniteRegion()); } +void Scene::Window::scheduleRepaint() +{ + if (kwinApp()->platform()->isPerScreenRenderingEnabled()) { + const QVector outputs = kwinApp()->platform()->enabledOutputs(); + for (AbstractOutput *output : outputs) { + if (window()->isOnOutput(output)) { + output->renderLoop()->scheduleRepaint(); + } + } + } else { + kwinApp()->platform()->renderLoop()->scheduleRepaint(); + } +} + +void Scene::Window::handleSurfaceCommitted(KWaylandServer::SurfaceInterface *surface) +{ + if (surface->hasFrameCallbacks()) { + scheduleRepaint(); + } +} + //**************************************** // WindowPixmap //**************************************** diff --git a/scene.h b/scene.h index 171725f617..7adceac619 100644 --- a/scene.h +++ b/scene.h @@ -400,6 +400,8 @@ protected: ImageFilterType filter; Shadow *m_shadow; private: + void scheduleRepaint(); + void handleSurfaceCommitted(KWaylandServer::SurfaceInterface *surface); void reallocRepaints(); QScopedPointer m_currentPixmap; diff --git a/subsurfacemonitor.cpp b/subsurfacemonitor.cpp index 2ae048ed8d..e67976bc8e 100644 --- a/subsurfacemonitor.cpp +++ b/subsurfacemonitor.cpp @@ -39,6 +39,8 @@ void SubSurfaceMonitor::registerSubSurface(SubSurfaceInterface *subSurface) this, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged); connect(surface, &SurfaceInterface::bufferSizeChanged, this, &SubSurfaceMonitor::subSurfaceBufferSizeChanged); + connect(surface, &SurfaceInterface::committed, + this, [this, subSurface]() { emit subSurfaceCommitted(subSurface); }); registerSurface(surface); } @@ -49,18 +51,7 @@ void SubSurfaceMonitor::unregisterSubSurface(SubSurfaceInterface *subSurface) if (!surface) return; - disconnect(subSurface, &SubSurfaceInterface::positionChanged, - this, &SubSurfaceMonitor::subSurfaceMoved); - disconnect(surface, &SurfaceInterface::sizeChanged, - this, &SubSurfaceMonitor::subSurfaceResized); - disconnect(surface, &SurfaceInterface::mapped, - this, &SubSurfaceMonitor::subSurfaceMapped); - disconnect(surface, &SurfaceInterface::unmapped, - this, &SubSurfaceMonitor::subSurfaceUnmapped); - disconnect(surface, &SurfaceInterface::surfaceToBufferMatrixChanged, - this, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged); - disconnect(surface, &SurfaceInterface::bufferSizeChanged, - this, &SubSurfaceMonitor::subSurfaceBufferSizeChanged); + disconnect(subSurface, nullptr, this, nullptr); unregisterSurface(surface); } @@ -79,14 +70,7 @@ void SubSurfaceMonitor::registerSurface(SurfaceInterface *surface) void SubSurfaceMonitor::unregisterSurface(SurfaceInterface *surface) { - disconnect(surface, &SurfaceInterface::childSubSurfaceAdded, - this, &SubSurfaceMonitor::subSurfaceAdded); - disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved, - this, &SubSurfaceMonitor::subSurfaceRemoved); - disconnect(surface, &SurfaceInterface::childSubSurfaceAdded, - this, &SubSurfaceMonitor::registerSubSurface); - disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved, - this, &SubSurfaceMonitor::unregisterSubSurface); + disconnect(surface, nullptr, this, nullptr); } } // namespace KWin diff --git a/subsurfacemonitor.h b/subsurfacemonitor.h index 52062ce3b5..ed8ee76e33 100644 --- a/subsurfacemonitor.h +++ b/subsurfacemonitor.h @@ -68,6 +68,7 @@ Q_SIGNALS: * This signal is emitted when the buffer size of a subsurface has changed. */ void subSurfaceBufferSizeChanged(); + void subSurfaceCommitted(KWaylandServer::SubSurfaceInterface *subSurface); private: void registerSubSurface(KWaylandServer::SubSurfaceInterface *subSurface); diff --git a/toplevel.cpp b/toplevel.cpp index 072d917fb0..821830c572 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -9,6 +9,7 @@ #include "toplevel.h" #include "abstract_client.h" +#include "abstract_output.h" #ifdef KWIN_BUILD_ACTIVITIES #include "activities.h" #endif @@ -563,6 +564,11 @@ bool Toplevel::isOnActiveScreen() const return isOnScreen(screens()->current()); } +bool Toplevel::isOnOutput(AbstractOutput *output) const +{ + return output->geometry().intersects(frameGeometry()); +} + void Toplevel::updateShadow() { QRect dirtyRect; // old & new shadow region diff --git a/toplevel.h b/toplevel.h index c5e1ec85b4..7712c2aa83 100644 --- a/toplevel.h +++ b/toplevel.h @@ -37,6 +37,7 @@ class SurfaceInterface; namespace KWin { +class AbstractOutput; class ClientMachine; class Deleted; class EffectWindowImpl; @@ -347,6 +348,7 @@ public: int width() const; int height() const; bool isOnScreen(int screen) const; // true if it's at least partially there + bool isOnOutput(AbstractOutput *output) const; bool isOnActiveScreen() const; int screen() const; // the screen where the center is /**