Compare commits

..

5 Commits

Author SHA1 Message Date
4c40fddf04 update description from kwin 2025-04-25 15:26:50 +02:00
29a4489c72 rename the api to setAnchorRect 2025-04-25 15:26:50 +02:00
94c82f2ed1 update docs 2025-04-25 15:26:50 +02:00
5c987fb03e -1 is forbidden now 2025-04-25 15:26:50 +02:00
b40888ac2a Add set_accomodate_exclusive_zones call
Add a new method that tells the surface whether to accomodate
exclusive zones set by other surfaces or not.
right until now this was possible by setting the eclusive zone of
this surface to the value of -1.
Besides being a magic number, it makes impossible for this surface to
set an exclusive zone by itself if we want to ignore other exclusive zones
2025-04-25 15:26:50 +02:00
13 changed files with 200 additions and 272 deletions

View File

@ -4,13 +4,13 @@
cmake_minimum_required(VERSION 3.16)
project(layershellqt)
set(PROJECT_VERSION "6.5.80")
set(PROJECT_VERSION "6.3.80")
set(PROJECT_VERSION_MAJOR 6)
set(CMAKE_C_STANDARD 99)
set(QT_MIN_VERSION "6.9.0")
set(KF6_MIN_VERSION "6.18.0")
set(QT_MIN_VERSION "6.7.0")
set(KF6_MIN_VERSION "6.10.0")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
set(CMAKE_CXX_STANDARD 20)

View File

@ -5,8 +5,6 @@ remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
add_library(LayerShellQtInterface)
qt6_extract_metatypes(LayerShellQtInterface)
if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0")
set(private_code_option "PRIVATE_CODE")
endif()

View File

@ -4,8 +4,7 @@
ecm_add_qml_module(LayerShellQtQml
URI "org.kde.layershell"
VERSION 1.0
SOURCES types.h
GENERATE_PLUGIN_SOURCE)
SOURCES layershellqtplugin.cpp)
target_link_libraries(LayerShellQtQml PRIVATE Qt::Qml LayerShellQtInterface)
ecm_finalize_qml_module(LayerShellQtQml DESTINATION ${KDE_INSTALL_QMLDIR})
ecm_finalize_qml_module(LayerShellQtQml DESTINATION ${KDE_INSTALL_QMLDIR})

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleix.pol_gonzalez@mercedes-benz.com>
*
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "../interfaces/window.h"
#include <QQmlExtensionPlugin>
#include <qqml.h>
QML_DECLARE_TYPEINFO(LayerShellQt::Window, QML_HAS_ATTACHED_PROPERTIES)
class ExtQMargins
{
QMargins m_margins;
Q_GADGET
Q_PROPERTY(int left READ left WRITE setLeft FINAL)
Q_PROPERTY(int right READ right WRITE setRight FINAL)
Q_PROPERTY(int top READ top WRITE setTop FINAL)
Q_PROPERTY(int bottom READ bottom WRITE setBottom FINAL)
QML_FOREIGN(QMargins)
QML_EXTENDED(ExtQMargins)
public:
ExtQMargins(const QMargins &margins);
int left() const { return m_margins.left(); }
void setLeft(int left) { m_margins.setLeft(left); }
int right() const { return m_margins.right(); }
void setRight(int right) { m_margins.setRight(right); }
int top() const { return m_margins.top(); }
void setTop(int top) { m_margins.setTop(top); }
int bottom() const { return m_margins.bottom(); }
void setBottom(int bottom) { m_margins.setBottom(bottom); }
};
class Plugin : public QQmlExtensionPlugin
{
Q_PLUGIN_METADATA(IID "org.kde.layershellqt")
Q_OBJECT
public:
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.layershell"));
qmlRegisterType<LayerShellQt::Window>(uri, 1, 0, "Window");
qmlRegisterExtendedUncreatableType<QMargins, ExtQMargins>(uri, 1, 0, "ExtQMargins", QStringLiteral("Only created from C++"));
}
};
#include "layershellqtplugin.moc"

View File

@ -1,19 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleix.pol_gonzalez@mercedes-benz.com>
*
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "../interfaces/window.h"
#include <qqml.h>
QML_DECLARE_TYPEINFO(LayerShellQt::Window, QML_HAS_ATTACHED_PROPERTIES)
class WindowForeign
{
Q_GADGET
QML_NAMED_ELEMENT(Window)
QML_FOREIGN(LayerShellQt::Window)
QML_UNCREATABLE("")
QML_ATTACHED(LayerShellQt::Window)
};

View File

@ -9,7 +9,6 @@
#include <layershellqt_logging.h>
#include <QPlatformSurfaceEvent>
#include <QPointer>
#include <optional>
@ -33,11 +32,9 @@ public:
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
Window::Layer layer = Window::LayerTop;
QMargins margins;
QSize desiredSize = QSize(0, 0);
QPointer<QScreen> desiredScreen;
bool desiredActiveScreen = false;
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
bool closeOnDismissed = true;
bool activateOnShow = true;
Window::AnchorRect anchorRect = Window::AnchorRectWorkArea;
};
static QMap<QWindow *, Window *> s_map;
@ -88,6 +85,21 @@ Window::Anchor Window::exclusiveEdge() const
return d->exclusiveEdge;
}
Window::AnchorRect Window::anchorRect() const
{
return d->anchorRect;
}
void Window::setAnchorRect(Window::AnchorRect anchorRect)
{
if (d->anchorRect == anchorRect) {
return;
}
d->anchorRect = anchorRect;
Q_EMIT anchorRectChanged();
}
void Window::setMargins(const QMargins &margins)
{
if (d->margins != margins) {
@ -101,21 +113,6 @@ QMargins Window::margins() const
return d->margins;
}
void Window::setDesiredSize(const QSize &size)
{
if (size == d->desiredSize) {
return;
}
d->desiredSize = size;
Q_EMIT desiredSizeChanged();
}
QSize Window::desiredSize() const
{
return d->desiredSize;
}
void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity)
{
if (d->keyboardInteractivity != interactivity) {
@ -153,46 +150,14 @@ Window::Layer Window::layer() const
return d->layer;
}
void Window::setDesiredActiveScreen(bool set)
Window::ScreenConfiguration Window::screenConfiguration() const
{
if (d->desiredActiveScreen == set) {
return;
}
d->desiredActiveScreen = set;
if (d->desiredActiveScreen && d->desiredScreen) {
d->desiredScreen = nullptr;
Q_EMIT desiredScreenChanged();
}
Q_EMIT desiredActiveScreenChanged();
return d->screenConfiguration;
}
bool Window::desiredActiveScreen() const
void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration)
{
return d->desiredActiveScreen;
}
void Window::setDesiredScreen(QScreen *screen)
{
if (d->desiredScreen == screen) {
return;
}
d->desiredScreen = screen;
if (d->desiredScreen && d->desiredActiveScreen) {
d->desiredActiveScreen = false;
Q_EMIT desiredActiveScreenChanged();
}
Q_EMIT desiredScreenChanged();
}
QScreen *Window::desiredScreen() const
{
return d->desiredScreen;
d->screenConfiguration = screenConfiguration;
}
bool Window::closeOnDismissed() const
@ -205,50 +170,17 @@ void Window::setCloseOnDismissed(bool close)
d->closeOnDismissed = close;
}
bool Window::activateOnShow() const
{
return d->activateOnShow;
}
void Window::setActivateOnShow(bool activateOnShow)
{
d->activateOnShow = activateOnShow;
}
Window::Window(QWindow *window)
: QObject(window)
, d(new WindowPrivate(window))
{
s_map.insert(d->parentWindow, this);
window->installEventFilter(this);
if (window->isVisible()) {
qCWarning(LAYERSHELLQT) << d->parentWindow << "already has a shell integration. Call QWindow::close() first and show it again.";
}
if (window->handle()) {
initializeShell();
}
}
window->create();
bool Window::eventFilter(QObject *watched, QEvent *event)
{
auto window = qobject_cast<QWindow *>(watched);
if (!window) {
return false;
}
if (event->type() == QEvent::PlatformSurface) {
if (auto pse = static_cast<QPlatformSurfaceEvent *>(event); pse->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
initializeShell();
}
}
return false;
}
void Window::initializeShell()
{
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(d->parentWindow->handle());
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
if (!waylandWindow) {
qCWarning(LAYERSHELLQT) << d->parentWindow << "is not a wayland window. Not creating zwlr_layer_surface";
qCWarning(LAYERSHELLQT) << window << "is not a wayland window. Not creating zwlr_layer_surface";
return;
}
@ -262,6 +194,7 @@ void Window::initializeShell()
return;
}
}
waylandWindow->setShellIntegration(shellIntegration);
}

View File

@ -25,11 +25,10 @@ class LAYERSHELLQT_EXPORT Window : public QObject
Q_PROPERTY(QString scope READ scope WRITE setScope)
Q_PROPERTY(QMargins margins READ margins WRITE setMargins NOTIFY marginsChanged)
Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged)
Q_PROPERTY(AnchorRect anchorRect READ anchorRect WRITE setAnchorRect NOTIFY anchorRectChanged)
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
Q_PROPERTY(bool activateOnShow READ activateOnShow WRITE setActivateOnShow)
Q_PROPERTY(bool desiredActiveScreen READ desiredActiveScreen WRITE setDesiredActiveScreen NOTIFY desiredActiveScreenChanged)
Q_PROPERTY(QScreen *desiredScreen READ desiredScreen WRITE setDesiredScreen NOTIFY desiredScreenChanged)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
public:
~Window() override;
@ -41,8 +40,14 @@ public:
AnchorLeft = 4, ///< The left edge of the anchor rectangle
AnchorRight = 8, ///< The right edge of the anchor rectangle
};
Q_ENUM(Anchor);
Q_DECLARE_FLAGS(Anchors, Anchor)
Q_FLAG(Anchors)
/**
* This enum is used to choose between anchoring to work area or screen area
*/
enum AnchorRect { AnchorRectWorkArea = 0, AnchorRectFullArea = 1 };
Q_ENUM(AnchorRect);
/**
* This enum type is used to specify the layer where a surface can be put in.
@ -65,6 +70,17 @@ public:
};
Q_ENUM(KeyboardInteractivity)
/**
* This enum type is used to specify which screen to place the surface on.
* ScreenFromQWindow (the default) reads QWindow::screen() while ScreenFromCompositor
* passes nil and lets the compositor decide.
*/
enum ScreenConfiguration {
ScreenFromQWindow = 0,
ScreenFromCompositor = 1,
};
Q_ENUM(ScreenConfiguration)
void setAnchors(Anchors anchor);
Anchors anchors() const;
@ -74,45 +90,20 @@ public:
void setExclusiveEdge(Window::Anchor edge);
Window::Anchor exclusiveEdge() const;
AnchorRect anchorRect() const;
void setAnchorRect(AnchorRect anchorRect);
void setMargins(const QMargins &margins);
QMargins margins() const;
void setDesiredSize(const QSize &size);
QSize desiredSize() const;
void setKeyboardInteractivity(KeyboardInteractivity interactivity);
KeyboardInteractivity keyboardInteractivity() const;
void setLayer(Layer layer);
Layer layer() const;
/**
* Indicates whether the layer shell surface should be placed on the active screen based on @a set.
*
* The active screen depends on the compositor policies.
*
* If no explicit desired screen has been specified with the setDesiredScreen() function or the layer
* surface doesn't need to be placed on the active screen, i.e. setDesiredActiveScreen() has not
* been called, the QWindow::screen() will be used to decide what screen the layer shell surface
* should be placed on.
*
* The desiredScreen() will be reset if @a set is @c true.
*/
void setDesiredActiveScreen(bool set);
bool desiredActiveScreen() const;
/**
* Indicates that the layer shell surface should be placed on the specified @a screen.
*
* If no explicit desired screen has been specified with the setDesiredScreen() function or the layer
* surface doesn't need to be placed on the active screen, i.e. setDesiredActiveScreen() has not
* been called, the QWindow::screen() will be used to decide what screen the layer shell surface
* should be placed on.
*
* The desiredActiveScreen() will be reset to @c false after calling this function.
*/
void setDesiredScreen(QScreen *screen);
QScreen *desiredScreen() const;
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
ScreenConfiguration screenConfiguration() const;
/**
* Sets a string based identifier for this window.
@ -133,18 +124,6 @@ public:
void setCloseOnDismissed(bool close);
bool closeOnDismissed() const;
/**
* Whether the window should requestActivate on show.
*
* Normally, you want this enabled but in case of e.g. a desktop window, this can be disabled.
*
* It does nothing when KeyboardInteractivity is KeyboardInteractivityNone.
*
* The default is true.
*/
void setActivateOnShow(bool activateOnShow);
bool activateOnShow() const;
/**
* Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred
@ -153,22 +132,16 @@ public:
static Window *qmlAttachedProperties(QObject *object);
bool eventFilter(QObject *watched, QEvent *event) override;
Q_SIGNALS:
void anchorsChanged();
void exclusionZoneChanged();
void exclusiveEdgeChanged();
void anchorRectChanged();
void marginsChanged();
void desiredSizeChanged();
void keyboardInteractivityChanged();
void layerChanged();
void desiredActiveScreenChanged();
void desiredScreenChanged();
private:
void initializeShell();
Window(QWindow *window);
QScopedPointer<WindowPrivate> d;
};

View File

@ -15,7 +15,7 @@
namespace LayerShellQt
{
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
: QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>(5)
: QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>(6)
, m_xdgActivation(new QWaylandXdgActivationV1)
{
}

View File

@ -26,12 +26,7 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
, m_window(window)
{
wl_output *output = nullptr;
if (!m_interface->desiredActiveScreen()) {
QScreen *desiredScreen = m_interface->desiredScreen();
if (!desiredScreen) {
window->window()->screen();
}
if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) {
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(window->window()->screen()->handle());
// Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created
// this will not cast to a QWaylandScreen
@ -49,11 +44,7 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
setAnchor(m_interface->anchors());
connect(m_interface, &Window::anchorsChanged, this, [this]() {
setAnchor(m_interface->anchors());
if (m_interface->desiredSize().isNull()) {
setDesiredSize(m_window->windowContentGeometry().size());
} else {
setDesiredSize(m_interface->desiredSize());
}
setDesiredSize(m_window->windowContentGeometry().size());
});
setExclusiveZone(m_interface->exclusionZone());
@ -65,27 +56,22 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
setExclusiveEdge(m_interface->exclusiveEdge());
});
setAnchorRect(m_interface->anchorRect());
connect(m_interface, &Window::anchorRectChanged, this, [this]() {
setAnchorRect(m_interface->anchorRect());
});
setMargins(m_interface->margins());
connect(m_interface, &Window::marginsChanged, this, [this]() {
setMargins(m_interface->margins());
});
connect(m_interface, &Window::desiredSizeChanged, this, [this]() {
if (!m_interface->desiredSize().isNull()) {
setDesiredSize(m_interface->desiredSize());
}
});
setKeyboardInteractivity(m_interface->keyboardInteractivity());
connect(m_interface, &Window::keyboardInteractivityChanged, this, [this]() {
setKeyboardInteractivity(m_interface->keyboardInteractivity());
});
if (m_interface->desiredSize().isNull()) {
setDesiredSize(window->windowContentGeometry().size());
} else {
setDesiredSize(m_interface->desiredSize());
}
setDesiredSize(window->windowContentGeometry().size());
}
QWaylandLayerSurface::~QWaylandLayerSurface()
@ -129,7 +115,13 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po
void QWaylandLayerSurface::applyConfigure()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
m_configuring = true;
#endif
window()->resizeFromApplyConfigure(m_pendingSize);
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
m_configuring = false;
#endif
}
void QWaylandLayerSurface::setDesiredSize(const QSize &size)
@ -164,6 +156,13 @@ void QWaylandLayerSurface::setExclusiveEdge(uint32_t edge)
}
}
void QWaylandLayerSurface::setAnchorRect(int32_t anchorRect)
{
if (zwlr_layer_surface_v1_get_version(object()) >= ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_RECT_SINCE_VERSION) {
set_anchor_rect(anchorRect);
}
}
void QWaylandLayerSurface::setMargins(const QMargins &margins)
{
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
@ -180,12 +179,21 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
set_layer(layer);
}
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
{
if (m_configuring) {
return;
}
setDesiredSize(geometry.size());
}
#else
void QWaylandLayerSurface::setWindowSize(const QSize &size)
{
if (m_interface->desiredSize().isNull()) {
setDesiredSize(size);
}
setDesiredSize(size);
}
#endif
bool QWaylandLayerSurface::requestActivate()
{
@ -197,10 +205,6 @@ bool QWaylandLayerSurface::requestActivate()
activation->activate(m_activationToken, window()->wlSurface());
m_activationToken = {};
return true;
} else if (const auto token = qEnvironmentVariable("XDG_ACTIVATION_TOKEN"); !token.isEmpty()) {
activation->activate(token, window()->wlSurface());
qunsetenv("XDG_ACTIVATION_TOKEN");
return true;
} else {
const auto focusWindow = QGuiApplication::focusWindow();
const auto wlWindow = focusWindow ? static_cast<QtWaylandClient::QWaylandWindow *>(focusWindow->handle()) : window();
@ -216,23 +220,6 @@ bool QWaylandLayerSurface::requestActivate()
return false;
}
bool QWaylandLayerSurface::requestActivateOnShow()
{
if (!m_interface->activateOnShow()) {
return false;
}
if (m_interface->keyboardInteractivity() == Window::KeyboardInteractivityNone) {
return false;
}
if (m_window->window()->property("_q_showWithoutActivating").toBool()) {
return false;
}
return requestActivate();
}
void QWaylandLayerSurface::setXdgActivationToken(const QString &token)
{
m_activationToken = token;
@ -254,6 +241,13 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
void QWaylandLayerSurface::sendExpose()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
window()->handleExpose(QRect(QPoint(), m_pendingSize));
#elif QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
window()->sendRecursiveExposeEvent();
#else
window()->updateExposure();
#endif
}
}

View File

@ -8,6 +8,7 @@
#ifndef _LAYERSURFACE_H
#define _LAYERSURFACE_H
#include <cstdint>
#include <wayland-client.h>
#include "qwaylandlayershellintegration_p.h"
@ -38,15 +39,19 @@ public:
void setAnchor(uint32_t anchor);
void setExclusiveZone(int32_t zone);
void setExclusiveEdge(uint32_t edge);
void setAnchorRect(int32_t anchorRect);
void setMargins(const QMargins &margins);
void setKeyboardInteractivity(uint32_t interactivity);
void setLayer(uint32_t layer);
void applyConfigure() override;
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
void setWindowGeometry(const QRect &geometry) override;
#else
void setWindowSize(const QSize &size) override;
#endif
bool requestActivate() override;
bool requestActivateOnShow() override;
void setXdgActivationToken(const QString &token) override;
void requestXdgActivationToken(quint32 serial) override;
@ -62,6 +67,9 @@ private:
QString m_activationToken;
bool m_configured = false;
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
bool m_configuring = false;
#endif
};
}

View File

@ -25,7 +25,7 @@
THIS SOFTWARE.
</copyright>
<interface name="zwlr_layer_shell_v1" version="5">
<interface name="zwlr_layer_shell_v1" version="6">
<description summary="create surfaces that are layers of the desktop">
Clients can use this interface to assign the surface_layer role to
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
@ -100,7 +100,7 @@
</request>
</interface>
<interface name="zwlr_layer_surface_v1" version="5">
<interface name="zwlr_layer_surface_v1" version="6">
<description summary="layer metadata interface">
An interface that may be implemented by a wl_surface, for surfaces that
are designed to be rendered as a layer of a stacked desktop-like
@ -168,21 +168,25 @@
Surfaces that do not wish to have an exclusive zone may instead specify
how they should interact with surfaces that do. If set to zero, the
surface indicates that it would like to be moved to avoid occluding
surfaces with a positive exclusive zone. If set to -1, the surface
indicates that it would not like to be moved to accommodate for other
surfaces, and the compositor should extend it all the way to the edges
it is anchored to.
surfaces with a positive exclusive zone.
For example, a panel might set its exclusive zone to 10, so that
maximized shell surfaces are not shown on top of it. A notification
might set its exclusive zone to 0, so that it is moved to avoid
occluding the panel, but shell surfaces are shown underneath it. A
wallpaper or lock screen might set their exclusive zone to -1, so that
they stretch below or over the panel.
occluding the panel, but shell surfaces are shown underneath it.
The default value is 0.
Exclusive zone is double-buffered, see wl_surface.commit.
Since version 6 It must be a value of 0 or more, otherwise the error
invalid_exclusive_zone will be triggered.
Until version 5 if set to -1, the surface indicates that it would not
like to be moved to accommodate for other surfaces, and the compositor
should extend it all the way to the edges it is anchored to.
A wallpaper or lock screen might set their exclusive zone to -1, so that
they stretch below or over the panel.
</description>
<arg name="zone" type="int"/>
</request>
@ -368,6 +372,7 @@
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
<entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
<entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/>
<entry name="invalid_exclusive_zone" value="5" summary="exclusive zone value is invalid, since version 6 it can't be less than zero"/>
</enum>
<enum name="anchor" bitfield="true">
@ -403,5 +408,33 @@
</description>
<arg name="edge" type="uint"/>
</request>
<!-- Version 6 additions -->
<enum name="anchor_rect">
<entry name="full_area" value="0" summary="the full area anchor rect">
<description summary="the full area anchor rect">
Place the layer_surface_v1 relative to the full output area.
</description>
</entry>
<entry name="work_area" value="1" summary="the work area anchor rect">
<description summary="the work area anchor rect">
Place the layer_surface_v1 relative to the output area while taking
the exclusive zone of other surfaces into account.
</description>
</entry>
</enum>
<request name="set_anchor_rect" since="6">
<description summary="set the anchor rect">
Set the anchor rectangle relative to which the anchors are applied.
By default, the layer_surface_v1 is anchored to the 'work_area'.
Anchor rect is double-buffered, see wl_surface.commit.
</description>
<arg name="rect" type="uint" enum="anchor_rect"/>
</request>
</interface>
</protocol>

View File

@ -1,42 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Aleix Pol i Gonzalez <aleixpol@kde.org>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
import QtQuick
import QtQuick.Controls
import org.kde.layershell 1.0 as LayerShell
Item
{
Button {
text: "Convert"
anchors.centerIn: parent
onClicked: {
win.close()
win.LayerShell.Window.anchors = LayerShell.Window.AnchorLeft;
win.LayerShell.Window.layer = LayerShell.Window.LayerTop;
win.LayerShell.Window.exclusionZone = -1;
win.show()
}
}
Window {
id: win
width: 100
height: 100
Rectangle {
anchors.fill: parent
color: "red"
Text {
anchors.centerIn: parent
text: "top"
}
}
visible: true
}
}

View File

@ -53,7 +53,7 @@ int main(int argc, char **argv)
QGuiApplication app(argc, argv);
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchors>();
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchor>();
QCommandLineParser parser;
QCommandLineOption marginsOption(QStringLiteral("margins"), QStringLiteral("Window margins"), QStringLiteral("pixels"), QStringLiteral("0"));