7#include "windowsystem.h"
9#include "surfacehelper.h"
10#include "waylandxdgactivationv1_p.h"
11#include "waylandxdgforeignv2_p.h"
13#include <KWaylandExtras>
14#include <KWindowSystem>
16#include "qwayland-plasma-window-management.h"
18#include <QGuiApplication>
23#include <QWaylandClientExtensionTemplate>
25#include <qpa/qplatformnativeinterface.h>
26#include <qpa/qplatformwindow_p.h>
28constexpr const char *c_kdeXdgForeignExportedProperty(
"_kde_xdg_foreign_exported_v2");
29constexpr const char *c_kdeXdgForeignImportedProperty(
"_kde_xdg_foreign_imported_v2");
30constexpr const char *c_kdeXdgForeignPendingHandleProperty(
"_kde_xdg_foreign_pending_handle");
32class WindowManagement :
public QWaylandClientExtensionTemplate<WindowManagement>,
public QtWayland::org_kde_plasma_window_management
36 : QWaylandClientExtensionTemplate<WindowManagement>(17)
40 void org_kde_plasma_window_management_show_desktop_changed(uint32_t state)
override
42 showingDesktop = state == show_desktop_enabled;
46 bool showingDesktop =
false;
49WindowSystem::WindowSystem()
51 , KWindowSystemPrivateV2()
52 , m_lastToken(qEnvironmentVariable(
"XDG_ACTIVATION_TOKEN"))
54 m_windowManagement =
new WindowManagement;
57WindowSystem::~WindowSystem()
59 delete m_windowManagement;
62void WindowSystem::activateWindow(
QWindow *win,
long int time)
65 auto s = surfaceForWindow(win);
69 WaylandXdgActivationV1 *activation = WaylandXdgActivationV1::self();
70 if (!activation->isActive()) {
73 activation->activate(m_lastToken, s);
76void WindowSystem::requestToken(
QWindow *window, uint32_t serial,
const QString &app_id)
81 wl_surface *wlSurface = surfaceForWindow(window);
83 WaylandXdgActivationV1 *activation = WaylandXdgActivationV1::self();
84 if (!activation->isActive()) {
92 auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>();
93 auto seat = waylandApp ? waylandApp->lastInputSeat() :
nullptr;
94 auto tokenReq = activation->requestXdgActivationToken(seat, wlSurface, serial, app_id);
103void WindowSystem::setCurrentToken(
const QString &token)
108quint32 WindowSystem::lastInputSerial(
QWindow *window)
111 if (
auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>()) {
112 return waylandApp->lastInputSerial();
117void WindowSystem::setShowingDesktop(
bool showing)
119 if (!m_windowManagement->isActive()) {
122 m_windowManagement->show_desktop(showing ? WindowManagement::show_desktop_enabled : WindowManagement::show_desktop_disabled);
125bool WindowSystem::showingDesktop()
127 if (!m_windowManagement->isActive()) {
130 return m_windowManagement->showingDesktop;
133void WindowSystem::exportWindow(
QWindow *window)
135 auto emitHandle = [
window](
const QString &handle) {
151 auto waylandWindow =
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>();
152 if (!waylandWindow) {
157 auto &exporter = WaylandXdgForeignExporterV2::self();
158 if (!exporter.isActive()) {
165 WaylandXdgForeignExportedV2 *exported = waylandWindow->property(c_kdeXdgForeignExportedProperty).value<WaylandXdgForeignExportedV2 *>();
167 exported = exporter.exportToplevel(surfaceForWindow(window));
168 exported->setParent(waylandWindow);
170 waylandWindow->setProperty(c_kdeXdgForeignExportedProperty,
QVariant::fromValue(exported));
172 waylandWindow->setProperty(c_kdeXdgForeignExportedProperty, QVariant());
175 connect(exported, &WaylandXdgForeignExportedV2::handleReceived, window, [window](
const QString &handle) {
180 if (!exported->handle().isEmpty()) {
181 emitHandle(exported->handle());
185void WindowSystem::unexportWindow(
QWindow *window)
187 auto waylandWindow =
window ?
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>() : nullptr;
188 if (!waylandWindow) {
192 WaylandXdgForeignExportedV2 *exported = waylandWindow->property(c_kdeXdgForeignExportedProperty).value<WaylandXdgForeignExportedV2 *>();
194 Q_ASSERT(!waylandWindow->property(c_kdeXdgForeignExportedProperty).isValid());
197void WindowSystem::setMainWindow(
QWindow *window,
const QString &handle)
204 auto waylandWindow =
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>();
205 if (!waylandWindow) {
211 auto *imported = waylandWindow->
property(c_kdeXdgForeignImportedProperty).
value<WaylandXdgForeignImportedV2 *>();
213 if (imported && imported->handle() != handle) {
216 Q_ASSERT(!waylandWindow->property(c_kdeXdgForeignImportedProperty).isValid());
224 if (
window->isExposed()) {
225 doSetMainWindow(window, handle);
231#if QT_VERSION < QT_VERSION_CHECK(6, 8, 0)
235 connect(waylandWindow, &QNativeInterface::Private::QWaylandWindow::surfaceRoleCreated, window, [window, handle] {
236 doSetMainWindow(window, handle);
242bool WindowSystem::eventFilter(
QObject *watched,
QEvent *event)
244#if QT_VERSION < QT_VERSION_CHECK(6, 8, 0)
246 auto *
window =
static_cast<QWindow *
>(watched);
247 if (
window->isExposed()) {
250 doSetMainWindow(window, handle);
262void WindowSystem::doSetMainWindow(
QWindow *window,
const QString &handle)
267 auto waylandWindow =
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>();
268 if (!waylandWindow) {
272 auto &importer = WaylandXdgForeignImporterV2::self();
273 if (!importer.isActive()) {
277 Q_ASSERT(!waylandWindow->property(c_kdeXdgForeignImportedProperty).isValid());
279 WaylandXdgForeignImportedV2 *imported = importer.importToplevel(handle);
280 imported->set_parent_of(surfaceForWindow(window));
281 imported->setParent(waylandWindow);
283 waylandWindow->setProperty(c_kdeXdgForeignImportedProperty,
QVariant::fromValue(imported));
285 waylandWindow->setProperty(c_kdeXdgForeignImportedProperty, QVariant());
289#include "moc_windowsystem.cpp"
void xdgActivationTokenArrived(int serial, const QString &token)
Activation token to pass to the client.
void windowExported(QWindow *window, const QString &handle)
Window handle to pass to the client.
void showingDesktopChanged(bool showing)
The state of showing the desktop has changed.
static KWindowSystem * self()
Access to the singleton instance.
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
virtual bool event(QEvent *e)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
QVariant property(const char *name) const const
void removeEventFilter(QObject *obj)
bool setProperty(const char *name, QVariant &&value)
bool isEmpty() const const
QVariant fromValue(T &&value)
QString toString() const const