Support XDG activation
QWaylandLayerShellIntegration has virtual hooks for Xdg Activation. This is important to hook up in layer shell because activation using requestActivate in Qt will go through this path. It also means we have support for us to drop the implementation in KWindowSystem in favour of calling into Qt.
This commit is contained in:
parent
00b26a196d
commit
de9fdb3fb7
|
@ -6,10 +6,11 @@ remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
|
||||||
add_library(LayerShellQtInterface)
|
add_library(LayerShellQtInterface)
|
||||||
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES
|
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES
|
||||||
${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
|
${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
|
${CMAKE_CURRENT_SOURCE_DIR}/wlr-layer-shell-unstable-v1.xml
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
|
ecm_qt_declare_logging_category(LayerShellQtInterface
|
||||||
HEADER
|
HEADER
|
||||||
layershellqt_logging.h
|
layershellqt_logging.h
|
||||||
IDENTIFIER
|
IDENTIFIER
|
||||||
|
@ -18,7 +19,14 @@ ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
|
||||||
layershellqt
|
layershellqt
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(LayerShellQtInterface PRIVATE qwaylandlayersurface.cpp interfaces/window.cpp interfaces/shell.cpp qwaylandlayershellintegration.cpp ${LAYER_SHELL_SOURCES})
|
target_sources(LayerShellQtInterface PRIVATE
|
||||||
|
qwaylandxdgactivationv1.cpp
|
||||||
|
qwaylandlayersurface.cpp
|
||||||
|
qwaylandlayershellintegration.cpp
|
||||||
|
interfaces/window.cpp
|
||||||
|
interfaces/shell.cpp
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(LayerShellQtInterface PUBLIC Qt::Gui)
|
target_link_libraries(LayerShellQtInterface PUBLIC Qt::Gui)
|
||||||
target_link_libraries(LayerShellQtInterface PRIVATE Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
|
target_link_libraries(LayerShellQtInterface PRIVATE Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
|
||||||
if (TARGET Qt::XkbCommonSupportPrivate)
|
if (TARGET Qt::XkbCommonSupportPrivate)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "qwaylandlayershellintegration_p.h"
|
#include "qwaylandlayershellintegration_p.h"
|
||||||
#include "qwaylandlayersurface_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>
|
||||||
|
@ -15,6 +16,7 @@ namespace LayerShellQt
|
||||||
{
|
{
|
||||||
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
|
QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
|
||||||
: QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>(4)
|
: QWaylandShellIntegrationTemplate<QWaylandLayerShellIntegration>(4)
|
||||||
|
, m_xdgActivation(new QWaylandXdgActivationV1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
|
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
|
||||||
#include <qwayland-wlr-layer-shell-unstable-v1.h>
|
#include <qwayland-wlr-layer-shell-unstable-v1.h>
|
||||||
|
|
||||||
|
class QWaylandXdgActivationV1;
|
||||||
|
|
||||||
namespace LayerShellQt
|
namespace LayerShellQt
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -22,7 +24,10 @@ 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:
|
||||||
|
QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,20 @@
|
||||||
#include "interfaces/window.h"
|
#include "interfaces/window.h"
|
||||||
#include "layershellqt_logging.h"
|
#include "layershellqt_logging.h"
|
||||||
#include "qwaylandlayersurface_p.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(QtWayland::zwlr_layer_shell_v1 *shell, QtWaylandClient::QWaylandWindow *window)
|
QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *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_interface(Window::get(window->window()))
|
||||||
{
|
{
|
||||||
wl_output *output = nullptr;
|
wl_output *output = nullptr;
|
||||||
|
@ -155,4 +159,54 @@ void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
|
||||||
set_size(size.width(), size.height());
|
set_size(size.width(), size.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#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>
|
||||||
|
@ -23,7 +25,7 @@ class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylan
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell, QtWaylandClient::QWaylandWindow *window);
|
QWaylandLayerSurface(QWaylandLayerShellIntegration *shell, QtWaylandClient::QWaylandWindow *window);
|
||||||
~QWaylandLayerSurface() override;
|
~QWaylandLayerSurface() override;
|
||||||
|
|
||||||
bool isExposed() const override
|
bool isExposed() const override
|
||||||
|
@ -43,12 +45,18 @@ public:
|
||||||
void applyConfigure() override;
|
void applyConfigure() override;
|
||||||
void setWindowGeometry(const QRect &geometry) override;
|
void setWindowGeometry(const QRect &geometry) override;
|
||||||
|
|
||||||
|
bool requestActivate() override;
|
||||||
|
void setXdgActivationToken(const QString &token) override;
|
||||||
|
void requestXdgActivationToken(quint32 serial) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
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;
|
LayerShellQt::Window *m_interface;
|
||||||
QSize m_pendingSize;
|
QSize m_pendingSize;
|
||||||
|
QString m_activationToken;
|
||||||
bool m_configured = false;
|
bool m_configured = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
44
src/qwaylandxdgactivationv1.cpp
Normal file
44
src/qwaylandxdgactivationv1.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/** 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"
|
48
src/qwaylandxdgactivationv1_p.h
Normal file
48
src/qwaylandxdgactivationv1_p.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/** 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
|
Loading…
Reference in a new issue