summaryrefslogtreecommitdiffstats
path: root/examples/wayland/custom-shell/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'examples/wayland/custom-shell/compositor')
-rw-r--r--examples/wayland/custom-shell/compositor/CMakeLists.txt57
-rw-r--r--examples/wayland/custom-shell/compositor/compositor.pro29
-rw-r--r--examples/wayland/custom-shell/compositor/compositor.qrc6
-rw-r--r--examples/wayland/custom-shell/compositor/exampleshell.cpp119
-rw-r--r--examples/wayland/custom-shell/compositor/exampleshell.h88
-rw-r--r--examples/wayland/custom-shell/compositor/exampleshellintegration.cpp29
-rw-r--r--examples/wayland/custom-shell/compositor/exampleshellintegration.h26
-rw-r--r--examples/wayland/custom-shell/compositor/images/background.pngbin0 -> 2275 bytes
-rw-r--r--examples/wayland/custom-shell/compositor/main.cpp29
-rw-r--r--examples/wayland/custom-shell/compositor/qml/main.qml72
10 files changed, 455 insertions, 0 deletions
diff --git a/examples/wayland/custom-shell/compositor/CMakeLists.txt b/examples/wayland/custom-shell/compositor/CMakeLists.txt
new file mode 100644
index 000000000..be1d7f623
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/CMakeLists.txt
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.14)
+project(custom-shell-compositor)
+
+set(CMAKE_AUTOMOC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/wayland/custom-shell/compositor")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml WaylandCompositor)
+
+qt_add_executable(custom-shell-compositor
+ exampleshell.cpp exampleshell.h
+ exampleshellintegration.cpp exampleshellintegration.h
+ main.cpp
+)
+
+qt6_generate_wayland_protocol_server_sources(custom-shell-compositor
+ FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/../protocol/example-shell.xml
+)
+
+set_target_properties(custom-shell-compositor PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(custom-shell-compositor PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::WaylandCompositor
+)
+
+# Resources:
+set(compositor_resource_files
+ "images/background.png"
+ "qml/main.qml"
+)
+
+qt6_add_resources(custom-shell-compositor "compositor"
+ PREFIX
+ "/"
+ FILES
+ ${compositor_resource_files}
+)
+
+install(TARGETS custom-shell-compositor
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/wayland/custom-shell/compositor/compositor.pro b/examples/wayland/custom-shell/compositor/compositor.pro
new file mode 100644
index 000000000..d64ddac61
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/compositor.pro
@@ -0,0 +1,29 @@
+QT += core gui qml
+
+QT += waylandcompositor
+
+CONFIG += wayland-scanner
+CONFIG += c++11
+SOURCES += \
+ main.cpp \
+ exampleshell.cpp \
+ exampleshellintegration.cpp \
+
+HEADERS += \
+ exampleshell.h \
+ exampleshellintegration.h
+
+OTHER_FILES = \
+ qml/main.qml \
+ images/background.jpg
+
+WAYLANDSERVERSOURCES += \
+ ../protocol/example-shell.xml
+
+RESOURCES += compositor.qrc
+
+TARGET = custom-shell-compositor
+
+
+target.path = $$[QT_INSTALL_EXAMPLES]/wayland/custom-shell/compositor
+INSTALLS += target
diff --git a/examples/wayland/custom-shell/compositor/compositor.qrc b/examples/wayland/custom-shell/compositor/compositor.qrc
new file mode 100644
index 000000000..59c00f5f9
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/compositor.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/background.png</file>
+ <file>qml/main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/wayland/custom-shell/compositor/exampleshell.cpp b/examples/wayland/custom-shell/compositor/exampleshell.cpp
new file mode 100644
index 000000000..f134a8ba6
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/exampleshell.cpp
@@ -0,0 +1,119 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "exampleshell.h"
+#include "exampleshellintegration.h"
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandResource>
+
+ExampleShell::ExampleShell()
+{
+}
+
+ExampleShell::ExampleShell(QWaylandCompositor *compositor)
+ : QWaylandCompositorExtensionTemplate<ExampleShell>(compositor)
+{
+ this->compositor = compositor;
+}
+
+//! [initialize]
+void ExampleShell::initialize()
+{
+ QWaylandCompositorExtensionTemplate::initialize();
+
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qWarning() << "Failed to find QWaylandCompositor when initializing ExampleShell";
+ return;
+ }
+
+ init(compositor->display(), 1);
+}
+//! [initialize]
+
+//! [surface_create]
+void ExampleShell::example_shell_surface_create(Resource *resource, wl_resource *surfaceResource, uint32_t id)
+{
+ QWaylandSurface *surface = QWaylandSurface::fromResource(surfaceResource);
+
+ if (!surface->setRole(ExampleShellSurface::role(), resource->handle, QT_EXAMPLE_SHELL_ERROR_ROLE))
+ return;
+
+ QWaylandResource shellSurfaceResource(wl_resource_create(resource->client(), &::qt_example_shell_surface_interface,
+ wl_resource_get_version(resource->handle), id));
+
+ auto *shellSurface = new ExampleShellSurface(this, surface, shellSurfaceResource);
+ emit shellSurfaceCreated(shellSurface);
+}
+//! [surface_create]
+
+ExampleShellSurface::ExampleShellSurface(ExampleShell *shell, QWaylandSurface *surface, const QWaylandResource &resource)
+{
+ m_shell = shell;
+ m_surface = surface;
+ init(resource.resource());
+ setExtensionContainer(surface);
+ QWaylandCompositorExtension::initialize();
+}
+
+QWaylandSurfaceRole ExampleShellSurface::s_role("qt_example_shell_surface");
+
+/*!
+ * Returns the surface role for the ExampleShellSurface.
+ */
+QWaylandSurfaceRole *ExampleShellSurface::role()
+{
+ return &s_role;
+}
+
+/*!
+ * Returns the ExampleShellSurface corresponding to the \a resource.
+ */
+ExampleShellSurface *ExampleShellSurface::fromResource(wl_resource *resource)
+{
+ auto *res = Resource::fromResource(resource);
+ return static_cast<ExampleShellSurface *>(res->object());
+}
+
+QWaylandQuickShellIntegration *ExampleShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
+{
+ return new ExampleShellIntegration(item);
+}
+
+void ExampleShellSurface::example_shell_surface_destroy_resource(Resource *resource)
+{
+ Q_UNUSED(resource);
+ delete this;
+}
+
+void ExampleShellSurface::example_shell_surface_destroy(Resource *resource)
+{
+ wl_resource_destroy(resource->handle);
+}
+
+void ExampleShellSurface::example_shell_surface_set_window_title(Resource *resource, const QString &window_title)
+{
+ Q_UNUSED(resource);
+ m_windowTitle = window_title;
+ emit windowTitleChanged();
+}
+
+void ExampleShellSurface::example_shell_surface_set_minimized(Resource *resource, uint32_t minimized)
+{
+ Q_UNUSED(resource);
+ if (m_minimized != minimized) {
+ m_minimized = minimized;
+ emit minimizedChanged();
+ }
+}
+
+void ExampleShellSurface::setMinimized(bool newMinimized)
+{
+ if (m_minimized == newMinimized)
+ return;
+ m_minimized = newMinimized;
+ send_minimize(newMinimized);
+ emit minimizedChanged();
+}
diff --git a/examples/wayland/custom-shell/compositor/exampleshell.h b/examples/wayland/custom-shell/compositor/exampleshell.h
new file mode 100644
index 000000000..5dd8b6c98
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/exampleshell.h
@@ -0,0 +1,88 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef EXAMPLESHELL_H
+#define EXAMPLESHELL_H
+
+#include <QtWaylandCompositor/QWaylandCompositorExtension>
+#include <QtWaylandCompositor/QWaylandQuickExtension>
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandResource>
+#include <QtCore/QSize>
+
+#include <QtWaylandCompositor/QWaylandShellSurface>
+#include "qwayland-server-example-shell.h"
+
+class ExampleShellSurface;
+
+//! [ExampleShell]
+class ExampleShell
+ : public QWaylandCompositorExtensionTemplate<ExampleShell>
+ , QtWaylandServer::qt_example_shell
+//! [ExampleShell]
+{
+ Q_OBJECT
+public:
+ ExampleShell();
+ ExampleShell(QWaylandCompositor *compositor);
+
+ void initialize() override;
+
+ using QtWaylandServer::qt_example_shell::interface;
+ using QtWaylandServer::qt_example_shell::interfaceName;
+
+protected:
+ void example_shell_surface_create(Resource *resource, wl_resource *surfaceResource, uint32_t id) override;
+
+signals:
+ void shellSurfaceCreated(ExampleShellSurface *shellSurface);
+
+private:
+ QWaylandCompositor *compositor;
+};
+
+class ExampleShellSurface :
+ public QWaylandShellSurfaceTemplate<ExampleShellSurface>
+ , public QtWaylandServer::qt_example_shell_surface
+{
+ Q_OBJECT
+ Q_PROPERTY(QString windowTitle READ windowTitle NOTIFY windowTitleChanged)
+ Q_PROPERTY(bool minimized READ minimized WRITE setMinimized NOTIFY minimizedChanged)
+public:
+ ExampleShellSurface(ExampleShell *shell, QWaylandSurface *surface, const QWaylandResource &resource);
+
+ using QtWaylandServer::qt_example_shell_surface::interface;
+ using QtWaylandServer::qt_example_shell_surface::interfaceName;
+ static QWaylandSurfaceRole *role();
+ static ExampleShellSurface *fromResource(::wl_resource *resource);
+
+ QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override;
+
+ QWaylandSurface *surface() const { return m_surface; }
+ const QString &windowTitle() const { return m_windowTitle; }
+ bool minimized() const { return m_minimized; }
+ void setMinimized(bool newMinimized);
+
+signals:
+ void windowTitleChanged();
+ void minimizedChanged();
+
+protected:
+ void example_shell_surface_destroy_resource(Resource *resource) override;
+ void example_shell_surface_destroy(Resource *resource) override;
+ void example_shell_surface_set_window_title(Resource *resource, const QString &window_title) override;
+ void example_shell_surface_set_minimized(Resource *resource, uint32_t minimized) override;
+
+private:
+ static QWaylandSurfaceRole s_role;
+ QWaylandSurface *m_surface = nullptr;
+ ExampleShell *m_shell = nullptr;
+ QString m_windowTitle;
+ bool m_minimized = false;
+};
+
+//! [declare_extension]
+Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(ExampleShell)
+//! [declare_extension]
+
+#endif // EXAMPLESHELL_H
diff --git a/examples/wayland/custom-shell/compositor/exampleshellintegration.cpp b/examples/wayland/custom-shell/compositor/exampleshellintegration.cpp
new file mode 100644
index 000000000..840927d0f
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/exampleshellintegration.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "exampleshellintegration.h"
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
+#include <QtWaylandCompositor/QWaylandSeat>
+#include "exampleshell.h"
+
+
+ExampleShellIntegration::ExampleShellIntegration(QWaylandQuickShellSurfaceItem *item)
+ : QWaylandQuickShellIntegration(item)
+ , m_item(item)
+ , m_shellSurface(qobject_cast<ExampleShellSurface *>(item->shellSurface()))
+{
+ m_item->setSurface(m_shellSurface->surface());
+ connect(m_shellSurface, &ExampleShellSurface::destroyed, this, &ExampleShellIntegration::handleExampleShellSurfaceDestroyed);
+}
+
+ExampleShellIntegration::~ExampleShellIntegration()
+{
+ m_item->setSurface(nullptr);
+}
+
+void ExampleShellIntegration::handleExampleShellSurfaceDestroyed()
+{
+ m_shellSurface = nullptr;
+}
diff --git a/examples/wayland/custom-shell/compositor/exampleshellintegration.h b/examples/wayland/custom-shell/compositor/exampleshellintegration.h
new file mode 100644
index 000000000..d03826ef0
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/exampleshellintegration.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef EXAMPLESHELLINTEGRATION_H
+#define EXAMPLESHELLINTEGRATION_H
+
+#include "exampleshell.h"
+#include <QtWaylandCompositor/QWaylandQuickShellIntegration>
+#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
+
+class ExampleShellIntegration : public QWaylandQuickShellIntegration
+{
+ Q_OBJECT
+public:
+ ExampleShellIntegration(QWaylandQuickShellSurfaceItem *item);
+ ~ExampleShellIntegration() override;
+
+private slots:
+ void handleExampleShellSurfaceDestroyed();
+
+private:
+ QWaylandQuickShellSurfaceItem *m_item = nullptr;
+ ExampleShellSurface *m_shellSurface = nullptr;
+};
+
+#endif // EXAMPLESHELLINTEGRATION_H
diff --git a/examples/wayland/custom-shell/compositor/images/background.png b/examples/wayland/custom-shell/compositor/images/background.png
new file mode 100644
index 000000000..cf264746f
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/images/background.png
Binary files differ
diff --git a/examples/wayland/custom-shell/compositor/main.cpp b/examples/wayland/custom-shell/compositor/main.cpp
new file mode 100644
index 000000000..72f233e8e
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/main.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+
+#include <QtQml/qqml.h>
+#include <QtQml/QQmlEngine>
+
+#include "exampleshell.h"
+
+static void registerTypes()
+{
+ qmlRegisterType<ExampleShellQuickExtension>("io.qt.examples", 1, 0, "ExampleShell");
+}
+
+int main(int argc, char *argv[])
+{
+ // ShareOpenGLContexts is needed for using the threaded renderer
+ // on Nvidia EGLStreams
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
+ QGuiApplication app(argc, argv);
+ registerTypes();
+ QQmlApplicationEngine appEngine(QUrl("qrc:///qml/main.qml"));
+
+ return app.exec();
+}
diff --git a/examples/wayland/custom-shell/compositor/qml/main.qml b/examples/wayland/custom-shell/compositor/qml/main.qml
new file mode 100644
index 000000000..149e0e748
--- /dev/null
+++ b/examples/wayland/custom-shell/compositor/qml/main.qml
@@ -0,0 +1,72 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtWayland.Compositor
+import QtQuick.Layouts
+import QtQuick.Controls
+
+import io.qt.examples 1.0
+
+WaylandCompositor {
+ id: comp
+
+ ListModel { id: shellSurfaces }
+
+
+ WaylandOutput {
+ sizeFollowsWindow: true
+ window: Window {
+ width: 1024
+ height: 768
+ visible: true
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+ Image {
+ fillMode: Image.Tile
+ source: "qrc:/images/background.png"
+ smooth: false
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ GridLayout {
+ columns: 3
+ Repeater {
+ model: shellSurfaces
+ ShellSurfaceItem {
+ id: chrome
+ shellSurface: modelData
+ visible: !shellSurface.minimized
+ onSurfaceDestroyed: shellSurfaces.remove(index)
+ }
+ }
+ }
+ }
+ Row {
+ id: taskbar
+ Layout.fillWidth: true
+ Repeater {
+ model: shellSurfaces
+ Button {
+ id: minimizeButton
+ checkable: true
+ text: modelData.windowTitle
+ onCheckedChanged: modelData.minimized = checked
+ checked: modelData.minimized
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //! [ExampleShell]
+ ExampleShell {
+ id: shell
+ onShellSurfaceCreated: (shellSurface) => {
+ shellSurfaces.append({shellSurface: shellSurface});
+ }
+ }
+ //! [ExampleShell]
+}