forked from quickshell/quickshell
feat(wayland): custom layershell implementation
A fair amount of things are broken but not in the layershell interface itself. The shell window platform extensions are next in line for refactoring and relevent issues will be fixed then. Same for docs.
This commit is contained in:
parent
b0567a569b
commit
4a82949854
21 changed files with 1167 additions and 401 deletions
|
@ -16,13 +16,4 @@ qt_add_executable(quickshell
|
|||
|
||||
qt_add_qml_module(quickshell URI QuickShell)
|
||||
|
||||
target_link_libraries(quickshell PRIVATE ${QT_DEPS} quickshell-wayland)
|
||||
|
||||
if (LAYERSHELL)
|
||||
find_package(LayerShellQt REQUIRED)
|
||||
|
||||
target_link_libraries(quickshell PRIVATE LayerShellQtInterface)
|
||||
target_compile_definitions(quickshell PRIVATE CONF_LAYERSHELL)
|
||||
|
||||
target_sources(quickshell PRIVATE layershell.cpp)
|
||||
endif()
|
||||
target_link_libraries(quickshell PRIVATE ${QT_DEPS} quickshell-waylandplugin)
|
||||
|
|
|
@ -1,300 +0,0 @@
|
|||
#include "layershell.hpp"
|
||||
|
||||
#include <LayerShellQt/window.h>
|
||||
#include <qmargins.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qquickitem.h>
|
||||
#include <qquickwindow.h>
|
||||
#include <qscreen.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
#include <qwindow.h>
|
||||
|
||||
#include "proxywindow.hpp"
|
||||
#include "shellwindow.hpp"
|
||||
|
||||
WaylandShellWindow::WaylandShellWindow(QObject* parent):
|
||||
ProxyShellWindow(parent), mWayland(new WaylandShellWindowExtensions(this)) {}
|
||||
|
||||
void WaylandShellWindow::setupWindow() {
|
||||
this->shellWindow = LayerShellQt::Window::get(this->window);
|
||||
|
||||
this->ProxyShellWindow::setupWindow();
|
||||
|
||||
// clang-format off
|
||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::anchorsChanged, this, &ProxyShellWindow::anchorsChanged);
|
||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::marginsChanged, this, &ProxyShellWindow::marginsChanged);
|
||||
|
||||
QObject::connect(
|
||||
this->shellWindow, &LayerShellQt::Window::layerChanged,
|
||||
this->mWayland, &WaylandShellWindowExtensions::layerChanged
|
||||
);
|
||||
QObject::connect(
|
||||
this->shellWindow, &LayerShellQt::Window::keyboardInteractivityChanged,
|
||||
this->mWayland, &WaylandShellWindowExtensions::keyboardFocusChanged
|
||||
);
|
||||
|
||||
QObject::connect(this->window, &QWindow::widthChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||
QObject::connect(this->window, &QWindow::heightChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||
QObject::connect(this, &ProxyShellWindow::anchorsChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||
QObject::connect(this, &ProxyShellWindow::marginsChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||
// clang-format on
|
||||
|
||||
this->setAnchors(this->mAnchors);
|
||||
this->setMargins(this->mMargins);
|
||||
this->setExclusionMode(this->mExclusionMode); // also sets exclusion zone
|
||||
this->mWayland->setLayer(this->mLayer);
|
||||
this->shellWindow->setScope(this->mScope);
|
||||
this->mWayland->setKeyboardFocus(this->mKeyboardFocus);
|
||||
|
||||
this->connected = true;
|
||||
}
|
||||
|
||||
QQuickWindow* WaylandShellWindow::disownWindow() {
|
||||
QObject::disconnect(this->shellWindow, nullptr, this, nullptr);
|
||||
return this->ProxyWindowBase::disownWindow();
|
||||
}
|
||||
|
||||
void WaylandShellWindow::setWidth(qint32 width) {
|
||||
this->mWidth = width;
|
||||
|
||||
// only update the actual size if not blocked by anchors
|
||||
auto anchors = this->anchors();
|
||||
if (!anchors.mLeft || !anchors.mRight) this->ProxyShellWindow::setWidth(width);
|
||||
}
|
||||
|
||||
void WaylandShellWindow::setHeight(qint32 height) {
|
||||
this->mHeight = height;
|
||||
|
||||
// only update the actual size if not blocked by anchors
|
||||
auto anchors = this->anchors();
|
||||
if (!anchors.mTop || !anchors.mBottom) this->ProxyShellWindow::setHeight(height);
|
||||
}
|
||||
|
||||
void WaylandShellWindow::setAnchors(Anchors anchors) {
|
||||
if (this->window == nullptr) {
|
||||
this->mAnchors = anchors;
|
||||
return;
|
||||
}
|
||||
|
||||
auto lsAnchors = LayerShellQt::Window::Anchors();
|
||||
if (anchors.mLeft) lsAnchors |= LayerShellQt::Window::AnchorLeft;
|
||||
if (anchors.mRight) lsAnchors |= LayerShellQt::Window::AnchorRight;
|
||||
if (anchors.mTop) lsAnchors |= LayerShellQt::Window::AnchorTop;
|
||||
if (anchors.mBottom) lsAnchors |= LayerShellQt::Window::AnchorBottom;
|
||||
|
||||
if (!anchors.mLeft || !anchors.mRight) this->ProxyWindowBase::setWidth(this->mWidth);
|
||||
if (!anchors.mTop || !anchors.mBottom) this->ProxyWindowBase::setHeight(this->mHeight);
|
||||
|
||||
this->shellWindow->setAnchors(lsAnchors);
|
||||
}
|
||||
|
||||
Anchors WaylandShellWindow::anchors() const {
|
||||
if (this->window == nullptr) return this->mAnchors;
|
||||
|
||||
auto lsAnchors = this->shellWindow->anchors();
|
||||
|
||||
Anchors anchors;
|
||||
anchors.mLeft = lsAnchors.testFlag(LayerShellQt::Window::AnchorLeft);
|
||||
anchors.mRight = lsAnchors.testFlag(LayerShellQt::Window::AnchorRight);
|
||||
anchors.mTop = lsAnchors.testFlag(LayerShellQt::Window::AnchorTop);
|
||||
anchors.mBottom = lsAnchors.testFlag(LayerShellQt::Window::AnchorBottom);
|
||||
|
||||
return anchors;
|
||||
}
|
||||
|
||||
void WaylandShellWindow::setExclusiveZone(qint32 zone) {
|
||||
if (zone < 0) zone = 0;
|
||||
if (this->connected && zone == this->mExclusionZone) return;
|
||||
this->mExclusionZone = zone;
|
||||
|
||||
if (this->window != nullptr && this->exclusionMode() == ExclusionMode::Normal) {
|
||||
this->shellWindow->setExclusiveZone(zone);
|
||||
emit this->exclusionZoneChanged();
|
||||
}
|
||||
}
|
||||
|
||||
qint32 WaylandShellWindow::exclusiveZone() const {
|
||||
if (this->window == nullptr) return this->mExclusionZone;
|
||||
else return this->shellWindow->exclusionZone();
|
||||
}
|
||||
|
||||
ExclusionMode::Enum WaylandShellWindow::exclusionMode() const { return this->mExclusionMode; }
|
||||
|
||||
void WaylandShellWindow::setExclusionMode(ExclusionMode::Enum exclusionMode) {
|
||||
if (this->connected && exclusionMode == this->mExclusionMode) return;
|
||||
this->mExclusionMode = exclusionMode;
|
||||
|
||||
if (this->window != nullptr) {
|
||||
if (exclusionMode == ExclusionMode::Normal) {
|
||||
this->shellWindow->setExclusiveZone(this->mExclusionZone);
|
||||
emit this->exclusionZoneChanged();
|
||||
} else if (exclusionMode == ExclusionMode::Ignore) {
|
||||
this->shellWindow->setExclusiveZone(-1);
|
||||
emit this->exclusionZoneChanged();
|
||||
} else {
|
||||
this->updateExclusionZone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandShellWindow::setMargins(Margins margins) {
|
||||
if (this->window == nullptr) this->mMargins = margins;
|
||||
else {
|
||||
auto lsMargins = QMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom);
|
||||
this->shellWindow->setMargins(lsMargins);
|
||||
}
|
||||
}
|
||||
|
||||
Margins WaylandShellWindow::margins() const {
|
||||
if (this->window == nullptr) return this->mMargins;
|
||||
auto lsMargins = this->shellWindow->margins();
|
||||
|
||||
auto margins = Margins();
|
||||
margins.mLeft = lsMargins.left();
|
||||
margins.mRight = lsMargins.right();
|
||||
margins.mTop = lsMargins.top();
|
||||
margins.mBottom = lsMargins.bottom();
|
||||
|
||||
return margins;
|
||||
}
|
||||
|
||||
void WaylandShellWindowExtensions::setLayer(Layer::Enum layer) {
|
||||
if (this->window->window == nullptr) {
|
||||
this->window->mLayer = layer;
|
||||
return;
|
||||
}
|
||||
|
||||
auto lsLayer = LayerShellQt::Window::LayerBackground;
|
||||
|
||||
// clang-format off
|
||||
switch (layer) {
|
||||
case Layer::Background: lsLayer = LayerShellQt::Window::LayerBackground; break;
|
||||
case Layer::Bottom: lsLayer = LayerShellQt::Window::LayerBottom; break;
|
||||
case Layer::Top: lsLayer = LayerShellQt::Window::LayerTop; break;
|
||||
case Layer::Overlay: lsLayer = LayerShellQt::Window::LayerOverlay; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
this->window->shellWindow->setLayer(lsLayer);
|
||||
}
|
||||
|
||||
Layer::Enum WaylandShellWindowExtensions::layer() const {
|
||||
if (this->window->window == nullptr) return this->window->mLayer;
|
||||
|
||||
auto layer = Layer::Top;
|
||||
auto lsLayer = this->window->shellWindow->layer();
|
||||
|
||||
// clang-format off
|
||||
switch (lsLayer) {
|
||||
case LayerShellQt::Window::LayerBackground: layer = Layer::Background; break;
|
||||
case LayerShellQt::Window::LayerBottom: layer = Layer::Bottom; break;
|
||||
case LayerShellQt::Window::LayerTop: layer = Layer::Top; break;
|
||||
case LayerShellQt::Window::LayerOverlay: layer = Layer::Overlay; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
void WaylandShellWindowExtensions::setScope(const QString& scope) {
|
||||
if (this->window->window == nullptr) this->window->mScope = scope;
|
||||
else this->window->shellWindow->setScope(scope);
|
||||
}
|
||||
|
||||
QString WaylandShellWindowExtensions::scope() const {
|
||||
if (this->window->window == nullptr) return this->window->mScope;
|
||||
else return this->window->shellWindow->scope();
|
||||
}
|
||||
|
||||
void WaylandShellWindowExtensions::setKeyboardFocus(KeyboardFocus::Enum focus) {
|
||||
if (this->window->window == nullptr) {
|
||||
this->window->mKeyboardFocus = focus;
|
||||
return;
|
||||
}
|
||||
|
||||
auto lsFocus = LayerShellQt::Window::KeyboardInteractivityNone;
|
||||
|
||||
// clang-format off
|
||||
switch (focus) {
|
||||
case KeyboardFocus::None: lsFocus = LayerShellQt::Window::KeyboardInteractivityNone; break;
|
||||
case KeyboardFocus::Exclusive: lsFocus = LayerShellQt::Window::KeyboardInteractivityExclusive; break;
|
||||
case KeyboardFocus::OnDemand: lsFocus = LayerShellQt::Window::KeyboardInteractivityOnDemand; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
this->window->shellWindow->setKeyboardInteractivity(lsFocus);
|
||||
}
|
||||
|
||||
KeyboardFocus::Enum WaylandShellWindowExtensions::keyboardFocus() const {
|
||||
if (this->window->window == nullptr) return this->window->mKeyboardFocus;
|
||||
|
||||
auto focus = KeyboardFocus::None;
|
||||
auto lsFocus = this->window->shellWindow->keyboardInteractivity();
|
||||
|
||||
// clang-format off
|
||||
switch (lsFocus) {
|
||||
case LayerShellQt::Window::KeyboardInteractivityNone: focus = KeyboardFocus::None; break;
|
||||
case LayerShellQt::Window::KeyboardInteractivityExclusive: focus = KeyboardFocus::Exclusive; break;
|
||||
case LayerShellQt::Window::KeyboardInteractivityOnDemand: focus = KeyboardFocus::OnDemand; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return focus;
|
||||
}
|
||||
|
||||
void WaylandShellWindowExtensions::setScreenConfiguration(ScreenConfiguration::Enum configuration) {
|
||||
if (this->window->window == nullptr) {
|
||||
this->window->mScreenConfiguration = configuration;
|
||||
return;
|
||||
}
|
||||
|
||||
auto lsConfiguration = LayerShellQt::Window::ScreenFromQWindow;
|
||||
|
||||
// clang-format off
|
||||
switch (configuration) {
|
||||
case ScreenConfiguration::Window: lsConfiguration = LayerShellQt::Window::ScreenFromQWindow; break;
|
||||
case ScreenConfiguration::Compositor: lsConfiguration = LayerShellQt::Window::ScreenFromCompositor; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
this->window->shellWindow->setScreenConfiguration(lsConfiguration);
|
||||
}
|
||||
|
||||
ScreenConfiguration::Enum WaylandShellWindowExtensions::screenConfiguration() const {
|
||||
if (this->window->window == nullptr) return this->window->mScreenConfiguration;
|
||||
|
||||
auto configuration = ScreenConfiguration::Window;
|
||||
auto lsConfiguration = this->window->shellWindow->screenConfiguration();
|
||||
|
||||
// clang-format off
|
||||
switch (lsConfiguration) {
|
||||
case LayerShellQt::Window::ScreenFromQWindow: configuration = ScreenConfiguration::Window; break;
|
||||
case LayerShellQt::Window::ScreenFromCompositor: configuration = ScreenConfiguration::Compositor; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
void WaylandShellWindow::updateExclusionZone() {
|
||||
if (this->window != nullptr && this->exclusionMode() == ExclusionMode::Auto) {
|
||||
auto anchors = this->anchors();
|
||||
|
||||
auto zone = -1;
|
||||
|
||||
if (anchors.mTop && anchors.mBottom) {
|
||||
if (anchors.mLeft) zone = this->width() + this->margins().mLeft;
|
||||
else if (anchors.mRight) zone = this->width() + this->margins().mRight;
|
||||
} else if (anchors.mLeft && anchors.mRight) {
|
||||
if (anchors.mTop) zone = this->height() + this->margins().mTop;
|
||||
else if (anchors.mBottom) zone = this->height() + this->margins().mBottom;
|
||||
}
|
||||
|
||||
if (zone != -1) {
|
||||
this->shellWindow->setExclusiveZone(zone);
|
||||
emit this->exclusionZoneChanged();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <LayerShellQt/window.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "shellwindow.hpp"
|
||||
|
||||
namespace Layer { // NOLINT
|
||||
Q_NAMESPACE;
|
||||
QML_ELEMENT;
|
||||
|
||||
enum Enum {
|
||||
Background = 0,
|
||||
Bottom = 1,
|
||||
Top = 2,
|
||||
Overlay = 3,
|
||||
};
|
||||
Q_ENUM_NS(Enum);
|
||||
|
||||
} // namespace Layer
|
||||
|
||||
/// Type of keyboard focus that will be accepted by a [ShellWindow]
|
||||
///
|
||||
/// [ShellWindow]: ../shellwindow
|
||||
namespace KeyboardFocus { // NOLINT
|
||||
Q_NAMESPACE;
|
||||
QML_ELEMENT;
|
||||
|
||||
enum Enum {
|
||||
/// No keyboard input will be accepted.
|
||||
None = 0,
|
||||
/// Exclusive access to the keyboard, locking out all other windows.
|
||||
Exclusive = 1,
|
||||
/// Access to the keyboard as determined by the operating system.
|
||||
///
|
||||
/// > [!WARNING] On some systems, `OnDemand` may cause the shell window to
|
||||
/// > retain focus over another window unexpectedly.
|
||||
/// > You should try `None` if you experience issues.
|
||||
OnDemand = 2,
|
||||
};
|
||||
Q_ENUM_NS(Enum);
|
||||
|
||||
} // namespace KeyboardFocus
|
||||
|
||||
namespace ScreenConfiguration { // NOLINT
|
||||
Q_NAMESPACE;
|
||||
QML_ELEMENT;
|
||||
|
||||
enum Enum {
|
||||
Window = 0,
|
||||
Compositor = 1,
|
||||
};
|
||||
Q_ENUM_NS(Enum);
|
||||
|
||||
} // namespace ScreenConfiguration
|
||||
|
||||
class WaylandShellWindowExtensions;
|
||||
|
||||
class WaylandShellWindow: public ProxyShellWindow {
|
||||
Q_OBJECT;
|
||||
Q_PROPERTY(WaylandShellWindowExtensions* wayland MEMBER mWayland CONSTANT);
|
||||
QML_NAMED_ELEMENT(ShellWindow);
|
||||
|
||||
public:
|
||||
explicit WaylandShellWindow(QObject* parent = nullptr);
|
||||
|
||||
WaylandShellWindowExtensions* wayland();
|
||||
|
||||
void setupWindow() override;
|
||||
QQuickWindow* disownWindow() override;
|
||||
|
||||
void setWidth(qint32 width) override;
|
||||
void setHeight(qint32 height) override;
|
||||
|
||||
void setAnchors(Anchors anchors) override;
|
||||
[[nodiscard]] Anchors anchors() const override;
|
||||
|
||||
void setExclusiveZone(qint32 zone) override;
|
||||
[[nodiscard]] qint32 exclusiveZone() const override;
|
||||
|
||||
void setExclusionMode(ExclusionMode::Enum exclusionMode) override;
|
||||
[[nodiscard]] ExclusionMode::Enum exclusionMode() const override;
|
||||
|
||||
void setMargins(Margins margins) override;
|
||||
[[nodiscard]] Margins margins() const override;
|
||||
|
||||
protected slots:
|
||||
void updateExclusionZone();
|
||||
|
||||
private:
|
||||
WaylandShellWindowExtensions* mWayland = nullptr;
|
||||
|
||||
LayerShellQt::Window* shellWindow = nullptr;
|
||||
Layer::Enum mLayer = Layer::Top;
|
||||
QString mScope;
|
||||
KeyboardFocus::Enum mKeyboardFocus = KeyboardFocus::None;
|
||||
ScreenConfiguration::Enum mScreenConfiguration = ScreenConfiguration::Window;
|
||||
|
||||
bool connected = false;
|
||||
|
||||
friend class WaylandShellWindowExtensions;
|
||||
};
|
||||
|
||||
class WaylandShellWindowExtensions: public QObject {
|
||||
Q_OBJECT;
|
||||
/// The shell layer the window sits in. Defaults to `Layer.Top`.
|
||||
Q_PROPERTY(Layer::Enum layer READ layer WRITE setLayer NOTIFY layerChanged);
|
||||
Q_PROPERTY(QString scope READ scope WRITE setScope);
|
||||
/// The degree of keyboard focus taken. Defaults to `KeyboardFocus.None`.
|
||||
Q_PROPERTY(KeyboardFocus::Enum keyboardFocus READ keyboardFocus WRITE setKeyboardFocus NOTIFY
|
||||
keyboardFocusChanged);
|
||||
Q_PROPERTY(ScreenConfiguration::Enum screenConfiguration READ screenConfiguration WRITE
|
||||
setScreenConfiguration);
|
||||
QML_ELEMENT;
|
||||
QML_UNCREATABLE("WaylandShellWindowExtensions cannot be created");
|
||||
|
||||
public:
|
||||
explicit WaylandShellWindowExtensions(WaylandShellWindow* window):
|
||||
QObject(window), window(window) {}
|
||||
|
||||
void setLayer(Layer::Enum layer);
|
||||
[[nodiscard]] Layer::Enum layer() const;
|
||||
|
||||
void setScope(const QString& scope);
|
||||
[[nodiscard]] QString scope() const;
|
||||
|
||||
void setKeyboardFocus(KeyboardFocus::Enum focus);
|
||||
[[nodiscard]] KeyboardFocus::Enum keyboardFocus() const;
|
||||
|
||||
void setScreenConfiguration(ScreenConfiguration::Enum configuration);
|
||||
[[nodiscard]] ScreenConfiguration::Enum screenConfiguration() const;
|
||||
|
||||
signals:
|
||||
void layerChanged();
|
||||
void keyboardFocusChanged();
|
||||
|
||||
private:
|
||||
WaylandShellWindow* window;
|
||||
|
||||
friend class WaylandShellWindow;
|
||||
};
|
|
@ -10,10 +10,6 @@
|
|||
|
||||
#include "rootwrapper.hpp"
|
||||
|
||||
#ifdef CONF_LAYERSHELL
|
||||
#include <LayerShellQt/shell.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const auto app = QGuiApplication(argc, argv);
|
||||
QGuiApplication::setApplicationName("quickshell");
|
||||
|
@ -42,10 +38,6 @@ int main(int argc, char** argv) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if CONF_LAYERSHELL
|
||||
LayerShellQt::Shell::useLayerShell();
|
||||
#endif
|
||||
|
||||
// Base window transparency appears to be additive.
|
||||
// Use a fully transparent window with a colored rect.
|
||||
QQuickWindow::setDefaultAlphaBuffer(true);
|
||||
|
|
|
@ -154,10 +154,10 @@ signals:
|
|||
void colorChanged();
|
||||
void maskChanged();
|
||||
|
||||
private slots:
|
||||
protected slots:
|
||||
virtual void onWidthChanged();
|
||||
virtual void onHeightChanged();
|
||||
void onMaskChanged();
|
||||
void onWidthChanged();
|
||||
void onHeightChanged();
|
||||
void onScreenDestroyed();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include <qscreen.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
QuickShellScreenInfo::QuickShellScreenInfo(QObject* parent, QScreen* screen):
|
||||
QObject(parent), screen(screen) {
|
||||
QuickShellScreenInfo::QuickShellScreenInfo(QObject* parent, QScreen* screen)
|
||||
: QObject(parent)
|
||||
, screen(screen) {
|
||||
|
||||
if (this->screen != nullptr) {
|
||||
// clang-format off
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
///
|
||||
/// [ProxyWindowBase]: ../proxywindowbase
|
||||
/// [PersistentProperties]: ../persistentproperties
|
||||
class Reloadable: public QObject, public QQmlParserStatus {
|
||||
class Reloadable
|
||||
: public QObject
|
||||
, public QQmlParserStatus {
|
||||
Q_OBJECT;
|
||||
Q_INTERFACES(QQmlParserStatus);
|
||||
/// An additional identifier that can be used to try to match a reloadable object to its
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include "shell.hpp"
|
||||
#include "watcher.hpp"
|
||||
|
||||
RootWrapper::RootWrapper(QString rootPath):
|
||||
QObject(nullptr), rootPath(std::move(rootPath)), engine(this) {
|
||||
RootWrapper::RootWrapper(QString rootPath)
|
||||
: QObject(nullptr)
|
||||
, rootPath(std::move(rootPath))
|
||||
, engine(this) {
|
||||
this->reloadGraph(true);
|
||||
|
||||
if (this->root == nullptr) {
|
||||
|
|
|
@ -20,6 +20,18 @@ class Anchors {
|
|||
Q_PROPERTY(bool bottom MEMBER mBottom);
|
||||
|
||||
public:
|
||||
[[nodiscard]] bool horizontalConstraint() const noexcept { return this->mLeft && this->mRight; }
|
||||
[[nodiscard]] bool verticalConstraint() const noexcept { return this->mTop && this->mBottom; }
|
||||
|
||||
[[nodiscard]] bool operator==(const Anchors& other) const noexcept {
|
||||
// clang-format off
|
||||
return this->mLeft == other.mLeft
|
||||
&& this->mRight == other.mRight
|
||||
&& this->mTop == other.mTop
|
||||
&& this->mBottom == other.mBottom;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
bool mLeft = false;
|
||||
bool mRight = false;
|
||||
bool mTop = false;
|
||||
|
@ -34,6 +46,15 @@ class Margins {
|
|||
Q_PROPERTY(qint32 bottom MEMBER mBottom);
|
||||
|
||||
public:
|
||||
[[nodiscard]] bool operator==(const Margins& other) const noexcept {
|
||||
// clang-format off
|
||||
return this->mLeft == other.mLeft
|
||||
&& this->mRight == other.mRight
|
||||
&& this->mTop == other.mTop
|
||||
&& this->mBottom == other.mBottom;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
qint32 mLeft = 0;
|
||||
qint32 mRight = 0;
|
||||
qint32 mTop = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue