forked from quickshell/quickshell
core/popupanchor: add margins property
This commit is contained in:
parent
ef077ddd24
commit
d1df932d60
3 changed files with 42 additions and 21 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include <qquickitem.h>
|
#include <qquickitem.h>
|
||||||
#include <qsize.h>
|
#include <qsize.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
|
#include <qvectornd.h>
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
|
|
||||||
#include "../window/proxywindow.hpp"
|
#include "../window/proxywindow.hpp"
|
||||||
|
@ -126,12 +127,21 @@ void PopupAnchor::setRect(Box rect) {
|
||||||
this->mUserRect = rect;
|
this->mUserRect = rect;
|
||||||
emit this->rectChanged();
|
emit this->rectChanged();
|
||||||
|
|
||||||
this->setWindowRect(rect);
|
this->setWindowRect(rect.qrect().marginsRemoved(this->mMargins.qmargins()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupAnchor::setWindowRect(Box rect) {
|
void PopupAnchor::setMargins(Margins margins) {
|
||||||
if (rect.w <= 0) rect.w = 1;
|
if (margins == this->mMargins) return;
|
||||||
if (rect.h <= 0) rect.h = 1;
|
|
||||||
|
this->mMargins = margins;
|
||||||
|
emit this->marginsChanged();
|
||||||
|
|
||||||
|
this->setWindowRect(this->mUserRect.qrect().marginsRemoved(margins.qmargins()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupAnchor::setWindowRect(QRect rect) {
|
||||||
|
if (rect.width() <= 0) rect.setWidth(1);
|
||||||
|
if (rect.height() <= 0) rect.setHeight(1);
|
||||||
if (rect == this->state.rect) return;
|
if (rect == this->state.rect) return;
|
||||||
|
|
||||||
this->state.rect = rect;
|
this->state.rect = rect;
|
||||||
|
@ -177,12 +187,14 @@ void PopupAnchor::updatePlacement(const QPoint& anchorpoint, const QSize& size)
|
||||||
|
|
||||||
void PopupAnchor::updateAnchor() {
|
void PopupAnchor::updateAnchor() {
|
||||||
if (this->mItem && this->mProxyWindow) {
|
if (this->mItem && this->mProxyWindow) {
|
||||||
auto rect = this->mProxyWindow->contentItem()->mapRectFromItem(
|
auto baseRect =
|
||||||
|
this->mUserRect.isEmpty() ? this->mItem->boundingRect() : this->mUserRect.qrect();
|
||||||
|
auto rect = this->mProxyWindow->contentItem()->mapFromItem(
|
||||||
this->mItem,
|
this->mItem,
|
||||||
this->mUserRect.isEmpty() ? this->mItem->boundingRect() : this->mUserRect.qrect()
|
baseRect.marginsRemoved(this->mMargins.qmargins())
|
||||||
);
|
);
|
||||||
|
|
||||||
this->setWindowRect(rect);
|
this->setWindowRect(rect.toRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
emit this->anchoring();
|
emit this->anchoring();
|
||||||
|
@ -207,7 +219,7 @@ void PopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bool only
|
||||||
|
|
||||||
auto adjustment = anchor->adjustment();
|
auto adjustment = anchor->adjustment();
|
||||||
auto screenGeometry = parentWindow->screen()->geometry();
|
auto screenGeometry = parentWindow->screen()->geometry();
|
||||||
auto anchorRectGeometry = anchor->windowRect().qrect().translated(parentGeometry.topLeft());
|
auto anchorRectGeometry = anchor->windowRect().translated(parentGeometry.topLeft());
|
||||||
|
|
||||||
auto anchorEdges = anchor->edges();
|
auto anchorEdges = anchor->edges();
|
||||||
auto anchorGravity = anchor->gravity();
|
auto anchorGravity = anchor->gravity();
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <qtclasshelpermacros.h>
|
#include <qtclasshelpermacros.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
|
#include <qvariant.h>
|
||||||
|
#include <qvectornd.h>
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
|
|
||||||
#include "../window/proxywindow.hpp"
|
#include "../window/proxywindow.hpp"
|
||||||
|
@ -61,7 +63,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(PopupAdjustment::Flags);
|
||||||
struct PopupAnchorState {
|
struct PopupAnchorState {
|
||||||
bool operator==(const PopupAnchorState& other) const;
|
bool operator==(const PopupAnchorState& other) const;
|
||||||
|
|
||||||
Box rect = {0, 0, 1, 1};
|
QRect rect = {0, 0, 1, 1};
|
||||||
Edges::Flags edges = Edges::Top | Edges::Left;
|
Edges::Flags edges = Edges::Top | Edges::Left;
|
||||||
Edges::Flags gravity = Edges::Bottom | Edges::Right;
|
Edges::Flags gravity = Edges::Bottom | Edges::Right;
|
||||||
PopupAdjustment::Flags adjustment = PopupAdjustment::Slide;
|
PopupAdjustment::Flags adjustment = PopupAdjustment::Slide;
|
||||||
|
@ -90,12 +92,19 @@ class PopupAnchor: public QObject {
|
||||||
/// The anchorpoints the popup will attach to, relative to @@item or @@window.
|
/// The anchorpoints the popup will attach to, relative to @@item or @@window.
|
||||||
/// Which anchors will be used is determined by the @@edges, @@gravity, and @@adjustment.
|
/// Which anchors will be used is determined by the @@edges, @@gravity, and @@adjustment.
|
||||||
///
|
///
|
||||||
|
/// If using @@item, the default anchor rectangle matches the dimensions of the item.
|
||||||
|
///
|
||||||
/// If you leave @@edges, @@gravity and @@adjustment at their default values,
|
/// If you leave @@edges, @@gravity and @@adjustment at their default values,
|
||||||
/// setting more than `x` and `y` does not matter. The anchor rect cannot
|
/// setting more than `x` and `y` does not matter. The anchor rect cannot
|
||||||
/// be smaller than 1x1 pixels.
|
/// be smaller than 1x1 pixels.
|
||||||
///
|
///
|
||||||
/// [coordinate mapping functions]: https://doc.qt.io/qt-6/qml-qtquick-item.html#mapFromItem-method
|
/// [coordinate mapping functions]: https://doc.qt.io/qt-6/qml-qtquick-item.html#mapFromItem-method
|
||||||
Q_PROPERTY(Box rect READ rect WRITE setRect RESET resetRect NOTIFY rectChanged);
|
Q_PROPERTY(Box rect READ rect WRITE setRect RESET resetRect NOTIFY rectChanged);
|
||||||
|
/// A margin applied to the anchor rect.
|
||||||
|
///
|
||||||
|
/// This is most useful when @@item is used and @@rect is left at its default
|
||||||
|
/// value (matching the Item's dimensions).
|
||||||
|
Q_PROPERTY(Margins margins READ margins WRITE setMargins NOTIFY marginsChanged);
|
||||||
/// The point on the anchor rectangle the popup should anchor to.
|
/// The point on the anchor rectangle the popup should anchor to.
|
||||||
/// Opposing edges suchs as `Edges.Left | Edges.Right` are not allowed.
|
/// Opposing edges suchs as `Edges.Left | Edges.Right` are not allowed.
|
||||||
///
|
///
|
||||||
|
@ -138,13 +147,16 @@ public:
|
||||||
[[nodiscard]] QQuickItem* item() const { return this->mItem; }
|
[[nodiscard]] QQuickItem* item() const { return this->mItem; }
|
||||||
void setItem(QQuickItem* item);
|
void setItem(QQuickItem* item);
|
||||||
|
|
||||||
[[nodiscard]] Box windowRect() const { return this->state.rect; }
|
[[nodiscard]] QRect windowRect() const { return this->state.rect; }
|
||||||
void setWindowRect(Box rect);
|
void setWindowRect(QRect rect);
|
||||||
|
|
||||||
[[nodiscard]] Box rect() const { return this->mUserRect; }
|
[[nodiscard]] Box rect() const { return this->mUserRect; }
|
||||||
void setRect(Box rect);
|
void setRect(Box rect);
|
||||||
void resetRect();
|
void resetRect();
|
||||||
|
|
||||||
|
[[nodiscard]] Margins margins() const { return this->mMargins; }
|
||||||
|
void setMargins(Margins margins);
|
||||||
|
|
||||||
[[nodiscard]] Edges::Flags edges() const { return this->state.edges; }
|
[[nodiscard]] Edges::Flags edges() const { return this->state.edges; }
|
||||||
void setEdges(Edges::Flags edges);
|
void setEdges(Edges::Flags edges);
|
||||||
|
|
||||||
|
@ -168,6 +180,7 @@ signals:
|
||||||
QSDOC_HIDE void backingWindowVisibilityChanged();
|
QSDOC_HIDE void backingWindowVisibilityChanged();
|
||||||
QSDOC_HIDE void windowRectChanged();
|
QSDOC_HIDE void windowRectChanged();
|
||||||
void rectChanged();
|
void rectChanged();
|
||||||
|
void marginsChanged();
|
||||||
void edgesChanged();
|
void edgesChanged();
|
||||||
void gravityChanged();
|
void gravityChanged();
|
||||||
void adjustmentChanged();
|
void adjustmentChanged();
|
||||||
|
@ -183,6 +196,7 @@ private:
|
||||||
ProxyWindowBase* mProxyWindow = nullptr;
|
ProxyWindowBase* mProxyWindow = nullptr;
|
||||||
PopupAnchorState state;
|
PopupAnchorState state;
|
||||||
Box mUserRect;
|
Box mUserRect;
|
||||||
|
Margins mMargins;
|
||||||
std::optional<PopupAnchorState> lastState;
|
std::optional<PopupAnchorState> lastState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,11 @@ void WaylandPopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bo
|
||||||
auto anchorRect = anchor->windowRect();
|
auto anchorRect = anchor->windowRect();
|
||||||
|
|
||||||
if (auto* p = window->transientParent()) {
|
if (auto* p = window->transientParent()) {
|
||||||
anchorRect.x = QHighDpi::toNativePixels(anchorRect.x, p);
|
anchorRect = QHighDpi::toNativePixels(anchorRect, p);
|
||||||
anchorRect.y = QHighDpi::toNativePixels(anchorRect.y, p);
|
|
||||||
anchorRect.w = QHighDpi::toNativePixels(anchorRect.w, p);
|
|
||||||
anchorRect.h = QHighDpi::toNativePixels(anchorRect.h, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
positioner.set_anchor_rect(anchorRect.x, anchorRect.y, anchorRect.w, anchorRect.h);
|
positioner
|
||||||
|
.set_anchor_rect(anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
|
||||||
|
|
||||||
XdgPositioner::anchor anchorFlag = XdgPositioner::anchor_none;
|
XdgPositioner::anchor anchorFlag = XdgPositioner::anchor_none;
|
||||||
switch (anchor->edges()) {
|
switch (anchor->edges()) {
|
||||||
|
@ -107,15 +105,12 @@ void WaylandPopupPositioner::setFlags(PopupAnchor* anchor, QWindow* window) {
|
||||||
auto anchorRect = anchor->windowRect();
|
auto anchorRect = anchor->windowRect();
|
||||||
|
|
||||||
if (auto* p = window->transientParent()) {
|
if (auto* p = window->transientParent()) {
|
||||||
anchorRect.x = QHighDpi::toNativePixels(anchorRect.x, p);
|
anchorRect = QHighDpi::toNativePixels(anchorRect, p);
|
||||||
anchorRect.y = QHighDpi::toNativePixels(anchorRect.y, p);
|
|
||||||
anchorRect.w = QHighDpi::toNativePixels(anchorRect.w, p);
|
|
||||||
anchorRect.h = QHighDpi::toNativePixels(anchorRect.h, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
window->setProperty("_q_waylandPopupConstraintAdjustment", anchor->adjustment().toInt());
|
window->setProperty("_q_waylandPopupConstraintAdjustment", anchor->adjustment().toInt());
|
||||||
window->setProperty("_q_waylandPopupAnchorRect", anchorRect.qrect());
|
window->setProperty("_q_waylandPopupAnchorRect", anchorRect);
|
||||||
window->setProperty("_q_waylandPopupAnchor", QVariant::fromValue(Edges::toQt(anchor->edges())));
|
window->setProperty("_q_waylandPopupAnchor", QVariant::fromValue(Edges::toQt(anchor->edges())));
|
||||||
window->setProperty("_q_waylandPopupGravity", QVariant::fromValue(Edges::toQt(anchor->gravity())));
|
window->setProperty("_q_waylandPopupGravity", QVariant::fromValue(Edges::toQt(anchor->gravity())));
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue