core/window: move input mask handling + commit scheduling to polish

This commit is contained in:
outfoxxed 2025-01-20 00:51:56 -08:00
parent d6b58521e9
commit 6464ead0f1
Signed by untrusted user: outfoxxed
GPG key ID: 4C88A185FB89301E
7 changed files with 76 additions and 32 deletions

View file

@ -28,15 +28,16 @@
ProxyWindowBase::ProxyWindowBase(QObject* parent)
: Reloadable(parent)
, mContentItem(new QQuickItem()) {
, mContentItem(new ProxyWindowContentItem()) {
QQmlEngine::setObjectOwnership(this->mContentItem, QQmlEngine::CppOwnership);
this->mContentItem->setParent(this);
// clang-format off
QObject::connect(this->mContentItem, &ProxyWindowContentItem::polished, this, &ProxyWindowBase::onPolished);
QObject::connect(this, &ProxyWindowBase::widthChanged, this, &ProxyWindowBase::onWidthChanged);
QObject::connect(this, &ProxyWindowBase::heightChanged, this, &ProxyWindowBase::onHeightChanged);
QObject::connect(this, &ProxyWindowBase::maskChanged, this, &ProxyWindowBase::onMaskChanged);
QObject::connect(this, &ProxyWindowBase::widthChanged, this, &ProxyWindowBase::onMaskChanged);
QObject::connect(this, &ProxyWindowBase::heightChanged, this, &ProxyWindowBase::onMaskChanged);
@ -264,6 +265,12 @@ void ProxyWindowBase::setVisibleDirect(bool visible) {
}
}
void ProxyWindowBase::schedulePolish() {
if (this->isVisibleDirect()) {
this->mContentItem->polish();
}
}
void ProxyWindowBase::polishItems() {
// Due to QTBUG-126704, layouts in invisible windows don't update their dimensions.
// Usually this isn't an issue, but it is when the size of a window is based on the size
@ -385,11 +392,11 @@ void ProxyWindowBase::setMask(PendingRegion* mask) {
this->mMask = mask;
if (mask != nullptr) {
mask->setParent(this);
QObject::connect(mask, &QObject::destroyed, this, &ProxyWindowBase::onMaskDestroyed);
QObject::connect(mask, &PendingRegion::changed, this, &ProxyWindowBase::maskChanged);
QObject::connect(mask, &PendingRegion::changed, this, &ProxyWindowBase::onMaskChanged);
}
this->onMaskChanged();
emit this->maskChanged();
}
@ -410,23 +417,13 @@ void ProxyWindowBase::onMaskChanged() {
void ProxyWindowBase::onMaskDestroyed() {
this->mMask = nullptr;
this->onMaskChanged();
emit this->maskChanged();
}
void ProxyWindowBase::updateMask() {
QRegion mask;
if (this->mMask != nullptr) {
// if left as the default, dont combine it with the whole window area, leave it as is.
if (this->mMask->mIntersection == Intersection::Combine) {
mask = this->mMask->build();
} else {
auto windowRegion = QRegion(QRect(0, 0, this->width(), this->height()));
mask = this->mMask->applyTo(windowRegion);
}
}
this->window->setFlag(Qt::WindowTransparentForInput, this->mMask != nullptr && mask.isEmpty());
this->window->setMask(mask);
this->pendingPolish.inputMask = true;
this->schedulePolish();
}
QQmlListProperty<QObject> ProxyWindowBase::data() {
@ -463,3 +460,21 @@ void ProxiedWindow::exposeEvent(QExposeEvent* event) {
this->QQuickWindow::exposeEvent(event);
emit this->exposed();
}
void ProxyWindowContentItem::updatePolish() { emit this->polished(); }
void ProxyWindowBase::onPolished() {
if (this->pendingPolish.inputMask) {
QRegion mask;
if (this->mMask != nullptr) {
mask = this->mMask->applyTo(QRect(0, 0, this->width(), this->height()));
}
this->window->setFlag(Qt::WindowTransparentForInput, this->mMask != nullptr && mask.isEmpty());
this->window->setMask(mask);
this->pendingPolish.inputMask = false;
}
emit this->polished();
}

View file

@ -20,6 +20,7 @@
#include "windowinterface.hpp"
class ProxiedWindow;
class ProxyWindowContentItem;
// Proxy to an actual window exposing a limited property set with the ability to
// transfer it to a new window.
@ -85,6 +86,8 @@ public:
virtual void setVisible(bool visible);
virtual void setVisibleDirect(bool visible);
void schedulePolish();
[[nodiscard]] virtual qint32 x() const;
[[nodiscard]] virtual qint32 y() const;
@ -124,6 +127,7 @@ signals:
void colorChanged();
void maskChanged();
void surfaceFormatChanged();
void polished();
protected slots:
virtual void onWidthChanged();
@ -131,6 +135,7 @@ protected slots:
void onMaskChanged();
void onMaskDestroyed();
void onScreenDestroyed();
void onPolished();
void runLints();
protected:
@ -141,12 +146,16 @@ protected:
QColor mColor = Qt::white;
PendingRegion* mMask = nullptr;
ProxiedWindow* window = nullptr;
QQuickItem* mContentItem = nullptr;
ProxyWindowContentItem* mContentItem = nullptr;
bool reloadComplete = false;
bool ranLints = false;
QsSurfaceFormat qsSurfaceFormat;
QSurfaceFormat mSurfaceFormat;
struct {
bool inputMask : 1 = false;
} pendingPolish;
private:
void polishItems();
void updateMask();
@ -190,3 +199,13 @@ protected:
private:
ProxyWindowBase* mProxy;
};
class ProxyWindowContentItem: public QQuickItem {
Q_OBJECT;
signals:
void polished();
protected:
void updatePolish() override;
};