Compare commits

...

33 Commits

Author SHA1 Message Date
28131eea16 Allow specifying explicit desired screen
If the window position is not specified, which is a reasonable thing to
do when using the layer shell protocol, setWidth() and setHeight() can
unintentionally change the screen() to the wrong one.

This change adds a setDesiredScreen() function so it's harder to shoot
yourself in the foot while using the layer shell protocol.
2025-11-19 16:39:43 +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
8b54edb695 update version for new release 2025-05-15 15:14:19 +05:30
ffa33fef9f Update Qt version requirement to 6.8.0
GIT_SILENT
2025-05-15 14:20:07 +05:30
3522070454 Update Frameworks version requirement to 6.14.0
GIT_SILENT
2025-05-15 14:20:07 +05:30
80d5e3c935 Expose setDesiredSize to the C++ API
Making it possible for clients to call setDesiredSize directly,

The idea is that under Wayland, the panel calls this intead of setGeometry,
not trying to set an abosulute geometry that might cause the panel sized wrongly,
but just sets an hint which will ensure the panel won't overlap another one

used by https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/5437

CCBUG:489703
2025-04-30 17:23:48 +02:00
b37ac92e9f CI: Add linux-qt6-next build 2025-02-12 07:28:37 +01:00
c8c8e3e983 Add xml/yaml linting 2025-02-01 09:52:29 +01:00
72d40f696e Fix build with Qt 6.10
The private parts have been extracted into a separate CMake config file, which we need to search for now

See https://bugreports.qt.io/browse/QTBUG-87776
2025-01-29 15:34:52 +01:00
ac333b19c7 update version for new release 2025-01-09 12:46:54 +00:00
c85d6e7baa update version for new release 2025-01-09 11:01:05 +00:00
e534206172 Update Frameworks version requirement to 6.10.0
GIT_SILENT
2025-01-09 10:29:52 +00:00
edb8f67b1b It compiles without deprecated methods 2024-12-18 13:24:21 +01:00
1796255496 update version for new release 2024-10-03 13:11:32 +01:00
2dbd1d6eb7 Update Frameworks version requirement to 6.5.0
GIT_SILENT
2024-09-12 11:08:45 +01:00
0d11058c8f update version for new release 2024-09-12 10:50:16 +01:00
a5fbaa5975 Reformat CMake code for better readability 2024-08-14 11:08:41 +02:00
6f8a3f5d42 Generate wayland code with PRIVATE_CODE 2024-08-14 10:47:07 +02:00
303f68cf10 Update Qt version requirement to 6.7.0
GIT_SILENT
2024-08-02 10:15:46 +01:00
368cf2dd37 Port to QWaylandWindow::updateExposure() 2024-07-05 09:49:38 +03:00
16a1debdca Port to QWaylandShellSurface::setWindowSize() 2024-06-26 13:01:50 +03:00
c4987c01c7 update version for new release 2024-05-24 16:14:22 +01:00
14 changed files with 288 additions and 109 deletions

View File

@ -7,3 +7,6 @@ include:
- /gitlab-templates/reuse-lint.yml
- /gitlab-templates/linux-qt6.yml
- /gitlab-templates/freebsd-qt6.yml
- /gitlab-templates/xml-lint.yml
- /gitlab-templates/yaml-lint.yml
- /gitlab-templates/linux-qt6-next.yml

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: CC0-1.0
Dependencies:
- 'on': ['@all']
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@latest-kf6'
'third-party/wayland': '@latest'

View File

@ -4,13 +4,13 @@
cmake_minimum_required(VERSION 3.16)
project(layershellqt)
set(PROJECT_VERSION "6.0.90")
set(PROJECT_VERSION "6.5.80")
set(PROJECT_VERSION_MAJOR 6)
set(CMAKE_C_STANDARD 99)
set(QT_MIN_VERSION "6.6.0")
set(KF6_MIN_VERSION "6.2.0")
set(QT_MIN_VERSION "6.9.0")
set(KF6_MIN_VERSION "6.18.0")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
set(CMAKE_CXX_STANDARD 20)
@ -34,6 +34,11 @@ include(ECMQmlModule)
include(KDEGitCommitHooks)
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml)
if (Qt6WaylandClient_VERSION VERSION_GREATER_EQUAL "6.10.0")
find_package(Qt6WaylandClientPrivate ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
endif()
find_package(WaylandScanner REQUIRED)
find_package(Wayland 1.3 COMPONENTS Client Server)
find_package(WaylandProtocols REQUIRED)
@ -55,8 +60,8 @@ kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT)
ecm_set_disabled_deprecation_versions(QT 6.5
KF 5.240
ecm_set_disabled_deprecation_versions(QT 6.8.1
KF 6.9.0
)
add_subdirectory(src)

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: CC0-1.0
maintainer:
- vladz
- vladz
description: Layer Shell Qt
platforms:
- name: Linux

View File

@ -4,7 +4,15 @@
remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
add_library(LayerShellQtInterface)
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES
qt6_extract_metatypes(LayerShellQtInterface)
if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0")
set(private_code_option "PRIVATE_CODE")
endif()
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface
${private_code_option}
FILES
${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
${WaylandProtocols_DATADIR}/staging/xdg-activation/xdg-activation-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/wlr-layer-shell-unstable-v1.xml

View File

@ -4,7 +4,8 @@
ecm_add_qml_module(LayerShellQtQml
URI "org.kde.layershell"
VERSION 1.0
SOURCES layershellqtplugin.cpp)
SOURCES types.h
GENERATE_PLUGIN_SOURCE)
target_link_libraries(LayerShellQtQml PRIVATE Qt::Qml LayerShellQtInterface)
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 <QPlatformSurfaceEvent>
#include <QPointer>
#include <optional>
@ -32,8 +33,11 @@ public:
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
Window::Layer layer = Window::LayerTop;
QMargins margins;
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
QSize desiredSize = QSize(0, 0);
QPointer<QScreen> desiredScreen;
bool desiredActiveScreen = false;
bool closeOnDismissed = true;
bool activateOnShow = true;
};
static QMap<QWindow *, Window *> s_map;
@ -97,6 +101,21 @@ 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) {
@ -134,14 +153,46 @@ Window::Layer Window::layer() const
return d->layer;
}
Window::ScreenConfiguration Window::screenConfiguration() const
void Window::setDesiredActiveScreen(bool set)
{
return d->screenConfiguration;
if (d->desiredActiveScreen == set) {
return;
}
d->desiredActiveScreen = set;
if (d->desiredActiveScreen && d->desiredScreen) {
d->desiredScreen = nullptr;
Q_EMIT desiredScreenChanged();
}
Q_EMIT desiredActiveScreenChanged();
}
void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration)
bool Window::desiredActiveScreen() const
{
d->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;
}
bool Window::closeOnDismissed() const
@ -154,17 +205,50 @@ 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.";
}
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) {
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;
}
@ -178,7 +262,6 @@ Window::Window(QWindow *window)
return;
}
}
waylandWindow->setShellIntegration(shellIntegration);
}

View File

@ -27,7 +27,9 @@ class LAYERSHELLQT_EXPORT Window : public QObject
Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged)
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
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)
public:
~Window() override;
@ -39,8 +41,8 @@ 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 type is used to specify the layer where a surface can be put in.
@ -63,17 +65,6 @@ 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;
@ -86,14 +77,42 @@ public:
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;
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
ScreenConfiguration screenConfiguration() 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;
/**
* Sets a string based identifier for this window.
@ -114,6 +133,18 @@ 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
@ -122,15 +153,22 @@ public:
static Window *qmlAttachedProperties(QObject *object);
bool eventFilter(QObject *watched, QEvent *event) override;
Q_SIGNALS:
void anchorsChanged();
void exclusionZoneChanged();
void exclusiveEdgeChanged();
void marginsChanged();
void desiredSizeChanged();
void keyboardInteractivityChanged();
void layerChanged();
void desiredActiveScreenChanged();
void desiredScreenChanged();
private:
void initializeShell();
Window(QWindow *window);
QScopedPointer<WindowPrivate> d;
};

View File

@ -26,7 +26,12 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
, m_window(window)
{
wl_output *output = nullptr;
if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) {
if (!m_interface->desiredActiveScreen()) {
QScreen *desiredScreen = m_interface->desiredScreen();
if (!desiredScreen) {
window->window()->screen();
}
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
@ -44,7 +49,11 @@ 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());
}
});
setExclusiveZone(m_interface->exclusionZone());
@ -61,12 +70,22 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
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());
}
}
QWaylandLayerSurface::~QWaylandLayerSurface()
@ -110,9 +129,7 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po
void QWaylandLayerSurface::applyConfigure()
{
m_configuring = true;
window()->resizeFromApplyConfigure(m_pendingSize);
m_configuring = false;
}
void QWaylandLayerSurface::setDesiredSize(const QSize &size)
@ -163,13 +180,11 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
set_layer(layer);
}
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
void QWaylandLayerSurface::setWindowSize(const QSize &size)
{
if (m_configuring) {
return;
if (m_interface->desiredSize().isNull()) {
setDesiredSize(size);
}
setDesiredSize(geometry.size());
}
bool QWaylandLayerSurface::requestActivate()
@ -182,6 +197,10 @@ 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();
@ -197,6 +216,23 @@ 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;
@ -218,11 +254,6 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
void QWaylandLayerSurface::sendExpose()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
window()->handleExpose(QRect(QPoint(), m_pendingSize));
#else
window()->sendRecursiveExposeEvent();
#endif
window()->updateExposure();
}
}

View File

@ -43,9 +43,10 @@ public:
void setLayer(uint32_t layer);
void applyConfigure() override;
void setWindowGeometry(const QRect &geometry) override;
void setWindowSize(const QSize &size) override;
bool requestActivate() override;
bool requestActivateOnShow() override;
void setXdgActivationToken(const QString &token) override;
void requestXdgActivationToken(quint32 serial) override;
@ -61,7 +62,6 @@ private:
QString m_activationToken;
bool m_configured = false;
bool m_configuring = false;
};
}

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);
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchor>();
const auto anchorMetaEnum = QMetaEnum::fromType<Window::Anchors>();
QCommandLineParser parser;
QCommandLineOption marginsOption(QStringLiteral("margins"), QStringLiteral("Window margins"), QStringLiteral("pixels"), QStringLiteral("0"));