Centralise window filtering around a new SceneWindowFilter class

This way WaylandServer can implement its own filter with its own set of
rules without having Scene be too involved in it.
This commit is contained in:
Aleix Pol 2022-03-28 17:07:28 +02:00 committed by Aleix Pol Gonzalez
parent d3259fe945
commit e3fe69041f
5 changed files with 36 additions and 7 deletions

View file

@ -138,6 +138,7 @@ QRect SceneDelegate::viewport() const
Scene::Scene(QObject *parent) Scene::Scene(QObject *parent)
: QObject(parent) : QObject(parent)
, m_filter(this)
{ {
} }
@ -611,12 +612,10 @@ void Scene::createStackingOrder()
if (!win->readyForPainting()) { if (!win->readyForPainting()) {
windows.removeAll(win); windows.removeAll(win);
} }
if (waylandServer() && waylandServer()->isScreenLocked()) { if (!m_filter.filterAcceptsWindow(win)) {
if (!win->isLockScreen() && !win->isInputMethod()) {
windows.removeAll(win); windows.removeAll(win);
} }
} }
}
// TODO: cache the stacking_order in case it has not changed // TODO: cache the stacking_order in case it has not changed
for (Toplevel *c : std::as_const(windows)) { for (Toplevel *c : std::as_const(windows)) {
@ -654,7 +653,7 @@ void Scene::finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion &regio
// will be eventually called from drawWindow() // will be eventually called from drawWindow()
void Scene::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data) void Scene::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data)
{ {
if (waylandServer() && waylandServer()->isScreenLocked() && !w->window()->isLockScreen() && !w->window()->isInputMethod()) { if (!m_filter.filterAcceptsWindow(w->window())) {
return; return;
} }
w->sceneWindow()->performPaint(mask, region, data); w->sceneWindow()->performPaint(mask, region, data);
@ -871,4 +870,20 @@ Scene::EffectFrame::~EffectFrame()
{ {
} }
//****************************************
// ScreenLockerFilter
//****************************************
ScreenLockerFilter::ScreenLockerFilter(Scene *s)
{
QObject::connect(waylandServer(), &WaylandServer::lockStateChanged, s, &Scene::addRepaintFull);
}
ScreenLockerFilter::~ScreenLockerFilter() = default;
bool ScreenLockerFilter::filterAcceptsWindow(KWin::Toplevel *w) const
{
return !waylandServer()->isScreenLocked() || (w->isLockScreen() || w->isInputMethod());
}
} // namespace } // namespace

View file

@ -15,6 +15,8 @@
#include "toplevel.h" #include "toplevel.h"
#include "utils/common.h" #include "utils/common.h"
#include <optional>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMatrix4x4> #include <QMatrix4x4>
@ -44,6 +46,15 @@ class SurfacePixmapX11;
class SurfaceTexture; class SurfaceTexture;
class WindowItem; class WindowItem;
class ScreenLockerFilter
{
public:
ScreenLockerFilter(Scene *scene);
~ScreenLockerFilter();
bool filterAcceptsWindow(KWin::Toplevel *w) const;
};
class SceneDelegate : public RenderLayerDelegate class SceneDelegate : public RenderLayerDelegate
{ {
Q_OBJECT Q_OBJECT
@ -264,6 +275,7 @@ protected:
// windows in their stacking order // windows in their stacking order
QVector<Window *> stacking_order; QVector<Window *> stacking_order;
ScreenLockerFilter m_filter;
private: private:
std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero(); std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();

View file

@ -313,7 +313,7 @@ Scene::Window *SceneOpenGL::createWindow(Toplevel *t)
void SceneOpenGL::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data) void SceneOpenGL::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data)
{ {
if (waylandServer() && waylandServer()->isScreenLocked() && !w->window()->isLockScreen() && !w->window()->isInputMethod()) { if (!m_filter.filterAcceptsWindow(w->window())) {
return; return;
} }
performPaintWindow(w, mask, region, data); performPaintWindow(w, mask, region, data);

View file

@ -600,6 +600,7 @@ void WaylandServer::initScreenLocker()
connect(seat, &KWaylandServer::SeatInterface::timestampChanged, connect(seat, &KWaylandServer::SeatInterface::timestampChanged,
screenLockerApp, &ScreenLocker::KSldApp::userActivity); screenLockerApp, &ScreenLocker::KSldApp::userActivity);
} }
Q_EMIT lockStateChanged();
}); });
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::unlocked, this, [this, screenLockerApp]() { connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::unlocked, this, [this, screenLockerApp]() {
@ -615,7 +616,7 @@ void WaylandServer::initScreenLocker()
screenLockerApp, &ScreenLocker::KSldApp::userActivity); screenLockerApp, &ScreenLocker::KSldApp::userActivity);
} }
ScreenLocker::KSldApp::self()->setWaylandFd(-1); ScreenLocker::KSldApp::self()->setWaylandFd(-1);
Compositor::self()->scene()->addRepaintFull(); Q_EMIT lockStateChanged();
}); });
ScreenLocker::KSldApp::self()->initialize(); ScreenLocker::KSldApp::self()->initialize();

View file

@ -239,6 +239,7 @@ Q_SIGNALS:
void shellClientRemoved(KWin::AbstractClient *); void shellClientRemoved(KWin::AbstractClient *);
void initialized(); void initialized();
void foreignTransientChanged(KWaylandServer::SurfaceInterface *child); void foreignTransientChanged(KWaylandServer::SurfaceInterface *child);
void lockStateChanged();
private: private:
int createScreenLockerConnection(); int createScreenLockerConnection();