diff --git a/src/wayland/wlr_layershell.cpp b/src/wayland/wlr_layershell.cpp index a649603c..84d3e147 100644 --- a/src/wayland/wlr_layershell.cpp +++ b/src/wayland/wlr_layershell.cpp @@ -71,21 +71,17 @@ bool WlrLayershell::deleteOnInvisible() const { return true; } -void WlrLayershell::setWidth(qint32 width) { - this->mWidth = width; - +void WlrLayershell::trySetWidth(qint32 implicitWidth) { // only update the actual size if not blocked by anchors if (!this->ext->anchors().horizontalConstraint()) { - this->ProxyWindowBase::setWidth(width); + this->ProxyWindowBase::trySetWidth(implicitWidth); } } -void WlrLayershell::setHeight(qint32 height) { - this->mHeight = height; - +void WlrLayershell::trySetHeight(qint32 implicitHeight) { // only update the actual size if not blocked by anchors if (!this->ext->anchors().verticalConstraint()) { - this->ProxyWindowBase::setHeight(height); + this->ProxyWindowBase::trySetHeight(implicitHeight); } } @@ -108,10 +104,11 @@ Anchors WlrLayershell::anchors() const { return this->ext->anchors(); } void WlrLayershell::setAnchors(Anchors anchors) { this->ext->setAnchors(anchors); + if (!this->window) return; // explicitly set width values are tracked so the entire screen isn't covered if an anchor is removed. - if (!anchors.horizontalConstraint()) this->ProxyWindowBase::setWidth(this->mWidth); - if (!anchors.verticalConstraint()) this->ProxyWindowBase::setHeight(this->mHeight); + if (!anchors.horizontalConstraint()) this->ProxyWindowBase::trySetWidth(this->implicitWidth()); + if (!anchors.verticalConstraint()) this->ProxyWindowBase::trySetHeight(this->implicitHeight()); } bool WlrLayershell::aboveWindows() const { return this->layer() > WlrLayer::Bottom; } @@ -190,6 +187,8 @@ WaylandPanelInterface::WaylandPanelInterface(QObject* parent) QObject::connect(this->layer, &ProxyWindowBase::windowConnected, this, &WaylandPanelInterface::windowConnected); QObject::connect(this->layer, &ProxyWindowBase::visibleChanged, this, &WaylandPanelInterface::visibleChanged); QObject::connect(this->layer, &ProxyWindowBase::backerVisibilityChanged, this, &WaylandPanelInterface::backingWindowVisibleChanged); + QObject::connect(this->layer, &ProxyWindowBase::implicitHeightChanged, this, &WaylandPanelInterface::implicitHeightChanged); + QObject::connect(this->layer, &ProxyWindowBase::implicitWidthChanged, this, &WaylandPanelInterface::implicitWidthChanged); QObject::connect(this->layer, &ProxyWindowBase::heightChanged, this, &WaylandPanelInterface::heightChanged); QObject::connect(this->layer, &ProxyWindowBase::widthChanged, this, &WaylandPanelInterface::widthChanged); QObject::connect(this->layer, &ProxyWindowBase::devicePixelRatioChanged, this, &WaylandPanelInterface::devicePixelRatioChanged); @@ -232,6 +231,8 @@ qreal WaylandPanelInterface::devicePixelRatio() const { return this->layer->devi void WaylandPanelInterface::set(type value) { this->layer->set(value); } proxyPair(bool, isVisible, setVisible); +proxyPair(qint32, implicitWidth, setImplicitWidth); +proxyPair(qint32, implicitHeight, setImplicitHeight); proxyPair(qint32, width, setWidth); proxyPair(qint32, height, setHeight); proxyPair(QuickshellScreenInfo*, screen, setScreen); diff --git a/src/wayland/wlr_layershell.hpp b/src/wayland/wlr_layershell.hpp index c3448706..c91f98c8 100644 --- a/src/wayland/wlr_layershell.hpp +++ b/src/wayland/wlr_layershell.hpp @@ -69,8 +69,8 @@ public: void connectWindow() override; [[nodiscard]] bool deleteOnInvisible() const override; - void setWidth(qint32 width) override; - void setHeight(qint32 height) override; + void trySetWidth(qint32 implicitWidth) override; + void trySetHeight(qint32 implicitHeight) override; void setScreen(QuickshellScreenInfo* screen) override; @@ -140,6 +140,12 @@ public: [[nodiscard]] bool isBackingWindowVisible() const override; void setVisible(bool visible) override; + [[nodiscard]] qint32 implicitWidth() const override; + void setImplicitWidth(qint32 implicitWidth) override; + + [[nodiscard]] qint32 implicitHeight() const override; + void setImplicitHeight(qint32 implicitHeight) override; + [[nodiscard]] qint32 width() const override; void setWidth(qint32 width) override; diff --git a/src/wayland/wlr_layershell/surface.cpp b/src/wayland/wlr_layershell/surface.cpp index b0276e45..6aa6c8be 100644 --- a/src/wayland/wlr_layershell/surface.cpp +++ b/src/wayland/wlr_layershell/surface.cpp @@ -1,4 +1,5 @@ #include "surface.hpp" +#include #include #include @@ -61,8 +62,8 @@ toWaylandKeyboardFocus(const WlrKeyboardFocus::Enum& focus) noexcept { [[nodiscard]] QSize constrainedSize(const Anchors& anchors, const QSize& size) noexcept { return QSize( - anchors.horizontalConstraint() ? 0 : size.width(), - anchors.verticalConstraint() ? 0 : size.height() + anchors.horizontalConstraint() ? 0 : std::max(1, size.width()), + anchors.verticalConstraint() ? 0 : std::max(1, size.height()) ); } diff --git a/src/window/floatingwindow.cpp b/src/window/floatingwindow.cpp index 761bc2d4..d11bae49 100644 --- a/src/window/floatingwindow.cpp +++ b/src/window/floatingwindow.cpp @@ -9,15 +9,15 @@ #include "proxywindow.hpp" #include "windowinterface.hpp" -void ProxyFloatingWindow::setWidth(qint32 width) { - if (this->window == nullptr || !this->window->isVisible()) { - this->ProxyWindowBase::setWidth(width); +void ProxyFloatingWindow::trySetWidth(qint32 implicitWidth) { + if (!this->window->isVisible()) { + this->ProxyWindowBase::trySetWidth(implicitWidth); } } -void ProxyFloatingWindow::setHeight(qint32 height) { - if (this->window == nullptr || !this->window->isVisible()) { - this->ProxyWindowBase::setHeight(height); +void ProxyFloatingWindow::trySetHeight(qint32 implicitHeight) { + if (!this->window->isVisible()) { + this->ProxyWindowBase::trySetHeight(implicitHeight); } } @@ -32,6 +32,8 @@ FloatingWindowInterface::FloatingWindowInterface(QObject* parent) QObject::connect(this->window, &ProxyWindowBase::backerVisibilityChanged, this, &FloatingWindowInterface::backingWindowVisibleChanged); QObject::connect(this->window, &ProxyWindowBase::heightChanged, this, &FloatingWindowInterface::heightChanged); QObject::connect(this->window, &ProxyWindowBase::widthChanged, this, &FloatingWindowInterface::widthChanged); + QObject::connect(this->window, &ProxyWindowBase::implicitHeightChanged, this, &FloatingWindowInterface::implicitHeightChanged); + QObject::connect(this->window, &ProxyWindowBase::implicitWidthChanged, this, &FloatingWindowInterface::implicitWidthChanged); QObject::connect(this->window, &ProxyWindowBase::devicePixelRatioChanged, this, &FloatingWindowInterface::devicePixelRatioChanged); QObject::connect(this->window, &ProxyWindowBase::screenChanged, this, &FloatingWindowInterface::screenChanged); QObject::connect(this->window, &ProxyWindowBase::windowTransformChanged, this, &FloatingWindowInterface::windowTransformChanged); @@ -64,6 +66,8 @@ qreal FloatingWindowInterface::devicePixelRatio() const { return this->window->d void FloatingWindowInterface::set(type value) { this->window->set(value); } proxyPair(bool, isVisible, setVisible); +proxyPair(qint32, implicitWidth, setImplicitWidth); +proxyPair(qint32, implicitHeight, setImplicitHeight); proxyPair(qint32, width, setWidth); proxyPair(qint32, height, setHeight); proxyPair(QuickshellScreenInfo*, screen, setScreen); diff --git a/src/window/floatingwindow.hpp b/src/window/floatingwindow.hpp index 7dd0d4ed..f43d0ce8 100644 --- a/src/window/floatingwindow.hpp +++ b/src/window/floatingwindow.hpp @@ -12,10 +12,10 @@ class ProxyFloatingWindow: public ProxyWindowBase { public: explicit ProxyFloatingWindow(QObject* parent = nullptr): ProxyWindowBase(parent) {} - // Setting geometry while the window is visible makes the content item shrinks but not the window + // Setting geometry while the window is visible makes the content item shrink but not the window // which is awful so we disable it for floating windows. - void setWidth(qint32 width) override; - void setHeight(qint32 height) override; + void trySetWidth(qint32 implicitWidth) override; + void trySetHeight(qint32 implicitHeight) override; }; ///! Standard toplevel operating system window that looks like any other application. @@ -36,6 +36,12 @@ public: [[nodiscard]] bool isBackingWindowVisible() const override; void setVisible(bool visible) override; + [[nodiscard]] qint32 implicitWidth() const override; + void setImplicitWidth(qint32 implicitWidth) override; + + [[nodiscard]] qint32 implicitHeight() const override; + void setImplicitHeight(qint32 implicitHeight) override; + [[nodiscard]] qint32 width() const override; void setWidth(qint32 width) override; diff --git a/src/window/proxywindow.cpp b/src/window/proxywindow.cpp index 5224c108..f9633f0e 100644 --- a/src/window/proxywindow.cpp +++ b/src/window/proxywindow.cpp @@ -203,8 +203,8 @@ void ProxyWindowBase::completeWindow() { this->window->setScreen(this->mScreen); } - this->setWidth(this->mWidth); - this->setHeight(this->mHeight); + this->trySetWidth(this->implicitWidth()); + this->trySetHeight(this->implicitHeight()); this->setColor(this->mColor); this->updateMask(); @@ -299,28 +299,52 @@ qint32 ProxyWindowBase::y() const { else return this->window->y(); } +qint32 ProxyWindowBase::implicitWidth() const { return this->mImplicitWidth; } + +void ProxyWindowBase::setImplicitWidth(qint32 implicitWidth) { + if (implicitWidth == this->mImplicitWidth) return; + this->mImplicitWidth = implicitWidth; + emit this->implicitWidthChanged(); + + if (this->window) this->trySetWidth(implicitWidth); + else emit this->widthChanged(); +} + +void ProxyWindowBase::trySetWidth(qint32 implicitWidth) { this->window->setWidth(implicitWidth); } + +qint32 ProxyWindowBase::implicitHeight() const { return this->mImplicitHeight; } + +void ProxyWindowBase::setImplicitHeight(qint32 implicitHeight) { + if (implicitHeight == this->mImplicitHeight) return; + this->mImplicitHeight = implicitHeight; + emit this->implicitHeightChanged(); + + if (this->window) this->trySetHeight(implicitHeight); + else emit this->heightChanged(); +} + +void ProxyWindowBase::trySetHeight(qint32 implicitHeight) { + this->window->setHeight(implicitHeight); +} + qint32 ProxyWindowBase::width() const { - if (this->window == nullptr) return this->mWidth; + if (this->window == nullptr) return this->implicitWidth(); else return this->window->width(); } void ProxyWindowBase::setWidth(qint32 width) { - this->mWidth = width; - if (this->window == nullptr) { - emit this->widthChanged(); - } else this->window->setWidth(width); + this->setImplicitWidth(width); + qmlWarning(this) << "Setting `width` is deprecated. Set `implicitWidth` instead."; } qint32 ProxyWindowBase::height() const { - if (this->window == nullptr) return this->mHeight; + if (this->window == nullptr) return this->implicitHeight(); else return this->window->height(); } void ProxyWindowBase::setHeight(qint32 height) { - this->mHeight = height; - if (this->window == nullptr) { - emit this->heightChanged(); - } else this->window->setHeight(height); + this->setImplicitHeight(height); + qmlWarning(this) << "Setting `height` is deprecated. Set `implicitHeight` instead."; } void ProxyWindowBase::setScreen(QuickshellScreenInfo* screen) { diff --git a/src/window/proxywindow.hpp b/src/window/proxywindow.hpp index 92a85f4f..1cf5a02f 100644 --- a/src/window/proxywindow.hpp +++ b/src/window/proxywindow.hpp @@ -42,6 +42,8 @@ class ProxyWindowBase: public Reloadable { Q_PROPERTY(QQuickWindow* _backingWindow READ backingWindow); Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT); Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged); + Q_PROPERTY(qint32 implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged); + Q_PROPERTY(qint32 implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged); Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged); Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged); Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged); @@ -92,11 +94,20 @@ public: [[nodiscard]] virtual qint32 x() const; [[nodiscard]] virtual qint32 y() const; + [[nodiscard]] qint32 implicitWidth() const; + void setImplicitWidth(qint32 implicitWidth); + + [[nodiscard]] qint32 implicitHeight() const; + void setImplicitHeight(qint32 implicitHeight); + [[nodiscard]] virtual qint32 width() const; - virtual void setWidth(qint32 width); + void setWidth(qint32 width); [[nodiscard]] virtual qint32 height() const; - virtual void setHeight(qint32 height); + void setHeight(qint32 height); + + virtual void trySetWidth(qint32 implicitWidth); + virtual void trySetHeight(qint32 implicitHeight); [[nodiscard]] qreal devicePixelRatio() const; @@ -124,6 +135,8 @@ signals: void backerVisibilityChanged(); void xChanged(); void yChanged(); + void implicitWidthChanged(); + void implicitHeightChanged(); void widthChanged(); void heightChanged(); void devicePixelRatioChanged(); @@ -145,8 +158,8 @@ protected slots: protected: bool mVisible = true; - qint32 mWidth = 100; - qint32 mHeight = 100; + qint32 mImplicitWidth = 100; + qint32 mImplicitHeight = 100; QScreen* mScreen = nullptr; QColor mColor = Qt::white; PendingRegion* mMask = nullptr; diff --git a/src/window/windowinterface.hpp b/src/window/windowinterface.hpp index 2aca7a76..894a5aa9 100644 --- a/src/window/windowinterface.hpp +++ b/src/window/windowinterface.hpp @@ -53,7 +53,17 @@ class WindowInterface: public Reloadable { /// This property is useful for ensuring windows spawn in a specific order, and you should /// not use it in place of [visible](#prop.visible). Q_PROPERTY(bool backingWindowVisible READ isBackingWindowVisible NOTIFY backingWindowVisibleChanged); + /// The window's desired width. + Q_PROPERTY(qint32 implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged); + /// The window's desired height. + Q_PROPERTY(qint32 implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged); + /// The window's actual width. + /// + /// Setting this property is deprecated. Set @@implicitWidth instead. Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged); + /// The window's actual height. + /// + /// Setting this property is deprecated. Set @@implicitHeight instead. Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged); /// The ratio between logical pixels and monitor pixels. /// @@ -147,6 +157,12 @@ public: [[nodiscard]] virtual bool isBackingWindowVisible() const = 0; virtual void setVisible(bool visible) = 0; + [[nodiscard]] virtual qint32 implicitWidth() const = 0; + virtual void setImplicitWidth(qint32 implicitWidth) = 0; + + [[nodiscard]] virtual qint32 implicitHeight() const = 0; + virtual void setImplicitHeight(qint32 implicitHeight) = 0; + [[nodiscard]] virtual qint32 width() const = 0; virtual void setWidth(qint32 width) = 0; @@ -177,6 +193,8 @@ signals: void windowConnected(); void visibleChanged(); void backingWindowVisibleChanged(); + void implicitWidthChanged(); + void implicitHeightChanged(); void widthChanged(); void heightChanged(); void devicePixelRatioChanged(); diff --git a/src/x11/panel_window.cpp b/src/x11/panel_window.cpp index ac182f76..a81b6162 100644 --- a/src/x11/panel_window.cpp +++ b/src/x11/panel_window.cpp @@ -126,22 +126,18 @@ void XPanelWindow::connectWindow() { } } -void XPanelWindow::setWidth(qint32 width) { - this->mWidth = width; - +void XPanelWindow::trySetWidth(qint32 implicitWidth) { // only update the actual size if not blocked by anchors if (!this->mAnchors.horizontalConstraint()) { - this->ProxyWindowBase::setWidth(width); + this->ProxyWindowBase::trySetWidth(implicitWidth); this->updateDimensions(); } } -void XPanelWindow::setHeight(qint32 height) { - this->mHeight = height; - +void XPanelWindow::trySetHeight(qint32 implicitHeight) { // only update the actual size if not blocked by anchors if (!this->mAnchors.verticalConstraint()) { - this->ProxyWindowBase::setHeight(height); + this->ProxyWindowBase::trySetHeight(implicitHeight); this->updateDimensions(); } } @@ -307,13 +303,14 @@ void XPanelWindow::updateDimensions(bool propagate) { geometry.setX(screenGeometry.x() + this->mMargins.mLeft); } else if (this->mAnchors.mRight) { geometry.setX( - screenGeometry.x() + screenGeometry.width() - this->mWidth - this->mMargins.mRight + screenGeometry.x() + screenGeometry.width() - this->implicitWidth() + - this->mMargins.mRight ); } else { - geometry.setX(screenGeometry.x() + screenGeometry.width() / 2 - this->mWidth / 2); + geometry.setX(screenGeometry.x() + screenGeometry.width() / 2 - this->implicitWidth() / 2); } - geometry.setWidth(this->mWidth); + geometry.setWidth(this->implicitWidth()); } if (this->mAnchors.verticalConstraint()) { @@ -324,13 +321,14 @@ void XPanelWindow::updateDimensions(bool propagate) { geometry.setY(screenGeometry.y() + this->mMargins.mTop); } else if (this->mAnchors.mBottom) { geometry.setY( - screenGeometry.y() + screenGeometry.height() - this->mHeight - this->mMargins.mBottom + screenGeometry.y() + screenGeometry.height() - this->implicitHeight() + - this->mMargins.mBottom ); } else { - geometry.setY(screenGeometry.y() + screenGeometry.height() / 2 - this->mHeight / 2); + geometry.setY(screenGeometry.y() + screenGeometry.height() / 2 - this->implicitHeight() / 2); } - geometry.setHeight(this->mHeight); + geometry.setHeight(this->implicitHeight()); } this->window->setGeometry(geometry); @@ -378,9 +376,11 @@ void XPanelWindow::getExclusion(int& side, quint32& exclusiveZone) { if (autoExclude) { if (side == 0 || side == 1) { - exclusiveZone = this->mWidth + (side == 0 ? this->mMargins.mLeft : this->mMargins.mRight); + exclusiveZone = + this->implicitWidth() + (side == 0 ? this->mMargins.mLeft : this->mMargins.mRight); } else { - exclusiveZone = this->mHeight + (side == 2 ? this->mMargins.mTop : this->mMargins.mBottom); + exclusiveZone = + this->implicitHeight() + (side == 2 ? this->mMargins.mTop : this->mMargins.mBottom); } } else { exclusiveZone = this->mExclusiveZone; @@ -476,6 +476,8 @@ XPanelInterface::XPanelInterface(QObject* parent) QObject::connect(this->panel, &ProxyWindowBase::windowConnected, this, &XPanelInterface::windowConnected); QObject::connect(this->panel, &ProxyWindowBase::visibleChanged, this, &XPanelInterface::visibleChanged); QObject::connect(this->panel, &ProxyWindowBase::backerVisibilityChanged, this, &XPanelInterface::backingWindowVisibleChanged); + QObject::connect(this->panel, &ProxyWindowBase::implicitHeightChanged, this, &XPanelInterface::implicitHeightChanged); + QObject::connect(this->panel, &ProxyWindowBase::implicitWidthChanged, this, &XPanelInterface::implicitWidthChanged); QObject::connect(this->panel, &ProxyWindowBase::heightChanged, this, &XPanelInterface::heightChanged); QObject::connect(this->panel, &ProxyWindowBase::widthChanged, this, &XPanelInterface::widthChanged); QObject::connect(this->panel, &ProxyWindowBase::devicePixelRatioChanged, this, &XPanelInterface::devicePixelRatioChanged); @@ -514,6 +516,8 @@ qreal XPanelInterface::devicePixelRatio() const { return this->panel->devicePixe void XPanelInterface::set(type value) { this->panel->set(value); } proxyPair(bool, isVisible, setVisible); +proxyPair(qint32, implicitWidth, setImplicitWidth); +proxyPair(qint32, implicitHeight, setImplicitHeight); proxyPair(qint32, width, setWidth); proxyPair(qint32, height, setHeight); proxyPair(QuickshellScreenInfo*, screen, setScreen); diff --git a/src/x11/panel_window.hpp b/src/x11/panel_window.hpp index 11041f22..d8cc9661 100644 --- a/src/x11/panel_window.hpp +++ b/src/x11/panel_window.hpp @@ -46,8 +46,8 @@ public: void connectWindow() override; - void setWidth(qint32 width) override; - void setHeight(qint32 height) override; + void trySetWidth(qint32 implicitWidth) override; + void trySetHeight(qint32 implicitHeight) override; void setScreen(QuickshellScreenInfo* screen) override; @@ -121,6 +121,12 @@ public: [[nodiscard]] bool isBackingWindowVisible() const override; void setVisible(bool visible) override; + [[nodiscard]] qint32 implicitWidth() const override; + void setImplicitWidth(qint32 implicitWidth) override; + + [[nodiscard]] qint32 implicitHeight() const override; + void setImplicitHeight(qint32 implicitHeight) override; + [[nodiscard]] qint32 width() const override; void setWidth(qint32 width) override;