KWindowSystem

kwindowsystem.cpp
1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "kwindowsystem.h"
7#include "kwindowsystem_debug.h"
8#include "kwindowsystem_dummy_p.h"
9#include "pluginwrapper_p.h"
10
11#include <config-kwindowsystem.h>
12
13#if KWINDOWSYSTEM_HAVE_X11
14#include "kstartupinfo.h"
15#endif
16
17#include <QGuiApplication>
18#include <QMetaMethod>
19#include <QPixmap>
20#include <QPluginLoader>
21#include <QTimer>
22#include <QWindow>
23#if KWINDOWSYSTEM_HAVE_X11
24#include <private/qtx11extras_p.h>
25#endif
26
27// QPoint and QSize all have handy / operators which are useful for scaling, positions and sizes for high DPI support
28// QRect does not, so we create one for internal purposes within this class
29inline QRect operator/(const QRect &rectangle, qreal factor)
30{
31 return QRect(rectangle.topLeft() / factor, rectangle.size() / factor);
32}
33
34class KWindowSystemStaticContainer
35{
36public:
37 KWindowSystemStaticContainer()
38 {
39 d.reset(KWindowSystemPluginWrapper::self().createWindowSystem());
40
43 }
44 }
45 KWindowSystem kwm;
46 std::unique_ptr<KWindowSystemPrivate> d;
47};
48
49Q_GLOBAL_STATIC(KWindowSystemStaticContainer, g_kwmInstanceContainer)
50
51KWindowSystemPrivate::~KWindowSystemPrivate()
52{
53}
54
55void KWindowSystemPrivateDummy::activateWindow(QWindow *win, long time)
56{
57 Q_UNUSED(win)
58 Q_UNUSED(time)
59}
60
61bool KWindowSystemPrivateDummy::showingDesktop()
62{
63 return false;
64}
65
66void KWindowSystemPrivateDummy::setShowingDesktop(bool showing)
67{
68 Q_UNUSED(showing);
69}
70
72{
73 return &(g_kwmInstanceContainer()->kwm);
74}
75
76KWindowSystemPrivate *KWindowSystem::d_func()
77{
78 return g_kwmInstanceContainer()->d.get();
79}
80
82{
84 d->activateWindow(win, time);
85}
86
87void KWindowSystem::setMainWindow(QWindow *subWindow, WId mainWindowId)
88{
89 QWindow *mainWindow = QWindow::fromWinId(mainWindowId);
90 if (mainWindow) { // foreign windows not supported on all platforms
91 subWindow->setTransientParent(mainWindow);
92
93 // mainWindow is not the child of any object, so make sure it gets deleted at some point
94 connect(subWindow, &QObject::destroyed, mainWindow, &QObject::deleteLater);
95 }
96}
97
98void KWindowSystem::setMainWindow(QWindow *subWindow, const QString &mainWindowId)
99{
101 if (isPlatformWayland()) {
102 if (auto dv2 = dynamic_cast<KWindowSystemPrivateV2 *>(d)) {
103 dv2->setMainWindow(subWindow, mainWindowId);
104 }
105 } else {
106 bool ok = false;
107 // base 0 means "C style" parsing with 0x for base 16, 0b for base 2, etc.
108 WId wid = mainWindowId.toULongLong(&ok, 0);
109 if (ok) {
110 setMainWindow(subWindow, wid);
111 } else {
112 qCWarning(LOG_KWINDOWSYSTEM) << "Failed to convert" << mainWindowId << "to WId";
113 }
114 }
115}
116
118{
120 return d->showingDesktop();
121}
122
124{
126 return d->setShowingDesktop(showing);
127}
128
129static inline KWindowSystem::Platform initPlatform()
130{
131 auto platformName = QGuiApplication::platformName();
132 if (platformName == QLatin1String("flatpak")) {
133 // here we cannot know what is the actual windowing system, let's try it's env variable
134 const auto flatpakPlatform = QString::fromLocal8Bit(qgetenv("QT_QPA_FLATPAK_PLATFORM"));
135 if (!flatpakPlatform.isEmpty()) {
136 platformName = flatpakPlatform;
137 }
138 }
139#if KWINDOWSYSTEM_HAVE_X11
140 if (platformName == QLatin1String("xcb")) {
142 }
143#endif
144 if (platformName.startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
146 }
148}
149
151{
152 static Platform s_platform = initPlatform();
153 return s_platform;
154}
155
156bool KWindowSystem::isPlatformX11()
157{
158 return platform() == Platform::X11;
159}
160
161bool KWindowSystem::isPlatformWayland()
162{
163 return platform() == Platform::Wayland;
164}
165
167{
168 // clang-format off
169 // TODO: move to a new KWindowSystemPrivate interface
170#if KWINDOWSYSTEM_HAVE_X11
171 if (isPlatformX11()) {
172 const QByteArray startupId = QX11Info::nextStartupId();
173 if (!startupId.isEmpty()) {
174 KStartupInfo::setNewStartupId(window, startupId);
175 }
176 } else
177#else
178 Q_UNUSED(window);
179#endif
180 if (isPlatformWayland()) {
181 const QString token = qEnvironmentVariable("XDG_ACTIVATION_TOKEN");
182 if (!token.isEmpty()) {
184 qunsetenv("XDG_ACTIVATION_TOKEN");
185 }
186 }
187 // clang-format on
188}
189
191{
193 auto dv2 = dynamic_cast<KWindowSystemPrivateV2 *>(d);
194 if (!dv2) {
195 return;
196 }
197 dv2->setCurrentToken(token);
198}
199
200#include "moc_kwindowsystem.cpp"
static void setNewStartupId(QWindow *window, const QByteArray &startup_id)
Use this function if the application got a request with startup notification from outside (for exampl...
Convenience access to certain properties and features of window systems.
static Q_INVOKABLE void activateWindow(QWindow *window, long time=0)
Requests that window window is activated.
static void setShowingDesktop(bool showing)
Sets the state of the "showing desktop" mode of the window manager.
static void setMainWindow(QWindow *subwindow, WId mainwindow)
Sets the parent window of subwindow to be mainwindow.
static Q_INVOKABLE void setCurrentXdgActivationToken(const QString &token)
Sets the token that will be used when activateWindow is called next.
bool showingDesktop
Whether "show desktop" is currently active.
static void updateStartupId(QWindow *window)
Updates the platform-specific startup id, if any.
static Platform platform()
Returns the Platform used by the QGuiApplication.
static KWindowSystem * self()
Access to the singleton instance.
Platform
Enum describing the windowing system platform used by the QGuiApplication.
@ Unknown
A platform unknown to the application is used.
@ Wayland
The Wayland window system.
@ X11
The X11 window system.
bool isEmpty() const const
QCoreApplication * instance()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
void destroyed(QObject *obj)
void moveToThread(QThread *targetThread)
QSize size() const const
QPoint topLeft() const const
QString fromLocal8Bit(QByteArrayView str)
bool isEmpty() const const
qulonglong toULongLong(bool *ok, int base) const const
CaseInsensitive
QWindow * fromWinId(WId id)
void setTransientParent(QWindow *parent)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:15:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.