mirror of
https://invent.kde.org/plasma/layer-shell-qt.git
synced 2025-07-14 11:04:20 -04:00
Compare commits
18 Commits
work/d_ed/
...
work/qdoc-
Author | SHA1 | Date | |
---|---|---|---|
33b30114a4 | |||
2dbd1d6eb7 | |||
0d11058c8f | |||
a5fbaa5975 | |||
6f8a3f5d42 | |||
303f68cf10 | |||
368cf2dd37 | |||
16a1debdca | |||
c4987c01c7 | |||
bfdf40b1b5 | |||
8676cf98ce | |||
16da49d3a9 | |||
97d85c8722 | |||
44e011e2c6 | |||
05de6c67b2 | |||
7c4706c415 | |||
80a047c0db | |||
2ac46d8d9d |
@ -7,3 +7,6 @@ Dependencies:
|
||||
'frameworks/extra-cmake-modules': '@latest-kf6'
|
||||
'third-party/wayland': '@latest'
|
||||
'third-party/wayland-protocols': '@latest'
|
||||
|
||||
Options:
|
||||
require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
|
||||
|
@ -4,13 +4,13 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(layershellqt)
|
||||
set(PROJECT_VERSION "6.0.80")
|
||||
set(PROJECT_VERSION "6.1.90")
|
||||
set(PROJECT_VERSION_MAJOR 6)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
set(QT_MIN_VERSION "6.6.0")
|
||||
set(KF6_MIN_VERSION "6.0.0")
|
||||
set(QT_MIN_VERSION "6.7.0")
|
||||
set(KF6_MIN_VERSION "6.5.0")
|
||||
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
@ -31,7 +31,8 @@ include(GenerateExportHeader)
|
||||
include(KDEClangFormat)
|
||||
include(ECMQtDeclareLoggingCategory)
|
||||
include(ECMQmlModule)
|
||||
|
||||
include(KDEGitCommitHooks)
|
||||
include(ECMGenerateQDoc)
|
||||
|
||||
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml)
|
||||
find_package(WaylandScanner REQUIRED)
|
||||
@ -53,6 +54,8 @@ ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX LAYERSHELLQT
|
||||
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
|
||||
kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
|
||||
|
||||
kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT)
|
||||
|
||||
ecm_set_disabled_deprecation_versions(QT 6.5
|
||||
KF 5.240
|
||||
)
|
||||
|
@ -4,10 +4,16 @@
|
||||
remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
|
||||
|
||||
add_library(LayerShellQtInterface)
|
||||
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES
|
||||
${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
|
||||
|
||||
if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0")
|
||||
set(private_code_option "PRIVATE_CODE")
|
||||
endif()
|
||||
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface
|
||||
${private_code_option}
|
||||
FILES
|
||||
${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
|
||||
@ -62,6 +68,8 @@ generate_export_header(LayerShellQtInterface
|
||||
EXPORT_FILE_NAME LayerShellQt/layershellqt_export.h
|
||||
)
|
||||
|
||||
ecm_generate_qdoc(LayerShellQtInterface layershellqt.qdocconf)
|
||||
|
||||
install(TARGETS layer-shell
|
||||
LIBRARY DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/wayland-shell-integration)
|
||||
|
||||
|
@ -4,20 +4,47 @@
|
||||
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include <QQmlExtensionPlugin>
|
||||
#include "../interfaces/window.h"
|
||||
#include <QQmlExtensionPlugin>
|
||||
#include <qqml.h>
|
||||
|
||||
QML_DECLARE_TYPEINFO(LayerShellQt::Window, QML_HAS_ATTACHED_PROPERTIES)
|
||||
|
||||
class ExtQMargins
|
||||
{
|
||||
QMargins m_margins;
|
||||
Q_GADGET
|
||||
Q_PROPERTY(int left READ left WRITE setLeft FINAL)
|
||||
Q_PROPERTY(int right READ right WRITE setRight FINAL)
|
||||
Q_PROPERTY(int top READ top WRITE setTop FINAL)
|
||||
Q_PROPERTY(int bottom READ bottom WRITE setBottom FINAL)
|
||||
QML_FOREIGN(QMargins)
|
||||
QML_EXTENDED(ExtQMargins)
|
||||
public:
|
||||
ExtQMargins(const QMargins &margins);
|
||||
int left() const { return m_margins.left(); }
|
||||
void setLeft(int left) { m_margins.setLeft(left); }
|
||||
|
||||
int right() const { return m_margins.right(); }
|
||||
void setRight(int right) { m_margins.setRight(right); }
|
||||
|
||||
int top() const { return m_margins.top(); }
|
||||
void setTop(int top) { m_margins.setTop(top); }
|
||||
|
||||
int bottom() const { return m_margins.bottom(); }
|
||||
void setBottom(int bottom) { m_margins.setBottom(bottom); }
|
||||
};
|
||||
|
||||
class Plugin : public QQmlExtensionPlugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "org.kde.layershellqt")
|
||||
Q_OBJECT
|
||||
public:
|
||||
void registerTypes(const char *uri) override {
|
||||
void registerTypes(const char *uri) override
|
||||
{
|
||||
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.layershell"));
|
||||
qmlRegisterType<LayerShellQt::Window>(uri, 1, 0, "Window");
|
||||
qmlRegisterExtendedUncreatableType<QMargins, ExtQMargins>(uri, 1, 0, "ExtQMargins", QStringLiteral("Only created from C++"));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,12 +13,18 @@
|
||||
|
||||
namespace LayerShellQt
|
||||
{
|
||||
/**
|
||||
* Sets the right environment so the shells created from now on use wlr-layer-shell.
|
||||
/*!
|
||||
* \class LayerShellQt::Shell
|
||||
* \inmodule LayerShellQt
|
||||
* \inheaderfile LayerShellQt/Shell
|
||||
*
|
||||
*/
|
||||
class LAYERSHELLQT_EXPORT Shell
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Sets the right environment so the shells created from now on use wlr-layer-shell.
|
||||
*/
|
||||
static void useLayerShell();
|
||||
};
|
||||
|
||||
|
@ -18,10 +18,18 @@ namespace LayerShellQt
|
||||
{
|
||||
class WindowPrivate;
|
||||
|
||||
/*!
|
||||
* \class LayerShellQt::Window
|
||||
* \inmodule LayerShellQt
|
||||
* \inheaderfile LayerShellQt/Window
|
||||
*
|
||||
* \brief A window.
|
||||
*/
|
||||
class LAYERSHELLQT_EXPORT Window : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Anchors anchors READ anchors WRITE setAnchors NOTIFY anchorsChanged)
|
||||
/*! \property LayerShellQt::Window::scope */
|
||||
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)
|
||||
@ -32,17 +40,24 @@ class LAYERSHELLQT_EXPORT Window : public QObject
|
||||
public:
|
||||
~Window() override;
|
||||
|
||||
/*!
|
||||
* \value AnchorNone
|
||||
* \value AnchorTop The top edge of the anchor rectangle
|
||||
* \value AnchorBottom The bottom edge of the anchor rectangle
|
||||
* \value AnchorLeft The left edge of the anchor rectangle
|
||||
* \value AnchorRight The right edge of the anchor rectangle
|
||||
*/
|
||||
enum Anchor {
|
||||
AnchorNone = 0,
|
||||
AnchorTop = 1, ///< The top edge of the anchor rectangle
|
||||
AnchorBottom = 2, ///< The bottom edge of the anchor rectangle
|
||||
AnchorLeft = 4, ///< The left edge of the anchor rectangle
|
||||
AnchorRight = 8, ///< The right edge of the anchor rectangle
|
||||
AnchorTop = 1,
|
||||
AnchorBottom = 2,
|
||||
AnchorLeft = 4,
|
||||
AnchorRight = 8,
|
||||
};
|
||||
Q_ENUM(Anchor);
|
||||
Q_DECLARE_FLAGS(Anchors, Anchor)
|
||||
|
||||
/**
|
||||
/*!
|
||||
* This enum type is used to specify the layer where a surface can be put in.
|
||||
*/
|
||||
enum Layer {
|
||||
@ -53,7 +68,7 @@ public:
|
||||
};
|
||||
Q_ENUM(Layer)
|
||||
|
||||
/**
|
||||
/*!
|
||||
* This enum type is used to specify how the layer surface handles keyboard focus.
|
||||
*/
|
||||
enum KeyboardInteractivity {
|
||||
@ -63,7 +78,7 @@ public:
|
||||
};
|
||||
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.
|
||||
@ -95,7 +110,7 @@ public:
|
||||
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
|
||||
ScreenConfiguration screenConfiguration() const;
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Sets a string based identifier for this window.
|
||||
* This may be used by a compositor to determine stacking
|
||||
* order within a given layer.
|
||||
@ -103,9 +118,17 @@ public:
|
||||
* May also be referred to as a role
|
||||
*/
|
||||
void setScope(const QString &scope);
|
||||
|
||||
/*!
|
||||
* A string based identifier for this window.
|
||||
* This may be used by a compositor to determine stacking
|
||||
* order within a given layer.
|
||||
*
|
||||
* May also be referred to as a role
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -114,7 +137,7 @@ public:
|
||||
void setCloseOnDismissed(bool close);
|
||||
bool closeOnDismissed() const;
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Gets the LayerShell Window for a given Qt Window
|
||||
* Ownership is not transferred
|
||||
*/
|
||||
|
72
src/layershellqt.qdoc
Normal file
72
src/layershellqt.qdoc
Normal file
@ -0,0 +1,72 @@
|
||||
/*!
|
||||
\module LayerShellQt
|
||||
\title LayerShellQt C++ Classes
|
||||
|
||||
\cmakepackage LayerShellQt
|
||||
\cmaketargetitem LayerShellQt::Interface
|
||||
*/
|
||||
|
||||
/*!
|
||||
\namespace LayerShellQt
|
||||
\inmodule LayerShellQt
|
||||
|
||||
Stuff
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlmodule org.kde.layershell
|
||||
\title LayerShellQt QML Types
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmltype Window
|
||||
\inqmlmodule org.kde.layershell
|
||||
|
||||
\nativetype LayerShellQt::Window
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty string Window::scope
|
||||
|
||||
A scope.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty int Window::margins.top
|
||||
\qmlproperty int Window::margins.bottom
|
||||
\qmlproperty int Window::margins.left
|
||||
\qmlproperty int Window::margins.right
|
||||
|
||||
Margins
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty int Window::exclusionZone
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page layershellqt-index.html
|
||||
\title LayerShellQt
|
||||
|
||||
Layer Shell
|
||||
|
||||
\section1 Using the Module
|
||||
|
||||
\include {module-use.qdocinc} {using the c++ api}
|
||||
|
||||
\section2 Building with CMake
|
||||
|
||||
\include {module-use.qdocinc} {building with cmake} {Widgets}
|
||||
|
||||
\section1 API Reference
|
||||
|
||||
\list
|
||||
\li \l{LayerShellQt C++ Classes}
|
||||
\li \l{LayerShellQt QML Types}
|
||||
\endlist
|
||||
|
||||
\section1 Licenses
|
||||
|
||||
TODO
|
||||
*/
|
||||
|
30
src/layershellqt.qdocconf
Normal file
30
src/layershellqt.qdocconf
Normal file
@ -0,0 +1,30 @@
|
||||
include($KDE_DOCS/global/qt-module-defaults.qdocconf)
|
||||
|
||||
project = LayerShellQt
|
||||
description = Qt component to allow applications to make use of the Wayland wl-layer-shell protocol
|
||||
|
||||
documentationinheaders = true
|
||||
|
||||
headerdirs = .
|
||||
|
||||
headers.fileextensions = "*.qdoc *.h"
|
||||
|
||||
outputdir = doc/html
|
||||
outputformats = HTML
|
||||
|
||||
depends += \
|
||||
qtcore
|
||||
|
||||
qhp.projects = LayerShellQt
|
||||
|
||||
qhp.LayerShellQt.file = layershellqt.qhp
|
||||
qhp.LayerShellQt.namespace = org.kde.layershellqt.$QT_VERSION_TAG
|
||||
qhp.LayerShellQt.virtualFolder = layershellqt
|
||||
qhp.LayerShellQt.indexTitle = LayerShellQt
|
||||
qhp.LayerShellQt.indexRoot =
|
||||
|
||||
qhp.LayerShellQt.subprojects = classes
|
||||
qhp.LayerShellQt.subprojects.classes.title = C++ Classes
|
||||
qhp.LayerShellQt.subprojects.classes.indexTitle = LayerShellQt C++ Classes
|
||||
qhp.LayerShellQt.subprojects.classes.selectors = class fake:headerfile
|
||||
qhp.LayerShellQt.subprojects.classes.sortPages = true
|
@ -32,5 +32,4 @@ QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration::createShel
|
||||
return new QWaylandLayerSurface(this, window);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,14 +18,19 @@ class QWaylandXdgActivationV1;
|
||||
namespace LayerShellQt
|
||||
{
|
||||
|
||||
class LAYERSHELLQT_EXPORT QWaylandLayerShellIntegration : public QtWaylandClient::QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>, public QtWayland::zwlr_layer_shell_v1
|
||||
class LAYERSHELLQT_EXPORT QWaylandLayerShellIntegration : public QtWaylandClient::QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>,
|
||||
public QtWayland::zwlr_layer_shell_v1
|
||||
{
|
||||
public:
|
||||
QWaylandLayerShellIntegration();
|
||||
~QWaylandLayerShellIntegration() override;
|
||||
|
||||
QWaylandXdgActivationV1 *activation() const { return m_xdgActivation.data(); }
|
||||
QWaylandXdgActivationV1 *activation() const
|
||||
{
|
||||
return m_xdgActivation.data();
|
||||
}
|
||||
QtWaylandClient::QWaylandShellSurface *createShellSurface(QtWaylandClient::QWaylandWindow *window) override;
|
||||
|
||||
private:
|
||||
QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation;
|
||||
};
|
||||
|
@ -67,15 +67,10 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
|
||||
});
|
||||
|
||||
setDesiredSize(window->windowContentGeometry().size());
|
||||
requestWaylandSync();
|
||||
}
|
||||
|
||||
QWaylandLayerSurface::~QWaylandLayerSurface()
|
||||
{
|
||||
for (auto syncCallback: m_waitForSyncCallbacks) {
|
||||
wl_callback_destroy(syncCallback);
|
||||
}
|
||||
m_waitForSyncCallbacks.clear();
|
||||
destroy();
|
||||
}
|
||||
|
||||
@ -88,17 +83,9 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_closed()
|
||||
|
||||
void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height)
|
||||
{
|
||||
qDebug() << "got configure";
|
||||
ack_configure(serial);
|
||||
m_pendingSize = QSize(width, height);
|
||||
|
||||
// because configure lacks a way to match it up with our resize requests
|
||||
// we apply it only when our callback sync is complete
|
||||
if (!m_waitForSyncCallbacks.isEmpty()) {
|
||||
m_hasPendingConfigureToApply = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_configured) {
|
||||
m_configured = true;
|
||||
applyConfigure();
|
||||
@ -108,8 +95,6 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint
|
||||
// are not painting to the window.
|
||||
window()->applyConfigureWhenPossible();
|
||||
}
|
||||
qDebug() << "end got confiure";
|
||||
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *popup)
|
||||
@ -125,10 +110,13 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po
|
||||
|
||||
void QWaylandLayerSurface::applyConfigure()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
m_configuring = true;
|
||||
qDebug() << "resizing panel to " << m_pendingSize;
|
||||
#endif
|
||||
window()->resizeFromApplyConfigure(m_pendingSize);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
m_configuring = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setDesiredSize(const QSize &size)
|
||||
@ -143,7 +131,6 @@ void QWaylandLayerSurface::setDesiredSize(const QSize &size)
|
||||
if (verticallyConstrained) {
|
||||
effectiveSize.setHeight(0);
|
||||
}
|
||||
qDebug() << "requesting size " << effectiveSize;
|
||||
set_size(effectiveSize.width(), effectiveSize.height());
|
||||
}
|
||||
|
||||
@ -180,6 +167,7 @@ void QWaylandLayerSurface::setLayer(uint32_t layer)
|
||||
set_layer(layer);
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
||||
{
|
||||
if (m_configuring) {
|
||||
@ -187,8 +175,13 @@ void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
||||
}
|
||||
|
||||
setDesiredSize(geometry.size());
|
||||
requestWaylandSync();
|
||||
}
|
||||
#else
|
||||
void QWaylandLayerSurface::setWindowSize(const QSize &size)
|
||||
{
|
||||
setDesiredSize(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool QWaylandLayerSurface::requestActivate()
|
||||
{
|
||||
@ -202,14 +195,12 @@ bool QWaylandLayerSurface::requestActivate()
|
||||
return true;
|
||||
} else {
|
||||
const auto focusWindow = QGuiApplication::focusWindow();
|
||||
const auto wlWindow = focusWindow ? static_cast<QtWaylandClient::QWaylandWindow*>(focusWindow->handle()) : window();
|
||||
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());
|
||||
});
|
||||
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;
|
||||
}
|
||||
@ -228,63 +219,23 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial)
|
||||
if (!activation->isActive()) {
|
||||
return;
|
||||
}
|
||||
auto tokenProvider = activation->requestXdgActivationToken(
|
||||
window()->display(), window()->wlSurface(), serial, QString());
|
||||
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, 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_waitForSyncCallbacks.removeOne(callback);
|
||||
layerSurface->handleWaylandSyncDone();
|
||||
}
|
||||
};
|
||||
|
||||
void QWaylandLayerSurface::requestWaylandSync()
|
||||
{
|
||||
auto syncCallback = wl_display_sync(m_window->display()->wl_display());
|
||||
m_waitForSyncCallbacks.append(syncCallback);
|
||||
wl_callback_add_listener(syncCallback, &syncCallbackListener, this);
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::handleWaylandSyncDone()
|
||||
{
|
||||
qDebug() << "handle sync done";
|
||||
if (!window()->window()->isVisible() || !m_waitForSyncCallbacks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_hasPendingConfigureToApply) {
|
||||
m_hasPendingConfigureToApply = false;
|
||||
if (!m_configured) {
|
||||
m_configured = true;
|
||||
applyConfigure();
|
||||
sendExpose();
|
||||
} else {
|
||||
// Later configures are resizes, so we have to queue them up for a time when we
|
||||
// are not painting to the window.
|
||||
window()->applyConfigureWhenPossible();
|
||||
}
|
||||
}
|
||||
qDebug() << "end handle sync done";
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::sendExpose()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
|
||||
window()->handleExpose(QRect(QPoint(), m_pendingSize));
|
||||
#else
|
||||
#elif QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
window()->sendRecursiveExposeEvent();
|
||||
#else
|
||||
window()->updateExposure();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
bool isExposed() const override
|
||||
{
|
||||
return m_configured && m_waitForSyncCallbacks.isEmpty();
|
||||
return m_configured;
|
||||
}
|
||||
void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override;
|
||||
|
||||
@ -43,15 +43,17 @@ public:
|
||||
void setLayer(uint32_t layer);
|
||||
|
||||
void applyConfigure() override;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
void setWindowGeometry(const QRect &geometry) override;
|
||||
#else
|
||||
void setWindowSize(const QSize &size) override;
|
||||
#endif
|
||||
|
||||
bool requestActivate() override;
|
||||
void setXdgActivationToken(const QString &token) override;
|
||||
void requestXdgActivationToken(quint32 serial) override;
|
||||
|
||||
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_closed() override;
|
||||
@ -63,12 +65,11 @@ private:
|
||||
QString m_activationToken;
|
||||
|
||||
bool m_configured = false;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
bool m_configuring = false;
|
||||
bool m_hasPendingConfigureToApply = false;
|
||||
|
||||
static const wl_callback_listener syncCallbackListener;
|
||||
QList<struct wl_callback*> m_waitForSyncCallbacks;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@ Item
|
||||
LayerShell.Window.anchors: LayerShell.Window.AnchorLeft
|
||||
LayerShell.Window.layer: LayerShell.Window.LayerTop
|
||||
LayerShell.Window.exclusionZone: width
|
||||
LayerShell.Window.margins.left: 100
|
||||
|
||||
width: 100
|
||||
height: 100
|
||||
|
Reference in New Issue
Block a user