Compare commits

..

14 Commits

Author SHA1 Message Date
e9b257954b RFC: Allow specifying margins in percents
Absolute margin values pose a problem if you want to place a surface
certain distance away from a screen edge (in percents) but you also want
the compositor to place the surface on the active output.

At the moment, this issue is worked around by using kwin dbus api to
query the active output. This is not good.

This change is a take on allowing to specify margin values in percents.
It can be used to drop a dbus call in krunner and assist us with porting
other components to layer shell, e.g. OSDs, they also need to be placed
one third away the bottom screen edge.
2025-11-20 00:39:51 +02:00
7629761b71 percent margins 2025-11-19 23:46:25 +02:00
b9e1260949 Window: Ensure we integrate windows that were already were shown in a different shell 2025-10-25 13:02:31 +02:00
cb79d3f60a window: Improve how we tell the window to do layer-shell
Instead of telling it in the construction after forcing the window
creation, install an event handler that sets it when we get the
PlatformSurface event.

It has the advantage that it will also trigger in subsequent platform
surface events (e.g. after hide and show).
2025-10-25 13:02:31 +02:00
2b8544f5a0 Drop obsolete code for Qt versions lower than 6.9 2025-10-16 14:02:29 +02:00
e4b5bdbf1b Update version for new release 6.5.80 2025-09-18 20:56:39 +05:30
ebd64dd395 Update version for new release 6.4.90 2025-09-18 17:26:46 +05:30
ca0ac57fb4 Update Qt version requirement to 6.9.0
GIT_SILENT
2025-09-18 14:00:16 +05:30
d085a88c81 Update Frameworks version requirement to 6.18.0
GIT_SILENT
2025-09-18 14:00:16 +05:30
5e57a060c6 Register anchors flags to QML
CCBUG: 507602
2025-08-05 13:04:50 +02:00
d436a779d7 Request activate on show
Unless the window doesn't have keyboard interactivity or the caller
wants it not to.

To match XDG Shell behavior and general Qt window behavior.
2025-08-03 10:08:40 +00:00
f599e829ad When activating, also try token from XDG_ACTIVATION_TOKEN
This matches upstream QWaylandXdgSurface behavior.

It also makes various activation magic e.g. KDBusService work.
2025-07-30 23:29:13 +00:00
397398dfd8 Port to declarative type registration
BUG: 507602
2025-07-30 21:39:23 +02:00
7a074a3684 update version for new release 2025-05-19 18:33:35 +05:30
12 changed files with 463 additions and 109 deletions

View File

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

View File

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

View File

@ -4,7 +4,8 @@
ecm_add_qml_module(LayerShellQtQml ecm_add_qml_module(LayerShellQtQml
URI "org.kde.layershell" URI "org.kde.layershell"
VERSION 1.0 VERSION 1.0
SOURCES layershellqtplugin.cpp) SOURCES types.h
GENERATE_PLUGIN_SOURCE)
target_link_libraries(LayerShellQtQml PRIVATE Qt::Qml LayerShellQtInterface) 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

@ -1,51 +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 <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"

19
src/declarative/types.h Normal file
View File

@ -0,0 +1,19 @@
/*
* 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,6 +9,7 @@
#include <layershellqt_logging.h> #include <layershellqt_logging.h>
#include <QPlatformSurfaceEvent>
#include <QPointer> #include <QPointer>
#include <optional> #include <optional>
@ -16,6 +17,49 @@
using namespace LayerShellQt; using namespace LayerShellQt;
Margin::Margin()
: m_value(0)
{
}
Margin::Margin(int pixels)
: m_value(pixels)
{
}
Margin::Margin(qreal percents)
: m_value(percents)
{
}
Margin Margin::fromPixels(int pixels)
{
return Margin(pixels);
}
Margin Margin::fromPercents(qreal percents)
{
return Margin(percents);
}
std::optional<int> Margin::pixels() const
{
if (std::holds_alternative<int>(m_value)) {
return std::get<int>(m_value);
} else {
return std::nullopt;
}
}
std::optional<qreal> Margin::percents() const
{
if (std::holds_alternative<qreal>(m_value)) {
return std::get<qreal>(m_value);
} else {
return std::nullopt;
}
}
class LayerShellQt::WindowPrivate class LayerShellQt::WindowPrivate
{ {
public: public:
@ -31,10 +75,14 @@ public:
Window::Anchor exclusiveEdge = Window::AnchorNone; Window::Anchor exclusiveEdge = Window::AnchorNone;
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand; Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
Window::Layer layer = Window::LayerTop; Window::Layer layer = Window::LayerTop;
QMargins margins; Margin leftMargin;
Margin topMargin;
Margin rightMargin;
Margin bottomMargin;
QSize desiredSize = QSize(0, 0); QSize desiredSize = QSize(0, 0);
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
bool closeOnDismissed = true; bool closeOnDismissed = true;
bool activateOnShow = true;
}; };
static QMap<QWindow *, Window *> s_map; static QMap<QWindow *, Window *> s_map;
@ -87,15 +135,74 @@ Window::Anchor Window::exclusiveEdge() const
void Window::setMargins(const QMargins &margins) void Window::setMargins(const QMargins &margins)
{ {
if (d->margins != margins) { setLeftMargin(Margin::fromPixels(margins.left()));
d->margins = margins; setTopMargin(Margin::fromPixels(margins.top()));
Q_EMIT marginsChanged(); setRightMargin(Margin::fromPixels(margins.right()));
} setBottomMargin(Margin::fromPixels(margins.bottom()));
} }
QMargins Window::margins() const QMargins Window::margins() const
{ {
return d->margins; return QMargins(d->leftMargin.pixels().value_or(0),
d->topMargin.pixels().value_or(0),
d->rightMargin.pixels().value_or(0),
d->bottomMargin.pixels().value_or(0));
}
void Window::setLeftMargin(Margin margin)
{
if (d->leftMargin != margin) {
d->leftMargin = margin;
Q_EMIT leftMarginChanged();
Q_EMIT marginsChanged();
}
}
Margin Window::leftMargin() const
{
return d->leftMargin;
}
void Window::setTopMargin(Margin margin)
{
if (d->topMargin != margin) {
d->topMargin = margin;
Q_EMIT topMarginChanged();
Q_EMIT marginsChanged();
}
}
Margin Window::topMargin() const
{
return d->topMargin;
}
void Window::setRightMargin(Margin margin)
{
if (d->rightMargin != margin) {
d->rightMargin = margin;
Q_EMIT rightMarginChanged();
Q_EMIT marginsChanged();
}
}
Margin Window::rightMargin() const
{
return d->rightMargin;
}
void Window::setBottomMargin(Margin margin)
{
if (d->bottomMargin != margin) {
d->bottomMargin = margin;
Q_EMIT bottomMarginChanged();
Q_EMIT marginsChanged();
}
}
Margin Window::bottomMargin() const
{
return d->bottomMargin;
} }
void Window::setDesiredSize(const QSize &size) void Window::setDesiredSize(const QSize &size)
@ -170,17 +277,50 @@ void Window::setCloseOnDismissed(bool close)
d->closeOnDismissed = close; d->closeOnDismissed = close;
} }
bool Window::activateOnShow() const
{
return d->activateOnShow;
}
void Window::setActivateOnShow(bool activateOnShow)
{
d->activateOnShow = activateOnShow;
}
Window::Window(QWindow *window) Window::Window(QWindow *window)
: QObject(window) : QObject(window)
, d(new WindowPrivate(window)) , d(new WindowPrivate(window))
{ {
s_map.insert(d->parentWindow, this); 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.";
}
window->create(); if (window->handle()) {
initializeShell();
}
}
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle()); 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());
if (!waylandWindow) { if (!waylandWindow) {
qCWarning(LAYERSHELLQT) << window << "is not a wayland window. Not creating zwlr_layer_surface"; qCWarning(LAYERSHELLQT) << d->parentWindow << "is not a wayland window. Not creating zwlr_layer_surface";
return; return;
} }
@ -194,7 +334,6 @@ Window::Window(QWindow *window)
return; return;
} }
} }
waylandWindow->setShellIntegration(shellIntegration); waylandWindow->setShellIntegration(shellIntegration);
} }

View File

@ -18,6 +18,34 @@ namespace LayerShellQt
{ {
class WindowPrivate; class WindowPrivate;
/**
* The Margin type provides a way to specify how far a layer surface should be away from a screen edge.
*
* A margin can have an absolute value or a percent value. An absolute value indicates the distance
* in pixels. A percent value indicates the distance as a percentage of the output size, for example
* this can be used to tell the compositor that the surface should be one third of the output height from
* a screen edge, etc.
*/
class LAYERSHELLQT_EXPORT Margin
{
public:
static Margin fromPixels(int pixels);
static Margin fromPercents(qreal percents);
Margin();
std::optional<int> pixels() const;
std::optional<qreal> percents() const;
auto operator<=>(const Margin &other) const = default;
private:
Margin(int pixels);
Margin(qreal percents);
std::variant<int, qreal> m_value;
};
class LAYERSHELLQT_EXPORT Window : public QObject class LAYERSHELLQT_EXPORT Window : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -28,6 +56,7 @@ class LAYERSHELLQT_EXPORT Window : public QObject
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged) Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged) Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration) Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
Q_PROPERTY(bool activateOnShow READ activateOnShow WRITE setActivateOnShow)
public: public:
~Window() override; ~Window() override;
@ -39,8 +68,8 @@ public:
AnchorLeft = 4, ///< The left edge of the anchor rectangle AnchorLeft = 4, ///< The left edge of the anchor rectangle
AnchorRight = 8, ///< The right edge of the anchor rectangle AnchorRight = 8, ///< The right edge of the anchor rectangle
}; };
Q_ENUM(Anchor);
Q_DECLARE_FLAGS(Anchors, Anchor) Q_DECLARE_FLAGS(Anchors, Anchor)
Q_FLAG(Anchors)
/** /**
* This enum type is used to specify the layer where a surface can be put in. * This enum type is used to specify the layer where a surface can be put in.
@ -86,6 +115,18 @@ public:
void setMargins(const QMargins &margins); void setMargins(const QMargins &margins);
QMargins margins() const; QMargins margins() const;
void setLeftMargin(Margin margin);
Margin leftMargin() const;
void setTopMargin(Margin margin);
Margin topMargin() const;
void setRightMargin(Margin margin);
Margin rightMargin() const;
void setBottomMargin(Margin margin);
Margin bottomMargin() const;
void setDesiredSize(const QSize &size); void setDesiredSize(const QSize &size);
QSize desiredSize() const; QSize desiredSize() const;
@ -117,6 +158,18 @@ public:
void setCloseOnDismissed(bool close); void setCloseOnDismissed(bool close);
bool closeOnDismissed() const; 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 * Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred * Ownership is not transferred
@ -125,16 +178,24 @@ public:
static Window *qmlAttachedProperties(QObject *object); static Window *qmlAttachedProperties(QObject *object);
bool eventFilter(QObject *watched, QEvent *event) override;
Q_SIGNALS: Q_SIGNALS:
void anchorsChanged(); void anchorsChanged();
void exclusionZoneChanged(); void exclusionZoneChanged();
void exclusiveEdgeChanged(); void exclusiveEdgeChanged();
void marginsChanged(); void marginsChanged();
void leftMarginChanged();
void topMarginChanged();
void rightMarginChanged();
void bottomMarginChanged();
void desiredSizeChanged(); void desiredSizeChanged();
void keyboardInteractivityChanged(); void keyboardInteractivityChanged();
void layerChanged(); void layerChanged();
private: private:
void initializeShell();
Window(QWindow *window); Window(QWindow *window);
QScopedPointer<WindowPrivate> d; QScopedPointer<WindowPrivate> d;
}; };

View File

@ -60,9 +60,24 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
setExclusiveEdge(m_interface->exclusiveEdge()); setExclusiveEdge(m_interface->exclusiveEdge());
}); });
setMargins(m_interface->margins()); setLeftMargin(m_interface->leftMargin());
connect(m_interface, &Window::marginsChanged, this, [this]() { connect(m_interface, &Window::leftMarginChanged, this, [this]() {
setMargins(m_interface->margins()); setLeftMargin(m_interface->leftMargin());
});
setTopMargin(m_interface->topMargin());
connect(m_interface, &Window::topMarginChanged, this, [this]() {
setTopMargin(m_interface->topMargin());
});
setRightMargin(m_interface->rightMargin());
connect(m_interface, &Window::rightMarginChanged, this, [this]() {
setRightMargin(m_interface->rightMargin());
});
setBottomMargin(m_interface->bottomMargin());
connect(m_interface, &Window::bottomMarginChanged, this, [this]() {
setBottomMargin(m_interface->bottomMargin());
}); });
connect(m_interface, &Window::desiredSizeChanged, this, [this]() { connect(m_interface, &Window::desiredSizeChanged, this, [this]() {
@ -124,13 +139,7 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po
void QWaylandLayerSurface::applyConfigure() void QWaylandLayerSurface::applyConfigure()
{ {
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
m_configuring = true;
#endif
window()->resizeFromApplyConfigure(m_pendingSize); window()->resizeFromApplyConfigure(m_pendingSize);
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
m_configuring = false;
#endif
} }
void QWaylandLayerSurface::setDesiredSize(const QSize &size) void QWaylandLayerSurface::setDesiredSize(const QSize &size)
@ -165,9 +174,68 @@ void QWaylandLayerSurface::setExclusiveEdge(uint32_t edge)
} }
} }
void QWaylandLayerSurface::setMargins(const QMargins &margins) void QWaylandLayerSurface::setLeftMargin(const Margin &margin)
{ {
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
if (const auto pixels = margin.pixels()) {
set_left_margin_absolute(*pixels);
} else if (const auto percents = margin.percents()) {
set_left_margin_percents(wl_fixed_from_double(*percents));
} else {
qCWarning(LAYERSHELLQT) << "Unspecified left margin for" << m_window->window();
}
} else {
const QMargins margins = m_interface->margins();
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left()); set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
}
}
void QWaylandLayerSurface::setTopMargin(const Margin &margin)
{
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
if (const auto pixels = margin.pixels()) {
set_top_margin_absolute(*pixels);
} else if (const auto percents = margin.percents()) {
set_top_margin_percents(wl_fixed_from_double(*percents));
} else {
qCWarning(LAYERSHELLQT) << "Unspecified top margin for" << m_window->window();
}
} else {
const QMargins margins = m_interface->margins();
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
}
}
void QWaylandLayerSurface::setRightMargin(const Margin &margin)
{
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
if (const auto pixels = margin.pixels()) {
set_right_margin_absolute(*pixels);
} else if (const auto percents = margin.percents()) {
set_right_margin_percents(wl_fixed_from_double(*percents));
} else {
qCWarning(LAYERSHELLQT) << "Unspecified right margin for" << m_window->window();
}
} else {
const QMargins margins = m_interface->margins();
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
}
}
void QWaylandLayerSurface::setBottomMargin(const Margin &margin)
{
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
if (const auto pixels = margin.pixels()) {
set_bottom_margin_absolute(*pixels);
} else if (const auto percents = margin.percents()) {
set_bottom_margin_percents(wl_fixed_from_double(*percents));
} else {
qCWarning(LAYERSHELLQT) << "Unspecified bottom margin for" << m_window->window();
}
} else {
const QMargins margins = m_interface->margins();
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
}
} }
void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity) void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity)
@ -181,25 +249,12 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
set_layer(layer); set_layer(layer);
} }
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
{
if (m_configuring) {
return;
}
if (m_interface->desiredSize().isNull()) {
setDesiredSize(geometry.size());
}
}
#else
void QWaylandLayerSurface::setWindowSize(const QSize &size) void QWaylandLayerSurface::setWindowSize(const QSize &size)
{ {
if (m_interface->desiredSize().isNull()) { if (m_interface->desiredSize().isNull()) {
setDesiredSize(size); setDesiredSize(size);
} }
} }
#endif
bool QWaylandLayerSurface::requestActivate() bool QWaylandLayerSurface::requestActivate()
{ {
@ -230,6 +285,23 @@ bool QWaylandLayerSurface::requestActivate()
return false; 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) void QWaylandLayerSurface::setXdgActivationToken(const QString &token)
{ {
m_activationToken = token; m_activationToken = token;
@ -251,13 +323,6 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
void QWaylandLayerSurface::sendExpose() 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(); window()->updateExposure();
#endif
} }
} }

View File

@ -19,6 +19,7 @@
namespace LayerShellQt namespace LayerShellQt
{ {
class Margin;
class Window; class Window;
class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1 class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1
@ -38,18 +39,18 @@ public:
void setAnchor(uint32_t anchor); void setAnchor(uint32_t anchor);
void setExclusiveZone(int32_t zone); void setExclusiveZone(int32_t zone);
void setExclusiveEdge(uint32_t edge); void setExclusiveEdge(uint32_t edge);
void setMargins(const QMargins &margins); void setLeftMargin(const Margin &margin);
void setTopMargin(const Margin &margin);
void setRightMargin(const Margin &margin);
void setBottomMargin(const Margin &margin);
void setKeyboardInteractivity(uint32_t interactivity); void setKeyboardInteractivity(uint32_t interactivity);
void setLayer(uint32_t layer); void setLayer(uint32_t layer);
void applyConfigure() override; 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; void setWindowSize(const QSize &size) override;
#endif
bool requestActivate() override; bool requestActivate() override;
bool requestActivateOnShow() override;
void setXdgActivationToken(const QString &token) override; void setXdgActivationToken(const QString &token) override;
void requestXdgActivationToken(quint32 serial) override; void requestXdgActivationToken(quint32 serial) override;
@ -65,9 +66,6 @@ private:
QString m_activationToken; QString m_activationToken;
bool m_configured = false; 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. THIS SOFTWARE.
</copyright> </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"> <description summary="create surfaces that are layers of the desktop">
Clients can use this interface to assign the surface_layer role to 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 wl_surfaces. Such surfaces are assigned to a "layer" of the output and
@ -100,7 +100,7 @@
</request> </request>
</interface> </interface>
<interface name="zwlr_layer_surface_v1" version="5"> <interface name="zwlr_layer_surface_v1" version="6">
<description summary="layer metadata interface"> <description summary="layer metadata interface">
An interface that may be implemented by a wl_surface, for surfaces that 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 are designed to be rendered as a layer of a stacked desktop-like
@ -403,5 +403,83 @@
</description> </description>
<arg name="edge" type="uint"/> <arg name="edge" type="uint"/>
</request> </request>
<!-- Version 6 additions -->
<request name="set_left_margin_absolute" since="6">
<description summary="set left margin in absolute pixels">
Sets the left margin in absolute pixels.
The left margin specified in percents will be overwritten.
</description>
<arg name="margin" type="int"/>
</request>
<request name="set_left_margin_percents" since="6">
<description summary="set the left margin proportional to area width">
Sets the left margin as a percentage of the area width. The
margin value is a number between 0 and 1.
The left margin specified in absolute values will be overwritten.
</description>
<arg name="margin" type="fixed"/>
</request>
<request name="set_top_margin_absolute" since="6">
<description summary="set top margin in absolute pixels">
Sets the top margin in absolute pixels.
The top margin specified in percents will be overwritten.
</description>
<arg name="margin" type="int"/>
</request>
<request name="set_top_margin_percents" since="6">
<description summary="set the top margin proportional to area width">
Sets the top margin as a percentage of the area width. The
margin value is a number between 0 and 1.
The top margin specified in absolute values will be overwritten.
</description>
<arg name="margin" type="fixed"/>
</request>
<request name="set_right_margin_absolute" since="6">
<description summary="set right margin in absolute pixels">
Sets the right margin in absolute pixels.
The right margin specified in percents will be overwritten.
</description>
<arg name="margin" type="int"/>
</request>
<request name="set_right_margin_percents" since="6">
<description summary="set the right margin proportional to area width">
Sets the right margin as a percentage of the area width. The
margin value is a number between 0 and 1.
The right margin specified in absolute values will be overwritten.
</description>
<arg name="margin" type="fixed"/>
</request>
<request name="set_bottom_margin_absolute" since="6">
<description summary="set bottom margin in absolute pixels">
Sets the bottom margin in absolute pixels.
The bottom margin specified in percents will be overwritten.
</description>
<arg name="margin" type="int"/>
</request>
<request name="set_bottom_margin_percents" since="6">
<description summary="set the bottom margin proportional to area width">
Sets the bottom margin as a percentage of the area width. The
margin value is a number between 0 and 1.
The bottom margin specified in absolute values will be overwritten.
</description>
<arg name="margin" type="fixed"/>
</request>
</interface> </interface>
</protocol> </protocol>

View File

@ -0,0 +1,42 @@
/*
* 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); QGuiApplication app(argc, argv);
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>(); const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchor>(); const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchors>();
QCommandLineParser parser; QCommandLineParser parser;
QCommandLineOption marginsOption(QStringLiteral("margins"), QStringLiteral("Window margins"), QStringLiteral("pixels"), QStringLiteral("0")); QCommandLineOption marginsOption(QStringLiteral("margins"), QStringLiteral("Window margins"), QStringLiteral("pixels"), QStringLiteral("0"));