29d0078909
In the current implementation we cannot use a LayerShellQt before the shell surface is created. At the moment a shell surface is created, the constructor is run and then QtWayland commits the current state. This means the compositor configures the window before a client has any chance to set anchors or margins. This works whilst we're just being a simple fullscreen window, but won't scale for plasmashell in the future. This patch makes LayerShellQt::Window always creatable, and we can set and cache properties before the platform window is created, just like one can on QWindow and XDGShell properties. This also makes it less potentially crashy as ::get always returns a valid result, and sets up the public API to be QML-able as an attached property in future. Co-authored on Aleix's patch for the unit test
100 lines
3.2 KiB
C++
100 lines
3.2 KiB
C++
/*
|
|
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
*/
|
|
|
|
#include <QCommandLineParser>
|
|
|
|
#include <QGuiApplication>
|
|
#include <QRasterWindow>
|
|
#include <QWindow>
|
|
#include <QPainter>
|
|
#include <QTimer>
|
|
|
|
#include <QMetaEnum>
|
|
|
|
#include <interfaces/shell.h>
|
|
#include <interfaces/window.h>
|
|
|
|
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<typename T>
|
|
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;
|
|
}
|
|
|
|
class BasicWindow : public QRasterWindow
|
|
{
|
|
void paintEvent(QPaintEvent *) {
|
|
QPainter p(this);
|
|
p.fillRect(QRect(0,0,width(), height()), Qt::red);
|
|
}
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
Shell::useLayerShell();
|
|
|
|
QGuiApplication app(argc, argv);
|
|
|
|
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
|
|
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchor>();
|
|
|
|
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);
|
|
|
|
|
|
BasicWindow window;
|
|
|
|
LayerShellQt::Window* layerShell = LayerShellQt::Window::get(&window);
|
|
if (parser.isSet(marginsOption)) {
|
|
int margins = parser.value(marginsOption).toInt();
|
|
layerShell->setMargins({margins, margins, margins, margins});
|
|
}
|
|
|
|
if (parser.isSet(scopeOption)) {
|
|
layerShell->setScope(parser.value(scopeOption));
|
|
}
|
|
if (parser.isSet(layerOption)) {
|
|
layerShell->setLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption)))));
|
|
}
|
|
if (parser.isSet(anchorsOption)) {
|
|
layerShell->setAnchor(stringToEnum<Window::Anchors>(anchorMetaEnum, parser.value(anchorsOption)));
|
|
}
|
|
window.show();
|
|
|
|
|
|
// just so you don't block yourself out whilst testing
|
|
QTimer::singleShot(5000, &app, &QGuiApplication::quit);
|
|
return app.exec();
|
|
}
|