Compare commits

..

3 Commits

Author SHA1 Message Date
2502a4a6dd hacks 2021-11-26 21:26:19 +02:00
3214fb588f Set dummy project version 2021-11-13 12:32:53 +02:00
8c39cad0ba Bump to Qt6 2021-11-13 12:11:48 +02:00
25 changed files with 174 additions and 792 deletions

View File

@ -2,8 +2,5 @@
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
include: include:
- project: sysadmin/ci-utilities - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
file: - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
- /gitlab-templates/reuse-lint.yml
- /gitlab-templates/linux-qt6.yml
- /gitlab-templates/freebsd-qt6.yml

View File

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

View File

@ -4,43 +4,39 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(layershellqt) project(layershellqt)
set(PROJECT_VERSION "6.0.5") set(PROJECT_VERSION "6.0.0")
set(PROJECT_VERSION_MAJOR 6) set(PROJECT_VERSION_MAJOR 6)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(QT_MIN_VERSION "6.6.0") set(QT_MIN_VERSION "6.2.0")
set(KF6_MIN_VERSION "6.0.0") set(KF5_MIN_VERSION "5.86")
set(KDE_COMPILERSETTINGS_LEVEL "5.82") set(KDE_COMPILERSETTINGS_LEVEL "5.82")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE) find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${ECM_MODULE_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${ECM_MODULE_PATH})
include(KDEInstallDirs) include(KDEInstallDirs)
include(KDECMakeSettings) include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE) include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMSetupVersion) include(ECMSetupVersion)
include(ECMDeprecationSettings)
include(ECMGenerateHeaders) include(ECMGenerateHeaders)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(FeatureSummary) include(FeatureSummary)
include(GenerateExportHeader) include(GenerateExportHeader)
include(KDEClangFormat) include(KDEClangFormat)
include(ECMQtDeclareLoggingCategory) include(ECMQtDeclareLoggingCategory)
include(ECMQmlModule)
find_package(WaylandScanner)
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml) find_package(QtWaylandScanner)
find_package(WaylandScanner REQUIRED)
find_package(Wayland 1.3 COMPONENTS Client Server) find_package(Wayland 1.3 COMPONENTS Client Server)
find_package(WaylandProtocols REQUIRED) find_package(WaylandProtocols)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(XKBCOMMON xkbcommon REQUIRED IMPORTED_TARGET)
set_package_properties(Wayland PROPERTIES set_package_properties(Wayland PROPERTIES
TYPE REQUIRED) TYPE REQUIRED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
@ -48,19 +44,14 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX LAYERSHELLQT ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX LAYERSHELLQT
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/layershellqt_version.h" VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/layershellqt_version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/LayerShellQtConfigVersion.cmake" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/LayerShellQtConfigVersion.cmake"
SOVERSION ${PROJECT_VERSION_MAJOR}) SOVERSION 5)
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
ecm_set_disabled_deprecation_versions(QT 6.5
KF 5.240
)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(tests) add_subdirectory(tests)
set(CMAKECONFIG_INSTALL_DIR ${KDE_INSTALL_CMAKEPACKAGEDIR}/LayerShellQt) set(CMAKECONFIG_INSTALL_DIR ${KDE_INSTALL_LIBDIR}/cmake/LayerShellQt)
install(EXPORT LayerShellQtTargets install(EXPORT LayerShellQtTargets
NAMESPACE LayerShellQt:: NAMESPACE LayerShellQt::
DESTINATION ${CMAKECONFIG_INSTALL_DIR} DESTINATION ${CMAKECONFIG_INSTALL_DIR}

View File

@ -1,17 +0,0 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
maintainer:
- vladz
description: Layer Shell Qt
platforms:
- name: Linux
- name: FreeBSD
portingAid: false
deprecated: false
release: true
group: Plasma
public_lib: true
public_source_dirs:
- src/interfaces

View File

@ -3,14 +3,10 @@
remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS) remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
add_library(LayerShellQtInterface) ecm_add_qtwayland_client_protocol(LAYER_SHELL_SOURCES PROTOCOL ${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml BASENAME xdg-shell)
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES ecm_add_qtwayland_client_protocol(LAYER_SHELL_SOURCES PROTOCOL wlr-layer-shell-unstable-v1.xml BASENAME wlr-layer-shell-unstable-v1)
${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
)
ecm_qt_declare_logging_category(LayerShellQtInterface ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
HEADER HEADER
layershellqt_logging.h layershellqt_logging.h
IDENTIFIER IDENTIFIER
@ -19,19 +15,8 @@ ecm_qt_declare_logging_category(LayerShellQtInterface
layershellqt layershellqt
) )
target_sources(LayerShellQtInterface PRIVATE add_library(LayerShellQtInterface SHARED qwaylandlayersurface.cpp interfaces/window.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
qwaylandxdgactivationv1.cpp target_link_libraries(LayerShellQtInterface PRIVATE Qt::Gui Qt::WaylandClientPrivate Wayland::Client)
qwaylandlayersurface.cpp
qwaylandlayershellintegration.cpp
interfaces/window.cpp
interfaces/shell.cpp
)
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()
target_include_directories(LayerShellQtInterface PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt>" target_include_directories(LayerShellQtInterface PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt>"
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/>" INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/>"
) )
@ -41,30 +26,19 @@ set_target_properties(LayerShellQtInterface PROPERTIES VERSION ${LAYERSHELLQT_
EXPORT_NAME Interface EXPORT_NAME Interface
) )
add_library(layer-shell SHARED qwaylandlayershellintegrationplugin.cpp)
target_link_libraries(layer-shell LayerShellQtInterface Qt::WaylandClient Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
if (TARGET Qt::XkbCommonSupportPrivate)
target_link_libraries(layer-shell Qt::XkbCommonSupportPrivate)
endif()
ecm_generate_headers(LayerShellQt_HEADERS ecm_generate_headers(LayerShellQt_HEADERS
HEADER_NAMES HEADER_NAMES
Shell
Window Window
RELATIVE interfaces/ RELATIVE interfaces/
REQUIRED_HEADERS LayerShellQt_HEADERS REQUIRED_HEADERS LayerShellQt_HEADERS
) )
generate_export_header(LayerShellQtInterface generate_export_header(LayerShellQtInterface
BASE_NAME LayerShellQtInterface BASE_NAME LayerShellQtInterface
EXPORT_MACRO_NAME LAYERSHELLQT_EXPORT EXPORT_MACRO_NAME LAYERSHELLQT_EXPORT
EXPORT_FILE_NAME LayerShellQt/layershellqt_export.h EXPORT_FILE_NAME LayerShellQt/layershellqt_export.h
) )
install(TARGETS layer-shell
LIBRARY DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/wayland-shell-integration)
install(TARGETS LayerShellQtInterface EXPORT LayerShellQtTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS LayerShellQtInterface EXPORT LayerShellQtTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES install(FILES
@ -72,5 +46,3 @@ install(FILES
${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt/layershellqt_export.h ${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt/layershellqt_export.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/LayerShellQt COMPONENT Devel DESTINATION ${KDE_INSTALL_INCLUDEDIR}/LayerShellQt COMPONENT Devel
) )
add_subdirectory(declarative)

View File

@ -1,10 +0,0 @@
# 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"
VERSION 1.0
SOURCES layershellqtplugin.cpp)
target_link_libraries(LayerShellQtQml PRIVATE Qt::Qml LayerShellQtInterface)
ecm_finalize_qml_module(LayerShellQtQml DESTINATION ${KDE_INSTALL_QMLDIR})

View File

@ -1,24 +0,0 @@
/*
* 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

@ -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

@ -5,17 +5,16 @@
*/ */
#include "window.h" #include "window.h"
#include "../qwaylandlayersurface_p.h"
#include "../qwaylandlayershellintegration_p.h" #include "../qwaylandlayershellintegration_p.h"
#include <layershellqt_logging.h> #include <layershellqt_logging.h>
#include <private/qwaylandshellsurface_p.h>
#include <QPointer> #include <private/qwaylandwindow_p.h>
#include <optional>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
using namespace LayerShellQt; using namespace LayerShellQt;
static const char *s_interfaceKey = "__kde_layer_window";
class LayerShellQt::WindowPrivate class LayerShellQt::WindowPrivate
{ {
public: public:
@ -28,26 +27,22 @@ public:
QString scope = QStringLiteral("window"); QString scope = QStringLiteral("window");
Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight}; Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
int32_t exclusionZone = 0; int32_t exclusionZone = 0;
Window::Anchor exclusiveEdge = Window::AnchorNone; Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityExclusive;
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
Window::Layer layer = Window::LayerTop; Window::Layer layer = Window::LayerTop;
QMargins margins; QMargins margins;
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; QWaylandLayerSurface *getSurface() const;
bool closeOnDismissed = true;
}; };
static QMap<QWindow *, Window *> s_map;
Window::~Window() Window::~Window()
{ {
s_map.remove(d->parentWindow); d->parentWindow->setProperty(s_interfaceKey, QVariant());
} }
void Window::setAnchors(Anchors anchors) void Window::setAnchors(Anchors anchors)
{ {
if (d->anchors != anchors) { d->anchors = anchors;
d->anchors = anchors; if (auto surface = d->getSurface()) {
Q_EMIT anchorsChanged(); surface->setAnchor(anchors);
} }
} }
@ -58,9 +53,9 @@ Window::Anchors Window::anchors() const
void Window::setExclusiveZone(int32_t zone) void Window::setExclusiveZone(int32_t zone)
{ {
if (d->exclusionZone != zone) { d->exclusionZone = zone;
d->exclusionZone = zone; if (auto surface = d->getSurface()) {
Q_EMIT exclusionZoneChanged(); surface->setExclusiveZone(zone);
} }
} }
@ -69,26 +64,11 @@ int32_t Window::exclusionZone() const
return d->exclusionZone; return d->exclusionZone;
} }
void Window::setExclusiveEdge(Window::Anchor edge)
{
if (d->exclusiveEdge == edge) {
return;
}
d->exclusiveEdge = edge;
Q_EMIT exclusiveEdgeChanged();
}
Window::Anchor Window::exclusiveEdge() const
{
return d->exclusiveEdge;
}
void Window::setMargins(const QMargins &margins) void Window::setMargins(const QMargins &margins)
{ {
if (d->margins != margins) { d->margins = margins;
d->margins = margins; if (auto surface = d->getSurface()) {
Q_EMIT marginsChanged(); surface->setMargins(margins);
} }
} }
@ -99,9 +79,9 @@ QMargins Window::margins() const
void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity) void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity)
{ {
if (d->keyboardInteractivity != interactivity) { d->keyboardInteractivity = interactivity;
d->keyboardInteractivity = interactivity; if (auto surface = d->getSurface()) {
Q_EMIT keyboardInteractivityChanged(); surface->setKeyboardInteractivity(interactivity);
} }
} }
@ -112,9 +92,9 @@ Window::KeyboardInteractivity Window::keyboardInteractivity() const
void Window::setLayer(Layer layer) void Window::setLayer(Layer layer)
{ {
if (d->layer != layer) { d->layer = layer;
d->layer = layer; if (auto surface = d->getSurface()) {
Q_EMIT layerChanged(); surface->setLayer(layer);
} }
} }
@ -134,68 +114,44 @@ Window::Layer Window::layer() const
return d->layer; return d->layer;
} }
Window::ScreenConfiguration Window::screenConfiguration() const static QWaylandLayerShellIntegration *s_integration = nullptr;
{
return d->screenConfiguration;
}
void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration)
{
d->screenConfiguration = screenConfiguration;
}
bool Window::closeOnDismissed() const
{
return d->closeOnDismissed;
}
void Window::setCloseOnDismissed(bool close)
{
d->closeOnDismissed = close;
}
Window::Window(QWindow *window) Window::Window(QWindow *window)
: QObject(window) : QObject(window)
, d(new WindowPrivate(window)) , d(new WindowPrivate(window))
{ {
s_map.insert(d->parentWindow, this); Q_ASSERT(!Window::get(window));
window->winId(); // create platform window
window->create(); QtWaylandClient::QWaylandWindow *waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
if (waylandWindow) {
auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle()); if (!s_integration) {
if (!waylandWindow) { s_integration = new QWaylandLayerShellIntegration();
qCWarning(LAYERSHELLQT) << window << "is not a wayland window. Not creating zwlr_layer_surface";
return;
}
static QWaylandLayerShellIntegration *shellIntegration = nullptr;
if (!shellIntegration) {
shellIntegration = new QWaylandLayerShellIntegration();
if (!shellIntegration->initialize(waylandWindow->display())) {
delete shellIntegration;
shellIntegration = nullptr;
qCWarning(LAYERSHELLQT) << "Failed to initialize layer-shell integration, possibly because compositor does not support the layer-shell protocol";
return;
} }
waylandWindow->setShellIntegration(s_integration);
window->setProperty(s_interfaceKey, QVariant::fromValue<QObject *>(this));
} }
waylandWindow->setShellIntegration(shellIntegration);
} }
Window *Window::get(QWindow *window) Window *Window::get(QWindow *window)
{ {
if (!window) { return qobject_cast<Window *>(qvariant_cast<QObject *>(window->property(s_interfaceKey)));
}
QWaylandLayerSurface *WindowPrivate::getSurface() const
{
if (!parentWindow) {
return nullptr; return nullptr;
} }
auto ww = dynamic_cast<QtWaylandClient::QWaylandWindow *>(parentWindow->handle());
auto layerShellWindow = s_map.value(window); if (!ww) {
if (layerShellWindow) { qCDebug(LAYERSHELLQT) << "window not a wayland window" << parentWindow;
return layerShellWindow; return nullptr;
} }
return new Window(window); QWaylandLayerSurface *s = qobject_cast<QWaylandLayerSurface *>(ww->shellSurface());
} if (!s) {
qCDebug(LAYERSHELLQT) << "window not using wlr-layer-shell" << parentWindow << ww->shellSurface();
Window *Window::qmlAttachedProperties(QObject *object) return nullptr;
{ }
return get(qobject_cast<QWindow *>(object)); return s;
} }

View File

@ -9,7 +9,6 @@
#define LAYERSHELLQTWINDOW_H #define LAYERSHELLQTWINDOW_H
#include <QObject> #include <QObject>
#include <QScreen>
#include <QWindow> #include <QWindow>
#include "layershellqt_export.h" #include "layershellqt_export.h"
@ -21,23 +20,15 @@ class WindowPrivate;
class LAYERSHELLQT_EXPORT Window : public QObject class LAYERSHELLQT_EXPORT Window : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(Anchors anchors READ anchors WRITE setAnchors 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)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
public: public:
explicit Window(QWindow *window);
~Window() override; ~Window() override;
enum Anchor { enum Anchor {
AnchorNone = 0, AnchorTop = 1, // the top edge of the anchor rectangle
AnchorTop = 1, ///< The top edge of the anchor rectangle AnchorBottom = 2, // the bottom edge of the anchor rectangle
AnchorBottom = 2, ///< The bottom edge of the anchor rectangle AnchorLeft = 4, // the left edge of the anchor rectangle
AnchorLeft = 4, ///< The left edge of the anchor rectangle AnchorRight = 8, // the right edge of the anchor rectangle
AnchorRight = 8, ///< The right edge of the anchor rectangle
}; };
Q_ENUM(Anchor); Q_ENUM(Anchor);
Q_DECLARE_FLAGS(Anchors, Anchor) Q_DECLARE_FLAGS(Anchors, Anchor)
@ -63,26 +54,12 @@ public:
}; };
Q_ENUM(KeyboardInteractivity) 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); void setAnchors(Anchors anchor);
Anchors anchors() const; Anchors anchors() const;
void setExclusiveZone(int32_t zone); void setExclusiveZone(int32_t zone);
int32_t exclusionZone() const; int32_t exclusionZone() const;
void setExclusiveEdge(Window::Anchor edge);
Window::Anchor exclusiveEdge() const;
void setMargins(const QMargins &margins); void setMargins(const QMargins &margins);
QMargins margins() const; QMargins margins() const;
@ -92,9 +69,6 @@ public:
void setLayer(Layer layer); void setLayer(Layer layer);
Layer layer() const; Layer layer() const;
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
ScreenConfiguration screenConfiguration() const;
/** /**
* Sets a string based identifier for this window. * Sets a string based identifier for this window.
* This may be used by a compositor to determine stacking * This may be used by a compositor to determine stacking
@ -105,33 +79,13 @@ public:
void setScope(const QString &scope); void setScope(const QString &scope);
QString scope() const; QString scope() const;
/**
* Whether the QWindow should be closed when the layer surface is dismissed by the compositor.
* For example, if the associated screen has been removed.
*
* This can be used to map the window on another screen.
*/
void setCloseOnDismissed(bool close);
bool closeOnDismissed() const;
/** /**
* Gets the LayerShell Window for a given Qt Window * Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred * Ownership is not transferred
*/ */
static Window *get(QWindow *window); static Window *get(QWindow *window);
static Window *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
void anchorsChanged();
void exclusionZoneChanged();
void exclusiveEdgeChanged();
void marginsChanged();
void keyboardInteractivityChanged();
void layerChanged();
private: private:
Window(QWindow *window);
QScopedPointer<WindowPrivate> d; 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

@ -0,0 +1,26 @@
/*
* 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 "qwaylandlayershell_p.h"
#include "qwaylandlayersurface_p.h"
namespace LayerShellQt
{
QWaylandLayerShell::QWaylandLayerShell()
: QWaylandClientExtensionTemplate<QWaylandLayerShell>(2)
, QtWayland::zwlr_layer_shell_v1()
{
initialize();
}
QWaylandLayerShell::~QWaylandLayerShell()
{
if (zwlr_layer_shell_v1_get_version(object()) >= ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION)
zwlr_layer_shell_v1_destroy(object());
}
}

View File

@ -0,0 +1,30 @@
/*
* 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
*/
#ifndef _LAYERSHELL_H
#define _LAYERSHELL_H
#include <wayland-client.h>
#include <QtWaylandClient/QWaylandClientExtensionTemplate>
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
#include "qwaylandlayersurface_p.h"
namespace LayerShellQt
{
class QWaylandLayerShell : public QWaylandClientExtensionTemplate<QWaylandLayerShell>, public QtWayland::zwlr_layer_shell_v1
{
public:
QWaylandLayerShell();
~QWaylandLayerShell() override;
};
}
#endif

View File

@ -5,32 +5,27 @@
* SPDX-License-Identifier: LGPL-3.0-or-later * SPDX-License-Identifier: LGPL-3.0-or-later
*/ */
#include "qwaylandlayershell_p.h"
#include "qwaylandlayershellintegration_p.h" #include "qwaylandlayershellintegration_p.h"
#include "qwaylandlayersurface_p.h"
#include "qwaylandxdgactivationv1_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylandwindow_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
namespace LayerShellQt namespace LayerShellQt
{ {
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration() QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
: QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>(5) : m_layerShell(new QWaylandLayerShell())
, m_xdgActivation(new QWaylandXdgActivationV1)
{ {
} }
QWaylandLayerShellIntegration::~QWaylandLayerShellIntegration() QWaylandLayerShellIntegration::~QWaylandLayerShellIntegration()
{ {
if (object() && zwlr_layer_shell_v1_get_version(object()) >= ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION) {
zwlr_layer_shell_v1_destroy(object());
}
} }
QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration::createShellSurface(QtWaylandClient::QWaylandWindow *window) QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration::createShellSurface(QtWaylandClient::QWaylandWindow *window)
{ {
return new QWaylandLayerSurface(this, window); return new QWaylandLayerSurface(m_layerShell.data(), window);
} }
} }

View File

@ -9,25 +9,22 @@
#define _LAYERSHELLINTEGRATION_P_H #define _LAYERSHELLINTEGRATION_P_H
#include "layershellqt_export.h" #include "layershellqt_export.h"
#include <QtWaylandClient/private/qwaylandshellintegration_p.h> #include <QtWaylandClient/private/qwaylandshellintegration_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
class QWaylandXdgActivationV1;
namespace LayerShellQt namespace LayerShellQt
{ {
class QWaylandLayerShell;
class LAYERSHELLQT_EXPORT QWaylandLayerShellIntegration : public QtWaylandClient::QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>, public QtWayland::zwlr_layer_shell_v1 class LAYERSHELLQT_EXPORT QWaylandLayerShellIntegration : public QtWaylandClient::QWaylandShellIntegration
{ {
public: public:
QWaylandLayerShellIntegration(); QWaylandLayerShellIntegration();
~QWaylandLayerShellIntegration() override; ~QWaylandLayerShellIntegration() override;
QWaylandXdgActivationV1 *activation() const { return m_xdgActivation.data(); }
QtWaylandClient::QWaylandShellSurface *createShellSurface(QtWaylandClient::QWaylandWindow *window) override; QtWaylandClient::QWaylandShellSurface *createShellSurface(QtWaylandClient::QWaylandWindow *window) override;
private: private:
QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation; 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,83 +5,60 @@
* SPDX-License-Identifier: LGPL-3.0-or-later * SPDX-License-Identifier: LGPL-3.0-or-later
*/ */
#include "qwaylandlayershell_p.h"
#include "qwaylandlayersurface_p.h"
#include "interfaces/window.h" #include "interfaces/window.h"
#include "layershellqt_logging.h" #include "layershellqt_logging.h"
#include "qwaylandlayersurface_p.h"
#include "qwaylandxdgactivationv1_p.h"
#include <QtWaylandClient/private/qwaylandscreen_p.h> #include <QtWaylandClient/private/qwaylandscreen_p.h>
#include <QtWaylandClient/private/qwaylandsurface_p.h> #include <QtWaylandClient/private/qwaylandsurface_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylandwindow_p.h>
#include <QGuiApplication>
namespace LayerShellQt namespace LayerShellQt
{ {
QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell, QtWaylandClient::QWaylandWindow *window) QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window)
: QtWaylandClient::QWaylandShellSurface(window) : QtWaylandClient::QWaylandShellSurface(window)
, QtWayland::zwlr_layer_surface_v1() , QtWayland::zwlr_layer_surface_v1()
, m_shell(shell)
, m_interface(Window::get(window->window()))
, m_window(window)
{ {
wl_output *output = nullptr; Window *interface = Window::get(window->window());
if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) { Q_ASSERT(interface);
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 // 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 // this will not cast to a QWaylandScreen
if (!waylandScreen) { QtWaylandClient::QWaylandScreen *screen = window->waylandScreen();
qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly"; if (screen->isPlaceholder()) {
} else { qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly";
output = waylandScreen->output();
}
} }
init(shell->get_layer_surface(window->waylandSurface()->object(), output, m_interface->layer(), m_interface->scope()));
connect(m_interface, &Window::layerChanged, this, [this]() {
setLayer(m_interface->layer());
});
setAnchor(m_interface->anchors()); init(shell->get_layer_surface(window->waylandSurface()->object(), screen->isPlaceholder() ? nullptr : screen->output(), interface->layer(), interface->scope()));
connect(m_interface, &Window::anchorsChanged, this, [this]() {
setAnchor(m_interface->anchors());
setDesiredSize(m_window->windowContentGeometry().size());
});
setExclusiveZone(m_interface->exclusionZone()); Window::Anchors anchors = interface->anchors();
connect(m_interface, &Window::exclusionZoneChanged, this, [this]() {
setExclusiveZone(m_interface->exclusionZone());
});
setExclusiveEdge(m_interface->exclusiveEdge());
connect(m_interface, &Window::exclusiveEdgeChanged, this, [this]() {
setExclusiveEdge(m_interface->exclusiveEdge());
});
setMargins(m_interface->margins()); set_anchor(interface->anchors());
connect(m_interface, &Window::marginsChanged, this, [this]() { setMargins(interface->margins());
setMargins(m_interface->margins()); setKeyboardInteractivity(interface->keyboardInteractivity());
}); setExclusiveZone(interface->exclusionZone());
setKeyboardInteractivity(m_interface->keyboardInteractivity()); QSize size = window->surfaceSize();
connect(m_interface, &Window::keyboardInteractivityChanged, this, [this]() { if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) {
setKeyboardInteractivity(m_interface->keyboardInteractivity()); size.setWidth(0);
}); }
if ((anchors & Window::AnchorTop) && (anchors & Window::AnchorBottom)) {
setDesiredSize(window->windowContentGeometry().size()); size.setHeight(0);
}
if (size.isValid() && size != QSize(0, 0)) {
set_size(size.width(), size.height());
}
} }
QWaylandLayerSurface::~QWaylandLayerSurface() QWaylandLayerSurface::~QWaylandLayerSurface()
{ {
if (m_waitForSyncCallback) {
wl_callback_destroy(m_waitForSyncCallback);
}
destroy(); destroy();
} }
void QWaylandLayerSurface::zwlr_layer_surface_v1_closed() void QWaylandLayerSurface::zwlr_layer_surface_v1_closed()
{ {
if (m_interface->closeOnDismissed()) { window()->window()->close();
window()->window()->close();
}
} }
void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height)
@ -91,8 +68,8 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint
if (!m_configured) { if (!m_configured) {
m_configured = true; m_configured = true;
applyConfigure(); window()->resizeFromApplyConfigure(m_pendingSize);
sendExpose(); window()->handleExpose(QRect(QPoint(), m_pendingSize));
} else { } else {
// Later configures are resizes, so we have to queue them up for a time when we // Later configures are resizes, so we have to queue them up for a time when we
// are not painting to the window. // are not painting to the window.
@ -100,37 +77,9 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint
} }
} }
void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *popup)
{
std::any anyRole = popup->surfaceRole();
if (auto role = std::any_cast<::xdg_popup *>(&anyRole)) {
get_popup(*role);
} else {
qCWarning(LAYERSHELLQT) << "Cannot attach popup of unknown type";
}
}
void QWaylandLayerSurface::applyConfigure() void QWaylandLayerSurface::applyConfigure()
{ {
m_configuring = true;
window()->resizeFromApplyConfigure(m_pendingSize); window()->resizeFromApplyConfigure(m_pendingSize);
m_configuring = false;
}
void QWaylandLayerSurface::setDesiredSize(const QSize &size)
{
const bool horizontallyConstrained = m_interface->anchors().testFlags({Window::AnchorLeft, Window::AnchorRight});
const bool verticallyConstrained = m_interface->anchors().testFlags({Window::AnchorTop, Window::AnchorBottom});
QSize effectiveSize = size;
if (horizontallyConstrained) {
effectiveSize.setWidth(0);
}
if (verticallyConstrained) {
effectiveSize.setHeight(0);
}
set_size(effectiveSize.width(), effectiveSize.height());
} }
void QWaylandLayerSurface::setAnchor(uint anchor) void QWaylandLayerSurface::setAnchor(uint anchor)
@ -143,13 +92,6 @@ void QWaylandLayerSurface::setExclusiveZone(int32_t zone)
set_exclusive_zone(zone); set_exclusive_zone(zone);
} }
void QWaylandLayerSurface::setExclusiveEdge(uint32_t edge)
{
if (zwlr_layer_surface_v1_get_version(object()) >= ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_EDGE_SINCE_VERSION) {
set_exclusive_edge(edge);
}
}
void QWaylandLayerSurface::setMargins(const QMargins &margins) void QWaylandLayerSurface::setMargins(const QMargins &margins)
{ {
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left()); set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
@ -166,100 +108,4 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
set_layer(layer); set_layer(layer);
} }
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
{
if (m_configuring) {
return;
}
setDesiredSize(geometry.size());
requestWaylandSync();
} }
bool QWaylandLayerSurface::requestActivate()
{
QWaylandXdgActivationV1 *activation = m_shell->activation();
if (!activation->isActive()) {
return false;
}
if (!m_activationToken.isEmpty()) {
activation->activate(m_activationToken, window()->wlSurface());
m_activationToken = {};
return true;
} else {
const auto focusWindow = QGuiApplication::focusWindow();
const auto wlWindow = focusWindow ? static_cast<QtWaylandClient::QWaylandWindow*>(focusWindow->handle()) : window();
if (const auto seat = wlWindow->display()->lastInputDevice()) {
const auto tokenProvider = activation->requestXdgActivationToken(
wlWindow->display(), wlWindow->wlSurface(), 0, QString());
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, this,
[this](const QString &token) {
m_shell->activation()->activate(token, window()->wlSurface());
});
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, tokenProvider, &QObject::deleteLater);
return true;
}
}
return false;
}
void QWaylandLayerSurface::setXdgActivationToken(const QString &token)
{
m_activationToken = token;
}
void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
{
QWaylandXdgActivationV1 *activation = m_shell->activation();
if (!activation->isActive()) {
return;
}
auto tokenProvider = activation->requestXdgActivationToken(
window()->display(), window()->wlSurface(), serial, QString());
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, this,
[this](const QString &token) {
Q_EMIT window()->xdgActivationTokenCreated(token);
});
connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, tokenProvider, &QObject::deleteLater);
}
const wl_callback_listener QWaylandLayerSurface::syncCallbackListener = {
.done = [](void *data, struct wl_callback *callback, uint32_t time){
Q_UNUSED(time);
wl_callback_destroy(callback);
QWaylandLayerSurface *layerSurface = static_cast<QWaylandLayerSurface *>(data);
layerSurface->m_waitForSyncCallback = nullptr;
layerSurface->sendExpose();
}
};
void QWaylandLayerSurface::requestWaylandSync()
{
if (m_waitForSyncCallback) {
return;
}
m_waitForSyncCallback = wl_display_sync(m_window->display()->wl_display());
wl_callback_add_listener(m_waitForSyncCallback, &syncCallbackListener, this);
}
void QWaylandLayerSurface::handleWaylandSyncDone()
{
if (!window()->isExposed()) {
return;
}
sendExpose();
}
void QWaylandLayerSurface::sendExpose()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
window()->handleExpose(QRect(QPoint(), m_pendingSize));
#else
window()->sendRecursiveExposeEvent();
#endif
}
}

View File

@ -10,63 +10,40 @@
#include <wayland-client.h> #include <wayland-client.h>
#include "qwaylandlayershellintegration_p.h"
#include "layershellqt_export.h" #include "layershellqt_export.h"
#include <QtWaylandClient/private/qwaylandshellsurface_p.h> #include <QtWaylandClient/private/qwaylandshellsurface_p.h>
#include <qwayland-wlr-layer-shell-unstable-v1.h> #include <qwayland-wlr-layer-shell-unstable-v1.h>
namespace LayerShellQt namespace LayerShellQt
{ {
class QWaylandLayerShell;
class Window;
class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1 class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1
{ {
Q_OBJECT Q_OBJECT
public: public:
QWaylandLayerSurface(QWaylandLayerShellIntegration *shell, QtWaylandClient::QWaylandWindow *window); QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window);
~QWaylandLayerSurface() override; ~QWaylandLayerSurface() override;
bool isExposed() const override bool isExposed() const override
{ {
return m_configured && !m_waitForSyncCallback; return m_configured;
} }
void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override;
void setDesiredSize(const QSize &size);
void setAnchor(uint32_t anchor); void setAnchor(uint32_t anchor);
void setExclusiveZone(int32_t zone); void setExclusiveZone(int32_t zone);
void setExclusiveEdge(uint32_t edge);
void setMargins(const QMargins &margins); void setMargins(const QMargins &margins);
void setKeyboardInteractivity(uint32_t interactivity); void setKeyboardInteractivity(uint32_t interactivity);
void setLayer(uint32_t layer); void setLayer(uint32_t layer);
void applyConfigure() override; void applyConfigure() override;
void setWindowGeometry(const QRect &geometry) override;
bool requestActivate() override;
void setXdgActivationToken(const QString &token) override;
void requestXdgActivationToken(quint32 serial) override;
private: private:
void requestWaylandSync();
void handleWaylandSyncDone();
void sendExpose();
void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override; void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override;
void zwlr_layer_surface_v1_closed() override; void zwlr_layer_surface_v1_closed() override;
QWaylandLayerShellIntegration *m_shell;
LayerShellQt::Window *m_interface;
QtWaylandClient::QWaylandWindow *m_window;
QSize m_pendingSize; QSize m_pendingSize;
QString m_activationToken;
bool m_configured = false; bool m_configured = false;
bool m_configuring = false;
static const wl_callback_listener syncCallbackListener;
struct wl_callback *m_waitForSyncCallback = nullptr;
}; };
} }

View File

@ -1,44 +0,0 @@
/** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "qwaylandxdgactivationv1_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandinputdevice_p.h>
QWaylandXdgActivationV1::QWaylandXdgActivationV1()
: QWaylandClientExtensionTemplate<QWaylandXdgActivationV1>(1)
{
initialize();
}
QWaylandXdgActivationV1::~QWaylandXdgActivationV1()
{
if (isActive()) {
destroy();
}
}
QWaylandXdgActivationTokenV1 *QWaylandXdgActivationV1::requestXdgActivationToken(QtWaylandClient::QWaylandDisplay *display,
struct ::wl_surface *surface,
std::optional<uint32_t> serial,
const QString &app_id)
{
auto wl = get_activation_token();
auto provider = new QWaylandXdgActivationTokenV1;
provider->init(wl);
if (surface) {
provider->set_surface(surface);
}
if (!app_id.isEmpty()) {
provider->set_app_id(app_id);
}
if (serial && display->lastInputDevice()) {
provider->set_serial(*serial, display->lastInputDevice()->wl_seat());
}
provider->commit();
return provider;
}
#include "moc_qwaylandxdgactivationv1_p.cpp"

View File

@ -1,48 +0,0 @@
/** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef QWAYLANDXDGACTIVATIONV1_P_H
#define QWAYLANDXDGACTIVATIONV1_P_H
#include "qwayland-xdg-activation-v1.h"
#include <QObject>
#include <QtWaylandClient/QWaylandClientExtension>
namespace QtWaylandClient
{
class QWaylandDisplay;
class QWaylandSurface;
}
class QWaylandXdgActivationTokenV1 : public QObject, public QtWayland::xdg_activation_token_v1
{
Q_OBJECT
public:
~QWaylandXdgActivationTokenV1() override
{
destroy();
}
protected:
void xdg_activation_token_v1_done(const QString &token) override
{
Q_EMIT done(token);
}
Q_SIGNALS:
void done(const QString &token);
};
class QWaylandXdgActivationV1 : public QWaylandClientExtensionTemplate<QWaylandXdgActivationV1>, public QtWayland::xdg_activation_v1
{
public:
QWaylandXdgActivationV1();
~QWaylandXdgActivationV1() override;
QWaylandXdgActivationTokenV1 *
requestXdgActivationToken(QtWaylandClient::QWaylandDisplay *display, struct ::wl_surface *surface, std::optional<uint32_t> serial, const QString &app_id);
};
#endif // QWAYLANDXDGACTIVATIONV1_P_H

View File

@ -25,7 +25,7 @@
THIS SOFTWARE. THIS SOFTWARE.
</copyright> </copyright>
<interface name="zwlr_layer_shell_v1" version="5"> <interface name="zwlr_layer_shell_v1" version="4">
<description summary="create surfaces that are layers of the desktop"> <description summary="create surfaces that are layers of the desktop">
Clients can use this interface to assign the surface_layer role to Clients can use this interface to assign the surface_layer role to
wl_surfaces. Such surfaces are assigned to a "layer" of the output and wl_surfaces. Such surfaces are assigned to a "layer" of the output and
@ -100,7 +100,7 @@
</request> </request>
</interface> </interface>
<interface name="zwlr_layer_surface_v1" version="5"> <interface name="zwlr_layer_surface_v1" version="4">
<description summary="layer metadata interface"> <description summary="layer metadata interface">
An interface that may be implemented by a wl_surface, for surfaces that An interface that may be implemented by a wl_surface, for surfaces that
are designed to be rendered as a layer of a stacked desktop-like are designed to be rendered as a layer of a stacked desktop-like
@ -367,7 +367,6 @@
<entry name="invalid_size" value="1" summary="size is invalid"/> <entry name="invalid_size" value="1" summary="size is invalid"/>
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
<entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/> <entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
<entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/>
</enum> </enum>
<enum name="anchor" bitfield="true"> <enum name="anchor" bitfield="true">
@ -387,21 +386,5 @@
</description> </description>
<arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/> <arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
</request> </request>
<!-- Version 5 additions -->
<request name="set_exclusive_edge" since="5">
<description summary="set the edge the exclusive zone will be applied to">
Requests an edge for the exclusive zone to apply. The exclusive
edge will be automatically deduced from anchor points when possible,
but when the surface is anchored to a corner, it will be necessary
to set it explicitly to disambiguate, as it is not possible to deduce
which one of the two corner edges should be used.
The edge must be one the surface is anchored to, otherwise the
invalid_exclusive_edge protocol error will be raised.
</description>
<arg name="edge" type="uint"/>
</request>
</interface> </interface>
</protocol> </protocol>

View File

@ -32,7 +32,7 @@ template<typename T>
T stringToEnum(QMetaEnum metaEnum, const QString &str) T stringToEnum(QMetaEnum metaEnum, const QString &str)
{ {
T ret = {}; T ret = {};
const auto splitted = str.split(QLatin1Char('|'), Qt::SkipEmptyParts); const auto splitted = str.split(QLatin1Char('|'));
for (const auto &value : splitted) { for (const auto &value : splitted) {
ret |= T(metaEnum.keyToValue(qPrintable(value))); ret |= T(metaEnum.keyToValue(qPrintable(value)));
} }
@ -41,7 +41,7 @@ T stringToEnum(QMetaEnum metaEnum, const QString &str)
class BasicWindow : public QRasterWindow class BasicWindow : public QRasterWindow
{ {
void paintEvent(QPaintEvent *) override void paintEvent(QPaintEvent *)
{ {
QPainter p(this); QPainter p(this);
p.fillRect(QRect(0, 0, width(), height()), Qt::red); p.fillRect(QRect(0, 0, width(), height()), Qt::red);
@ -75,9 +75,7 @@ int main(int argc, char **argv)
BasicWindow window; BasicWindow window;
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window); LayerShellQt::Window *layerShell = new LayerShellQt::Window(&window);
layerShell->setLayer(Window::LayerBottom);
if (parser.isSet(marginsOption)) { if (parser.isSet(marginsOption)) {
int margins = parser.value(marginsOption).toInt(); int margins = parser.value(marginsOption).toInt();
layerShell->setMargins({margins, margins, margins, margins}); layerShell->setMargins({margins, margins, margins, margins});

View File

@ -1,110 +0,0 @@
/*
* 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 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
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
}
}