diff --git a/src/wayland/screencopy/view.cpp b/src/wayland/screencopy/view.cpp index fe744fd8..aeafea61 100644 --- a/src/wayland/screencopy/view.cpp +++ b/src/wayland/screencopy/view.cpp @@ -1,5 +1,6 @@ #include "view.hpp" +#include #include #include #include @@ -12,6 +13,23 @@ namespace qs::wayland::screencopy { +ScreencopyView::ScreencopyView(QQuickItem* parent): QQuickItem(parent) { + this->bImplicitSize.setBinding([this] { + auto constraint = this->bConstraintSize.value(); + auto size = this->bSourceSize.value().toSizeF(); + + if (constraint.width() != 0 && constraint.height() != 0) { + size.scale(constraint.width(), constraint.height(), Qt::KeepAspectRatio); + } else if (constraint.width() != 0) { + size = QSizeF(constraint.width(), size.height() / constraint.width()); + } else if (constraint.height() != 0) { + size = QSizeF(size.width() / constraint.height(), constraint.height()); + } + + return size; + }); +} + void ScreencopyView::setCaptureSource(QObject* captureSource) { if (captureSource == this->mCaptureSource) return; auto hadContext = this->context != nullptr; @@ -148,4 +166,9 @@ QSGNode* ScreencopyView::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* return node; } +void ScreencopyView::updateImplicitSize() { + auto size = this->bImplicitSize.value(); + this->setImplicitSize(size.width(), size.height()); +} + } // namespace qs::wayland::screencopy diff --git a/src/wayland/screencopy/view.hpp b/src/wayland/screencopy/view.hpp index 53f42398..d2b304ec 100644 --- a/src/wayland/screencopy/view.hpp +++ b/src/wayland/screencopy/view.hpp @@ -36,10 +36,13 @@ class ScreencopyView: public QQuickItem { Q_PROPERTY(bool hasContent READ default NOTIFY hasContentChanged BINDABLE bindableHasContent); /// The size of the source image. Valid when @@hasContent is true. Q_PROPERTY(QSize sourceSize READ default NOTIFY sourceSizeChanged BINDABLE bindableSourceSize); + /// If nonzero, the width and height constraints set for this property will constrain those + /// dimensions of the ScreencopyView's implicit size, maintaining the image's aspect ratio. + Q_PROPERTY(QSizeF constraintSize READ default WRITE default NOTIFY constraintSizeChanged BINDABLE bindableConstraintSize); // clang-format on public: - explicit ScreencopyView(QQuickItem* parent = nullptr): QQuickItem(parent) {} + explicit ScreencopyView(QQuickItem* parent = nullptr); void componentComplete() override; @@ -57,6 +60,7 @@ public: [[nodiscard]] QBindable bindableHasContent() { return &this->bHasContent; } [[nodiscard]] QBindable bindableSourceSize() { return &this->bSourceSize; } + [[nodiscard]] QBindable bindableConstraintSize() { return &this->bConstraintSize; } signals: /// The compositor has ended the video stream. Attempting to restart it may or may not work. @@ -67,6 +71,7 @@ signals: void liveChanged(); void hasContentChanged(); void sourceSizeChanged(); + void constraintSizeChanged(); protected: QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data) override; @@ -80,10 +85,13 @@ private slots: private: void destroyContext(bool update = true); void createContext(); + void updateImplicitSize(); // clang-format off Q_OBJECT_BINDABLE_PROPERTY(ScreencopyView, bool, bHasContent, &ScreencopyView::hasContentChanged); Q_OBJECT_BINDABLE_PROPERTY(ScreencopyView, QSize, bSourceSize, &ScreencopyView::sourceSizeChanged); + Q_OBJECT_BINDABLE_PROPERTY(ScreencopyView, QSizeF, bConstraintSize, &ScreencopyView::constraintSizeChanged); + Q_OBJECT_BINDABLE_PROPERTY(ScreencopyView, QSizeF, bImplicitSize, &ScreencopyView::updateImplicitSize); // clang-format on QObject* mCaptureSource = nullptr;