From 7aa5a16038757b0d18922eba6ae4230186be52d0 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Wed, 14 Apr 2021 17:52:31 +0200 Subject: [PATCH] Add API to choose an initial state of the window --- src/interfaces/shell.cpp | 50 ++++++++++++++++++++++++++- src/interfaces/shell.h | 14 ++++++++ src/interfaces/window.h | 1 + src/qwaylandlayersurface.cpp | 25 ++++++++++---- tests/main.cpp | 66 ++++++++++++++++++++++++++++++++---- 5 files changed, 142 insertions(+), 14 deletions(-) diff --git a/src/interfaces/shell.cpp b/src/interfaces/shell.cpp index 6eb490c..ddfcf20 100644 --- a/src/interfaces/shell.cpp +++ b/src/interfaces/shell.cpp @@ -6,8 +6,8 @@ #include "shell.h" #include -#include #include +#include using namespace LayerShellQt; @@ -18,3 +18,51 @@ void Shell::useLayerShell() qCDebug(LAYERSHELLQT) << "Unable to set QT_WAYLAND_SHELL_INTEGRATION=layer-shell"; } } + +struct Defaults { + QString scope = QStringLiteral("normal"); + Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight}; + Window::Layer layer = Window::LayerTop; + QMargins margins; +}; +Q_GLOBAL_STATIC(Defaults, s_defaults); + +void Shell::setDefaultScope(const QString &scope) +{ + s_defaults->scope = scope; +} + +QString Shell::defaultScope() +{ + return s_defaults->scope; +} + +void Shell::setDefaultLayer(Window::Layer defaultLayer) +{ + s_defaults->layer = defaultLayer; +} + +Window::Layer Shell::defaultLayer() +{ + return s_defaults->layer; +} + +void Shell::setDefaultAnchors(Window::Anchors anchors) +{ + s_defaults->anchors = anchors; +} + +Window::Anchors Shell::defaultAnchors() +{ + return s_defaults->anchors; +} + +void Shell::setDefaultMargins(const QMargins &margins) +{ + s_defaults->margins = margins; +} + +QMargins Shell::defaultMargins() +{ + return s_defaults->margins; +} diff --git a/src/interfaces/shell.h b/src/interfaces/shell.h index cccae17..24058fc 100644 --- a/src/interfaces/shell.h +++ b/src/interfaces/shell.h @@ -8,6 +8,8 @@ #define LAYERSHELLQTSHELL_H #include "layershellqt_export.h" +#include "window.h" +#include namespace LayerShellQt { @@ -18,6 +20,18 @@ class LAYERSHELLQT_EXPORT Shell { public: static void useLayerShell(); + + static void setDefaultMargins(const QMargins &margins); + static QMargins defaultMargins(); + + static void setDefaultScope(const QString &scope); + static QString defaultScope(); + + static void setDefaultLayer(Window::Layer defaultLayer); + static Window::Layer defaultLayer(); + + static void setDefaultAnchors(Window::Anchors defaultAnchors); + static Window::Anchors defaultAnchors(); }; } diff --git a/src/interfaces/window.h b/src/interfaces/window.h index 64fbbcb..4c19c2d 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -30,6 +30,7 @@ public: AnchorRight = 8, // the right edge of the anchor rectangle }; Q_ENUM(Anchor); + Q_DECLARE_FLAGS(Anchors, Anchor) /** * This enum type is used to specify the layer where a surface can be put in. diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index d1bcd3c..4607bf7 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: LGPL-3.0-or-later */ +#include "interfaces/shell.h" #include "qwaylandlayershell_p.h" #include "qwaylandlayersurface_p.h" @@ -17,13 +18,25 @@ namespace LayerShellQt QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window) : QtWaylandClient::QWaylandShellSurface(window) , QtWayland::zwlr_layer_surface_v1( - // TODO: Specify namespace - shell->get_layer_surface(window->waylandSurface()->object(), - window->waylandScreen()->output(), - QtWayland::zwlr_layer_shell_v1::layer_top, - QStringLiteral("qt"))) + shell->get_layer_surface(window->waylandSurface()->object(), window->waylandScreen()->output(), Shell::defaultLayer(), Shell::defaultScope())) { - set_anchor(anchor_top | anchor_bottom | anchor_left | anchor_right); + const auto anchors = Shell::defaultAnchors(); + set_anchor(anchors); + + if (!Shell::defaultMargins().isNull()) { + setMargins(Shell::defaultMargins()); + } + + QSize size = window->surfaceSize(); + if (anchors & Window::AnchorLeft && anchors & Window::AnchorRight) { + size.setWidth(0); + } + if (anchors & Window::AnchorTop && anchors & Window::AnchorBottom) { + size.setHeight(0); + } + if (size.isValid() && size != QSize(0,0)) { + set_size(size.width(), size.height()); + } } QWaylandLayerSurface::~QWaylandLayerSurface() diff --git a/tests/main.cpp b/tests/main.cpp index c3d4d3d..1f6a8f3 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -4,16 +4,74 @@ * SPDX-License-Identifier: LGPL-3.0-or-later */ +#include #include #include #include #include +using namespace LayerShellQt; + +QStringList enumsToStringList(QMetaEnum metaEnum) +{ + QStringList ret; + ret.reserve(metaEnum.keyCount()); + for (int i = 0; i < metaEnum.keyCount(); ++i) { + ret.append(metaEnum.key(i)); + } + return ret; +} + +template +T stringToEnum(QMetaEnum metaEnum, const QString &str) +{ + T ret = {}; + const auto splitted = str.split(QLatin1Char('|')); + for (const auto &value : splitted) { + ret |= T(metaEnum.keyToValue(qPrintable(value))); + } + return ret; +} + int main(int argc, char **argv) { - LayerShellQt::Shell::useLayerShell(); + Shell::useLayerShell(); QGuiApplication app(argc, argv); + + const auto layerMetaEnum = QMetaEnum::fromType(); + const auto anchorMetaEnum = QMetaEnum::fromType(); + + QCommandLineParser parser; + QCommandLineOption marginsOption(QStringLiteral("margins"), QStringLiteral("Window margins"), QStringLiteral("pixels"), QStringLiteral("0")); + QCommandLineOption scopeOption(QStringLiteral("scope"), QStringLiteral("Window scope"), QStringLiteral("namespace"), QStringLiteral("normal")); + QCommandLineOption anchorsOption(QStringLiteral("anchors"), + QStringLiteral("Either ") + enumsToStringList(anchorMetaEnum).join(QLatin1String("|")), + QStringLiteral("anchors"), + QStringLiteral("AnchorTop|AnchorBottom|AnchorLeft|AnchorRight")); + QCommandLineOption layerOption(QStringLiteral("layer"), + QStringLiteral("One of ") + enumsToStringList(layerMetaEnum).join(QLatin1String("|")), + QStringLiteral("layer"), + QStringLiteral("LayerTop")); + parser.addOptions({marginsOption, scopeOption, anchorsOption, layerOption}); + parser.addHelpOption(); + parser.process(app); + + static int margins = 0; + if (parser.isSet(marginsOption)) { + margins = parser.value(marginsOption).toInt(); + Shell::setDefaultMargins({margins, margins, margins, margins}); + } + if (parser.isSet(scopeOption)) { + Shell::setDefaultScope(parser.value(scopeOption)); + } + if (parser.isSet(layerOption)) { + Shell::setDefaultLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption))))); + } + if (parser.isSet(anchorsOption)) { + Shell::setDefaultAnchors(stringToEnum(anchorMetaEnum, parser.value(anchorsOption))); + } + QQmlApplicationEngine engine; engine.loadData( "import QtQuick.Controls 2.10\n" @@ -28,11 +86,5 @@ int main(int argc, char **argv) , QStringLiteral("bananaland:/potato.qml")); - QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [](QObject *object) { - auto layerWindow = LayerShellQt::Window::get(qobject_cast(object)); - Q_ASSERT(layerWindow); - layerWindow->setMargins({50, 50, 50, 50}); - }); - return app.exec(); }