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)
: QObject(parent)
, m_filter(this)
{
}
@ -611,10 +612,8 @@ void Scene::createStackingOrder()
if (!win->readyForPainting()) {
windows.removeAll(win);
}
if (waylandServer() && waylandServer()->isScreenLocked()) {
if (!win->isLockScreen() && !win->isInputMethod()) {
windows.removeAll(win);
}
if (!m_filter.filterAcceptsWindow(win)) {
windows.removeAll(win);
}
}
@ -654,7 +653,7 @@ void Scene::finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion &regio
// will be eventually called from drawWindow()
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;
}
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

View file

@ -15,6 +15,8 @@
#include "toplevel.h"
#include "utils/common.h"
#include <optional>
#include <QElapsedTimer>
#include <QMatrix4x4>
@ -44,6 +46,15 @@ class SurfacePixmapX11;
class SurfaceTexture;
class WindowItem;
class ScreenLockerFilter
{
public:
ScreenLockerFilter(Scene *scene);
~ScreenLockerFilter();
bool filterAcceptsWindow(KWin::Toplevel *w) const;
};
class SceneDelegate : public RenderLayerDelegate
{
Q_OBJECT
@ -264,6 +275,7 @@ protected:
// windows in their stacking order
QVector<Window *> stacking_order;
ScreenLockerFilter m_filter;
private:
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)
{
if (waylandServer() && waylandServer()->isScreenLocked() && !w->window()->isLockScreen() && !w->window()->isInputMethod()) {
if (!m_filter.filterAcceptsWindow(w->window())) {
return;
}
performPaintWindow(w, mask, region, data);

View file

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

View file

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