Ensure we can set per-window properties before the intial commit
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
This commit is contained in:
parent
29d0078909
commit
2b1219cfdd
|
@ -21,10 +21,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
QWindow *parentWindow;
|
QWindow *parentWindow;
|
||||||
QString scope = QStringLiteral("qt");
|
QString scope = QStringLiteral("window");
|
||||||
Window::Anchors anchor = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
|
Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
|
||||||
int32_t exclusionZone = 0;
|
int32_t exclusionZone = 0;
|
||||||
bool keyboardInteractivity = false;
|
bool keyboardInteractivity = true;
|
||||||
Window::Layer layer = Window::LayerTop;
|
Window::Layer layer = Window::LayerTop;
|
||||||
QMargins margins;
|
QMargins margins;
|
||||||
QWaylandLayerSurface *getSurface() const;
|
QWaylandLayerSurface *getSurface() const;
|
||||||
|
@ -37,17 +37,17 @@ Window::~Window()
|
||||||
s_map.remove(d->parentWindow);
|
s_map.remove(d->parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setAnchor(Anchors anchor)
|
void Window::setAnchors(Anchors anchors)
|
||||||
{
|
{
|
||||||
d->anchor = anchor;
|
d->anchors = anchors;
|
||||||
if (auto surface = d->getSurface()) {
|
if (auto surface = d->getSurface()) {
|
||||||
surface->setAnchor(anchor);
|
surface->setAnchor(anchors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Anchors Window::anchor() const
|
Window::Anchors Window::anchors() const
|
||||||
{
|
{
|
||||||
return d->anchor;
|
return d->anchors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setExclusiveZone(int32_t zone)
|
void Window::setExclusiveZone(int32_t zone)
|
||||||
|
@ -113,13 +113,22 @@ Window::Layer Window::layer() const
|
||||||
return d->layer;
|
return d->layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window(WindowPrivate *d)
|
Window::Window(QWindow *window)
|
||||||
: QObject(d->parentWindow)
|
: QObject(window)
|
||||||
, d(d)
|
, d(new WindowPrivate(window))
|
||||||
{
|
{
|
||||||
s_map.insert(d->parentWindow, this);
|
s_map.insert(d->parentWindow, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window *Window::get(QWindow *window)
|
||||||
|
{
|
||||||
|
auto layerShellWindow = s_map.value(window);
|
||||||
|
if (layerShellWindow) {
|
||||||
|
return layerShellWindow;
|
||||||
|
}
|
||||||
|
return new Window(window);
|
||||||
|
}
|
||||||
|
|
||||||
QWaylandLayerSurface *WindowPrivate::getSurface() const
|
QWaylandLayerSurface *WindowPrivate::getSurface() const
|
||||||
{
|
{
|
||||||
if (!parentWindow) {
|
if (!parentWindow) {
|
||||||
|
@ -137,11 +146,3 @@ QWaylandLayerSurface *WindowPrivate::getSurface() const
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window *Window::get(QWindow *window)
|
|
||||||
{
|
|
||||||
if (s_map.contains(window)) {
|
|
||||||
return s_map[window];
|
|
||||||
}
|
|
||||||
return new Window(new WindowPrivate(window));
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ public:
|
||||||
};
|
};
|
||||||
Q_ENUM(Layer)
|
Q_ENUM(Layer)
|
||||||
|
|
||||||
void setAnchor(Anchors anchor);
|
void setAnchors(Anchors anchor);
|
||||||
Anchors anchor() const;
|
Anchors anchors() const;
|
||||||
|
|
||||||
void setExclusiveZone(int32_t zone);
|
void setExclusiveZone(int32_t zone);
|
||||||
int32_t exclusionZone() const;
|
int32_t exclusionZone() const;
|
||||||
|
@ -58,6 +58,13 @@ public:
|
||||||
void setLayer(Layer layer);
|
void setLayer(Layer layer);
|
||||||
Layer layer() const;
|
Layer layer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a string based identifier for this window.
|
||||||
|
* This may be used by a compositor to determine stacking
|
||||||
|
* order within a given layer.
|
||||||
|
*
|
||||||
|
* May also be referred to as a role
|
||||||
|
*/
|
||||||
void setScope(const QString &scope);
|
void setScope(const QString &scope);
|
||||||
QString scope() const;
|
QString scope() const;
|
||||||
|
|
||||||
|
@ -68,7 +75,7 @@ public:
|
||||||
static Window *get(QWindow *window);
|
static Window *get(QWindow *window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window(WindowPrivate *d);
|
Window(QWindow *window);
|
||||||
QScopedPointer<WindowPrivate> d;
|
QScopedPointer<WindowPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,25 +19,17 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandC
|
||||||
: QtWaylandClient::QWaylandShellSurface(window)
|
: QtWaylandClient::QWaylandShellSurface(window)
|
||||||
, QtWayland::zwlr_layer_surface_v1()
|
, QtWayland::zwlr_layer_surface_v1()
|
||||||
{
|
{
|
||||||
Window::Layer layer =Window::LayerTop;
|
|
||||||
QString scope =QStringLiteral( "qt");
|
|
||||||
LayerShellQt::Window *interface = Window::get(window->window());
|
LayerShellQt::Window *interface = Window::get(window->window());
|
||||||
Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
|
Q_ASSERT(interface);
|
||||||
|
|
||||||
if (interface) {
|
init(shell->get_layer_surface(window->waylandSurface()->object(), window->waylandScreen()->output(), interface->layer(), interface->scope()));
|
||||||
anchors = interface->anchor();
|
|
||||||
layer = interface->layer();
|
|
||||||
scope = interface->scope();
|
|
||||||
}
|
|
||||||
|
|
||||||
init(shell->get_layer_surface(window->waylandSurface()->object(), window->waylandScreen()->output(), layer, scope));
|
Window::Anchors anchors = interface->anchors();
|
||||||
set_anchor(anchors);
|
|
||||||
|
|
||||||
if (interface) {
|
set_anchor(interface->anchors());
|
||||||
setMargins(interface->margins());
|
setMargins(interface->margins());
|
||||||
setKeyboardInteractivity(interface->keyboardInteractivity());
|
setKeyboardInteractivity(interface->keyboardInteractivity());
|
||||||
setExclusiveZone(interface->exclusionZone());
|
setExclusiveZone(interface->exclusionZone());
|
||||||
}
|
|
||||||
|
|
||||||
QSize size = window->surfaceSize();
|
QSize size = window->surfaceSize();
|
||||||
if (anchors & Window::AnchorLeft && anchors & Window::AnchorRight) {
|
if (anchors & Window::AnchorLeft && anchors & Window::AnchorRight) {
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QRasterWindow>
|
|
||||||
#include <QWindow>
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QRasterWindow>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
@ -42,7 +42,8 @@ T stringToEnum(QMetaEnum metaEnum, const QString &str)
|
||||||
|
|
||||||
class BasicWindow : public QRasterWindow
|
class BasicWindow : public QRasterWindow
|
||||||
{
|
{
|
||||||
void paintEvent(QPaintEvent *) {
|
void paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.fillRect(QRect(0, 0, width(), height()), Qt::red);
|
p.fillRect(QRect(0, 0, width(), height()), Qt::red);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +73,6 @@ int main(int argc, char **argv)
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|
||||||
|
|
||||||
BasicWindow window;
|
BasicWindow window;
|
||||||
|
|
||||||
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window);
|
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window);
|
||||||
|
@ -88,11 +88,10 @@ int main(int argc, char **argv)
|
||||||
layerShell->setLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption)))));
|
layerShell->setLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption)))));
|
||||||
}
|
}
|
||||||
if (parser.isSet(anchorsOption)) {
|
if (parser.isSet(anchorsOption)) {
|
||||||
layerShell->setAnchor(stringToEnum<Window::Anchors>(anchorMetaEnum, parser.value(anchorsOption)));
|
layerShell->setAnchors(stringToEnum<Window::Anchors>(anchorMetaEnum, parser.value(anchorsOption)));
|
||||||
}
|
}
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
|
|
||||||
// just so you don't block yourself out whilst testing
|
// just so you don't block yourself out whilst testing
|
||||||
QTimer::singleShot(5000, &app, &QGuiApplication::quit);
|
QTimer::singleShot(5000, &app, &QGuiApplication::quit);
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
Loading…
Reference in a new issue