This commit is contained in:
Vlad Zahorodnii 2021-11-26 21:16:54 +02:00
parent 3214fb588f
commit 2502a4a6dd
14 changed files with 36 additions and 145 deletions

View File

@ -15,7 +15,7 @@ ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
layershellqt
)
add_library(LayerShellQtInterface SHARED qwaylandlayersurface.cpp interfaces/window.cpp interfaces/shell.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
add_library(LayerShellQtInterface SHARED qwaylandlayersurface.cpp interfaces/window.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
target_link_libraries(LayerShellQtInterface PRIVATE Qt::Gui Qt::WaylandClientPrivate Wayland::Client)
target_include_directories(LayerShellQtInterface PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt>"
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/>"
@ -26,27 +26,19 @@ set_target_properties(LayerShellQtInterface PROPERTIES VERSION ${LAYERSHELLQT_
EXPORT_NAME Interface
)
add_library(layer-shell SHARED qwaylandlayershellintegrationplugin.cpp)
target_link_libraries(layer-shell LayerShellQtInterface Qt::WaylandClient Qt::WaylandClientPrivate Wayland::Client)
ecm_generate_headers(LayerShellQt_HEADERS
HEADER_NAMES
Shell
Window
RELATIVE interfaces/
REQUIRED_HEADERS LayerShellQt_HEADERS
)
generate_export_header(LayerShellQtInterface
BASE_NAME LayerShellQtInterface
EXPORT_MACRO_NAME LAYERSHELLQT_EXPORT
EXPORT_FILE_NAME LayerShellQt/layershellqt_export.h
)
install(TARGETS layer-shell
LIBRARY DESTINATION ${QT_PLUGIN_INSTALL_DIR}/wayland-shell-integration)
install(TARGETS LayerShellQtInterface EXPORT LayerShellQtTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES

View File

@ -1,20 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "shell.h"
#include <QByteArray>
#include <layershellqt_logging.h>
#include <qglobal.h>
using namespace LayerShellQt;
void Shell::useLayerShell()
{
const bool ret = qputenv("QT_WAYLAND_SHELL_INTEGRATION", "layer-shell");
if (!ret) {
qCDebug(LAYERSHELLQT) << "Unable to set QT_WAYLAND_SHELL_INTEGRATION=layer-shell";
}
}

View File

@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef LAYERSHELLQTSHELL_H
#define LAYERSHELLQTSHELL_H
#include "layershellqt_export.h"
#include "window.h"
#include <QString>
namespace LayerShellQt
{
/**
* Sets the right environment so the shells created from now on use wlr-layer-shell.
*/
class LAYERSHELLQT_EXPORT Shell
{
public:
static void useLayerShell();
};
}
#endif

View File

@ -6,12 +6,15 @@
#include "window.h"
#include "../qwaylandlayersurface_p.h"
#include "../qwaylandlayershellintegration_p.h"
#include <layershellqt_logging.h>
#include <private/qwaylandshellsurface_p.h>
#include <private/qwaylandwindow_p.h>
using namespace LayerShellQt;
static const char *s_interfaceKey = "__kde_layer_window";
class LayerShellQt::WindowPrivate
{
public:
@ -30,11 +33,9 @@ public:
QWaylandLayerSurface *getSurface() const;
};
static QMap<QWindow *, Window *> s_map;
Window::~Window()
{
s_map.remove(d->parentWindow);
d->parentWindow->setProperty(s_interfaceKey, QVariant());
}
void Window::setAnchors(Anchors anchors)
@ -113,20 +114,28 @@ Window::Layer Window::layer() const
return d->layer;
}
static QWaylandLayerShellIntegration *s_integration = nullptr;
Window::Window(QWindow *window)
: QObject(window)
, d(new WindowPrivate(window))
{
s_map.insert(d->parentWindow, this);
Q_ASSERT(!Window::get(window));
window->winId(); // create platform window
QtWaylandClient::QWaylandWindow *waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
if (waylandWindow) {
if (!s_integration) {
s_integration = new QWaylandLayerShellIntegration();
}
waylandWindow->setShellIntegration(s_integration);
window->setProperty(s_interfaceKey, QVariant::fromValue<QObject *>(this));
}
}
Window *Window::get(QWindow *window)
{
auto layerShellWindow = s_map.value(window);
if (layerShellWindow) {
return layerShellWindow;
}
return new Window(window);
return qobject_cast<Window *>(qvariant_cast<QObject *>(window->property(s_interfaceKey)));
}
QWaylandLayerSurface *WindowPrivate::getSurface() const

View File

@ -21,6 +21,7 @@ class LAYERSHELLQT_EXPORT Window : public QObject
{
Q_OBJECT
public:
explicit Window(QWindow *window);
~Window() override;
enum Anchor {
@ -85,7 +86,6 @@ public:
static Window *get(QWindow *window);
private:
Window(QWindow *window);
QScopedPointer<WindowPrivate> d;
};

View File

@ -1,3 +0,0 @@
{
"Keys": [ "layer-shell" ]
}

View File

@ -1,2 +0,0 @@
SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
SPDX-License-Identifier: CC0-1.0

View File

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

View File

@ -10,6 +10,7 @@
#include <wayland-client.h>
#include <QtWaylandClient/QWaylandClientExtensionTemplate>
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
@ -17,14 +18,11 @@
namespace LayerShellQt
{
class LAYERSHELLQT_EXPORT QWaylandLayerShell : public QtWayland::zwlr_layer_shell_v1
class QWaylandLayerShell : public QWaylandClientExtensionTemplate<QWaylandLayerShell>, public QtWayland::zwlr_layer_shell_v1
{
public:
QWaylandLayerShell(::wl_registry *registry, uint32_t id, uint32_t version);
QWaylandLayerShell();
~QWaylandLayerShell() override;
QWaylandLayerSurface *createLayerSurface(QtWaylandClient::QWaylandWindow *window);
// TODO: Popups
};
}

View File

@ -15,6 +15,7 @@
namespace LayerShellQt
{
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
: m_layerShell(new QWaylandLayerShell())
{
}
@ -22,26 +23,9 @@ QWaylandLayerShellIntegration::~QWaylandLayerShellIntegration()
{
}
bool QWaylandLayerShellIntegration::initialize(QtWaylandClient::QWaylandDisplay *display)
{
QWaylandShellIntegration::initialize(display);
display->addRegistryListener(registryLayer, this);
return m_layerShell != nullptr;
}
QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration::createShellSurface(QtWaylandClient::QWaylandWindow *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)));
return new QWaylandLayerSurface(m_layerShell.data(), window);
}
}
//#include "qwaylandlayershellintegration.moc"

View File

@ -8,8 +8,6 @@
#ifndef _LAYERSHELLINTEGRATION_P_H
#define _LAYERSHELLINTEGRATION_P_H
#include <wayland-client.h>
#include "layershellqt_export.h"
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
@ -23,12 +21,9 @@ public:
QWaylandLayerShellIntegration();
~QWaylandLayerShellIntegration() override;
bool initialize(QtWaylandClient::QWaylandDisplay *display) override;
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

@ -1,33 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
* SPDX-FileCopyrightText: 2018 Drew DeVault <sir@cmpwn.com>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "qwaylandlayershellintegration_p.h"
#include <QtWaylandClient/private/qwaylandshellintegrationplugin_p.h>
using namespace LayerShellQt;
class QWaylandLayerShellIntegrationPlugin : public QtWaylandClient::QWaylandShellIntegrationPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QWaylandShellIntegrationFactoryInterface_iid FILE "layer-shell.json")
public:
QWaylandLayerShellIntegrationPlugin()
{
}
QtWaylandClient::QWaylandShellIntegration *create(const QString &key, const QStringList &paramList) override
{
Q_UNUSED(key);
Q_UNUSED(paramList);
return new QWaylandLayerShellIntegration();
}
};
// Q_IMPORT_PLUGIN(QWaylandLayerShellIntegrationPlugin);
#include "qwaylandlayershellintegrationplugin.moc"

View File

@ -5,9 +5,9 @@
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "interfaces/shell.h"
#include "qwaylandlayershell_p.h"
#include "qwaylandlayersurface_p.h"
#include "interfaces/window.h"
#include "layershellqt_logging.h"
#include <QtWaylandClient/private/qwaylandscreen_p.h>
@ -20,7 +20,7 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandC
: QtWaylandClient::QWaylandShellSurface(window)
, QtWayland::zwlr_layer_surface_v1()
{
LayerShellQt::Window *interface = Window::get(window->window());
Window *interface = Window::get(window->window());
Q_ASSERT(interface);
// Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created

View File

@ -14,7 +14,6 @@
#include <QMetaEnum>
#include <interfaces/shell.h>
#include <interfaces/window.h>
using namespace LayerShellQt;
@ -51,8 +50,6 @@ class BasicWindow : public QRasterWindow
int main(int argc, char **argv)
{
Shell::useLayerShell();
QGuiApplication app(argc, argv);
const auto layerMetaEnum = QMetaEnum::fromType<Window::Layer>();
@ -78,7 +75,7 @@ int main(int argc, char **argv)
BasicWindow window;
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window);
LayerShellQt::Window *layerShell = new LayerShellQt::Window(&window);
if (parser.isSet(marginsOption)) {
int margins = parser.value(marginsOption).toInt();
layerShell->setMargins({margins, margins, margins, margins});
@ -102,6 +99,10 @@ 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();