Compare commits

..

10 Commits

Author SHA1 Message Date
1618161af3 Expose the Window interface to QML
If we are designing our UI's windows from QML, it makes sense that we
might want to configure how they're placed from the same place.

Everything was already in place but for a few technical bits which this
change adds.

Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
2023-07-13 10:51:12 +02:00
d610813bac Update version number for 5.27.6
GIT_SILENT
2023-06-20 14:02:45 +01:00
debc455bd5 Update version number for 5.27.5
GIT_SILENT
2023-05-09 12:18:32 +01:00
b2dcb1acff Update version number for 5.27.4
GIT_SILENT
2023-04-04 11:21:08 +01:00
94eb90d823 Update version number for 5.27.3
GIT_SILENT
2023-03-14 11:53:20 +00:00
dac784828f Update version number for 5.27.2
GIT_SILENT
2023-02-28 12:01:30 +00:00
ddc4aead87 Use the QScreen of the QWindow as default output
If the Window::setDesiredOutput API was not called for the QWindow, use
QWindow::screen(). This allows assigning QWindows to specific screens using
the plain Qt API.

Passing nullptr to Window::setDesiredOutput explicitly results in nil as
desired output for the layer, which lets the compositor select a screen.

(cherry picked from commit 3c85e2e889)
2023-02-23 09:38:55 +01:00
7a862bdcd4 Update version number for 5.27.1
GIT_SILENT
2023-02-21 11:05:04 +00:00
b758105bd7 Update version number for 5.27.0
GIT_SILENT
2023-02-09 11:41:27 +00:00
79441811ff Update kf5 version requirement to 5.102.0
GIT_SILENT
2023-01-21 20:17:53 +00:00
15 changed files with 215 additions and 63 deletions

View File

@ -3,5 +3,7 @@
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml

View File

@ -4,4 +4,4 @@
Dependencies:
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@latest-kf6'
'frameworks/extra-cmake-modules': '@latest'

View File

@ -4,19 +4,19 @@
cmake_minimum_required(VERSION 3.16)
project(layershellqt)
set(PROJECT_VERSION "5.27.80")
set(PROJECT_VERSION "5.27.6")
set(PROJECT_VERSION_MAJOR 5)
set(CMAKE_C_STANDARD 99)
set(QT_MIN_VERSION "6.5.0")
set(KF6_MIN_VERSION "5.240.0")
set(QT_MIN_VERSION "5.15.2")
set(KF5_MIN_VERSION "5.102.0")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${ECM_MODULE_PATH})
include(KDEInstallDirs)
@ -29,6 +29,7 @@ include(CMakePackageConfigHelpers)
include(FeatureSummary)
include(GenerateExportHeader)
include(KDEClangFormat)
include(ECMQmlModule)
include(ECMQtDeclareLoggingCategory)

View File

@ -24,7 +24,8 @@ ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
)
target_sources(LayerShellQtInterface PRIVATE qwaylandlayersurface.cpp interfaces/window.cpp interfaces/shell.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
target_link_libraries(LayerShellQtInterface PRIVATE Qt::Gui Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
target_link_libraries(LayerShellQtInterface PUBLIC Qt::Gui)
target_link_libraries(LayerShellQtInterface PRIVATE Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
if (TARGET Qt::XkbCommonSupportPrivate)
target_link_libraries(LayerShellQtInterface PRIVATE Qt::XkbCommonSupportPrivate)
endif()
@ -68,3 +69,5 @@ install(FILES
${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt/layershellqt_export.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/LayerShellQt COMPONENT Devel
)
add_subdirectory(declarative)

View File

@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleix.pol_gonzalez@mercedes-benz.com>
# SPDX-License-Identifier: BSD-3-Clause
ecm_add_qml_module(LayerShellQtQml URI "org.kde.layershell")
target_sources(LayerShellQtQml PRIVATE layershellqtplugin.cpp)
target_link_libraries(LayerShellQtQml PRIVATE Qt::Qml LayerShellQtInterface)
ecm_finalize_qml_module(LayerShellQtQml DESTINATION ${KDE_INSTALL_QMLDIR})

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleix.pol_gonzalez@mercedes-benz.com>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <QQmlExtensionPlugin>
#include "../interfaces/window.h"
#include <qqml.h>
QML_DECLARE_TYPEINFO(LayerShellQt::Window, QML_HAS_ATTACHED_PROPERTIES)
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");
}
};
#include "layershellqtplugin.moc"

View File

@ -5,18 +5,11 @@
*/
#include "window.h"
#include "../qwaylandlayershellintegration_p.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#include "../qwaylandlayersurface_p.h"
#endif
#include <layershellqt_logging.h>
#include <QPointer>
#include <optional>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
using namespace LayerShellQt;
class LayerShellQt::WindowPrivate
@ -124,40 +117,27 @@ void Window::setDesiredOutput(QScreen *output)
d->desiredOutput = output;
}
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
void Window::attachPopup(QWindow *window, xdg_popup *popup)
{
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
if (!waylandWindow) {
return;
}
auto shellSurface = dynamic_cast<QWaylandLayerSurface *>(waylandWindow->shellSurface());
if (shellSurface) {
shellSurface->get_popup(popup);
}
}
#endif
Window::Window(QWindow *window)
: QObject(window)
, d(new WindowPrivate(window))
{
s_map.insert(d->parentWindow, this);
window->create();
if (auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle())) {
static QWaylandLayerShellIntegration integration;
waylandWindow->setShellIntegration(&integration);
}
}
Window *Window::get(QWindow *window)
{
if (!window) {
return nullptr;
}
auto layerShellWindow = s_map.value(window);
if (layerShellWindow) {
return layerShellWindow;
}
return new Window(window);
}
Window *Window::qmlAttachedProperties(QObject *object)
{
return get(qobject_cast<QWindow *>(object));
}

View File

@ -14,10 +14,6 @@
#include "layershellqt_export.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
struct xdg_popup;
#endif
namespace LayerShellQt
{
class WindowPrivate;
@ -25,7 +21,15 @@ class WindowPrivate;
class LAYERSHELLQT_EXPORT Window : public QObject
{
Q_OBJECT
Q_PROPERTY(int anchors READ anchors WRITE setAnchorsInt NOTIFY anchorsChanged)
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(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
public:
Window(QWindow *window = nullptr);
~Window() override;
enum Anchor {
@ -91,15 +95,16 @@ public:
void setScope(const QString &scope);
QString scope() const;
/// Workaround needed for Qt 5 not to get confused with types, not necessary on Qt 6
void setAnchorsInt(int x) { setAnchors(Anchors(x)); }
/**
* Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred
*/
static Window *get(QWindow *window);
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
static void attachPopup(QWindow *window, xdg_popup *popup);
#endif
static Window *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
void anchorsChanged();
@ -109,7 +114,6 @@ Q_SIGNALS:
void layerChanged();
private:
Window(QWindow *window);
QScopedPointer<WindowPrivate> d;
};

View File

@ -10,11 +10,9 @@
namespace LayerShellQt
{
QWaylandLayerShell::QWaylandLayerShell()
: QWaylandClientExtensionTemplate<QWaylandLayerShell>(4)
, QtWayland::zwlr_layer_shell_v1()
QWaylandLayerShell::QWaylandLayerShell(::wl_registry *registry, uint32_t id, uint32_t version)
: QtWayland::zwlr_layer_shell_v1(registry, id, version)
{
initialize();
}
QWaylandLayerShell::~QWaylandLayerShell()
@ -23,4 +21,9 @@ QWaylandLayerShell::~QWaylandLayerShell()
zwlr_layer_shell_v1_destroy(object());
}
QWaylandLayerSurface *QWaylandLayerShell::createLayerSurface(QtWaylandClient::QWaylandWindow *window)
{
return new QWaylandLayerSurface(this, window);
}
}

View File

@ -8,20 +8,23 @@
#ifndef _LAYERSHELL_H
#define _LAYERSHELL_H
#include "layershellqt_export.h"
#include <wayland-client.h>
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
#include "qwaylandlayersurface_p.h"
namespace LayerShellQt
{
class LAYERSHELLQT_EXPORT QWaylandLayerShell : public QWaylandClientExtensionTemplate<QWaylandLayerShell>, public QtWayland::zwlr_layer_shell_v1
class LAYERSHELLQT_EXPORT QWaylandLayerShell : public QtWayland::zwlr_layer_shell_v1
{
public:
QWaylandLayerShell();
QWaylandLayerShell(::wl_registry *registry, uint32_t id, uint32_t version);
~QWaylandLayerShell() override;
QWaylandLayerSurface *createLayerSurface(QtWaylandClient::QWaylandWindow *window);
// TODO: Popups
};
}

View File

@ -7,7 +7,6 @@
#include "qwaylandlayershell_p.h"
#include "qwaylandlayershellintegration_p.h"
#include "qwaylandlayersurface_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
@ -16,7 +15,6 @@
namespace LayerShellQt
{
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
: m_layerShell(new QWaylandLayerShell())
{
}
@ -26,14 +24,26 @@ QWaylandLayerShellIntegration::~QWaylandLayerShellIntegration()
bool QWaylandLayerShellIntegration::initialize(QtWaylandClient::QWaylandDisplay *display)
{
Q_UNUSED(display)
return m_layerShell->isActive();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QWaylandShellIntegration::initialize(display);
#endif
display->addRegistryListener(registryLayer, this);
return m_layerShell != nullptr;
}
QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration::createShellSurface(QtWaylandClient::QWaylandWindow *window)
{
return new QWaylandLayerSurface(m_layerShell.get(), window);
return m_layerShell->createLayerSurface(window);
}
void QWaylandLayerShellIntegration::registryLayer(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version)
{
QWaylandLayerShellIntegration *shell = static_cast<QWaylandLayerShellIntegration *>(data);
if (interface == zwlr_layer_shell_v1_interface.name)
shell->m_layerShell.reset(new QWaylandLayerShell(registry, id, std::min(version, 4u)));
}
}
//#include "qwaylandlayershellintegration.moc"

View File

@ -27,6 +27,8 @@ public:
QtWaylandClient::QWaylandShellSurface *createShellSurface(QtWaylandClient::QWaylandWindow *window) override;
private:
static void registryLayer(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version);
QScopedPointer<QWaylandLayerShell> m_layerShell;
};

View File

@ -5,7 +5,7 @@
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "interfaces/window.h"
#include "interfaces/shell.h"
#include "layershellqt_logging.h"
#include "qwaylandlayershell_p.h"
#include "qwaylandlayersurface_p.h"

View File

@ -14,6 +14,7 @@
#include <QMetaEnum>
#include <interfaces/shell.h>
#include <interfaces/window.h>
using namespace LayerShellQt;
@ -50,6 +51,8 @@ class BasicWindow : public QRasterWindow
int main(int argc, char **argv)
{
Shell::useLayerShell();
QGuiApplication app(argc, argv);
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
@ -76,8 +79,6 @@ int main(int argc, char **argv)
BasicWindow window;
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window);
layerShell->setLayer(Window::LayerBottom);
if (parser.isSet(marginsOption)) {
int margins = parser.value(marginsOption).toInt();
layerShell->setMargins({margins, margins, margins, margins});
@ -101,10 +102,6 @@ int main(int argc, char **argv)
window.show();
BasicWindow window2;
window2.resize(400, 400);
window2.show();
// just so you don't block yourself out whilst testing
QTimer::singleShot(5000, &app, &QGuiApplication::quit);
return app.exec();

115
tests/quicktest.qml Normal file
View File

@ -0,0 +1,115 @@
/*
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleix.pol_gonzalez@mercedes-benz.com>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Window 2.15
import org.kde.layershell 1.0 as LayerShell
Item
{
Text {
text: "A normal Window"
anchors.centerIn: parent
}
Window {
LayerShell.Window.anchors: LayerShell.Window.AnchorLeft
LayerShell.Window.layer: LayerShell.Window.LayerBackground
LayerShell.Window.exclusionZone: -1
Component.onCompleted: {
console.log("xxxx", LayerShell.Window.AnchorLeft, LayerShell.Window.anchors)
}
width: 200
height: 150
Rectangle {
anchors.fill: parent
color: "green"
Text {
anchors.centerIn: parent
text: "left bg"
}
}
visible: true
}
Window {
LayerShell.Window.scope: "dock"
LayerShell.Window.anchors: LayerShell.Window.AnchorLeft
LayerShell.Window.layer: LayerShell.Window.LayerTop
LayerShell.Window.exclusionZone: width
width: 100
height: 100
Rectangle {
anchors.fill: parent
color: "red"
Text {
anchors.centerIn: parent
text: "left"
}
}
visible: true
}
Window {
LayerShell.Window.scope: "normal"
LayerShell.Window.anchors: LayerShell.Window.AnchorRight
width: 100
height: 100
Rectangle {
anchors.fill: parent
color: "red"
Text {
anchors.centerIn: parent
text: "right"
}
}
visible: true
}
Window {
LayerShell.Window.scope: "normal"
LayerShell.Window.anchors: LayerShell.Window.AnchorTop
width: 100
height: 100
Rectangle {
anchors.fill: parent
color: "red"
Text {
anchors.centerIn: parent
text: "top"
}
}
visible: true
}
Window {
LayerShell.Window.scope: "normal"
LayerShell.Window.anchors: LayerShell.Window.AnchorBottom
width: 100
height: 100
Rectangle {
anchors.fill: parent
color: "red"
Text {
anchors.centerIn: parent
text: "bottom"
}
}
visible: true
}
}