diff --git a/CMakeLists.txt b/CMakeLists.txt index fc4452a..a4d9634 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ include(CMakePackageConfigHelpers) include(FeatureSummary) include(GenerateExportHeader) include(KDEClangFormat) +include(ECMQmlModule) include(ECMQtDeclareLoggingCategory) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 176fa52..30ebc20 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/declarative/CMakeLists.txt b/src/declarative/CMakeLists.txt new file mode 100644 index 0000000..8e804b9 --- /dev/null +++ b/src/declarative/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez +# 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}) diff --git a/src/declarative/layershellqtplugin.cpp b/src/declarative/layershellqtplugin.cpp new file mode 100644 index 0000000..4c89ae4 --- /dev/null +++ b/src/declarative/layershellqtplugin.cpp @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include +#include "../interfaces/window.h" +#include + +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(uri, 1, 0, "Window"); + } +}; + +#include "layershellqtplugin.moc" diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp index 7aa39f4..c7cc0c4 100644 --- a/src/interfaces/window.cpp +++ b/src/interfaces/window.cpp @@ -126,9 +126,18 @@ Window::Window(QWindow *window) 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(object)); +} diff --git a/src/interfaces/window.h b/src/interfaces/window.h index 5ebc9b1..90fdd65 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -21,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 { @@ -87,12 +95,17 @@ 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); + static Window *qmlAttachedProperties(QObject *object); + Q_SIGNALS: void anchorsChanged(); void exclusionZoneChanged(); @@ -101,7 +114,6 @@ Q_SIGNALS: void layerChanged(); private: - Window(QWindow *window); QScopedPointer d; }; diff --git a/tests/quicktest.qml b/tests/quicktest.qml new file mode 100644 index 0000000..99cbb3d --- /dev/null +++ b/tests/quicktest.qml @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * + * 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 + } +}