KWin
Loading...
Searching...
No Matches
kwin_wayland_test.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "kwin_wayland_test.h"
10
12#include "compositor_wayland.h"
13#include "core/session.h"
15#include "inputmethod.h"
16#include "placement.h"
17#include "pluginmanager.h"
18#include "utils/xcbutils.h"
19#include "wayland_server.h"
20#include "workspace.h"
21#include "xwayland/xwayland.h"
23
24#include <KPluginMetaData>
25
26#include <QAbstractEventDispatcher>
27#include <QPluginLoader>
28#include <QSocketNotifier>
29#include <QThread>
30#include <QtConcurrentRun>
31
32// system
33#include <iostream>
34#include <sys/socket.h>
35#include <unistd.h>
36
37Q_IMPORT_PLUGIN(KWinIntegrationPlugin)
38#if KWIN_BUILD_GLOBALSHORTCUTS
39Q_IMPORT_PLUGIN(KGlobalAccelImpl)
40#endif
41Q_IMPORT_PLUGIN(KWindowSystemKWinPlugin)
42Q_IMPORT_PLUGIN(KWinIdleTimePoller)
43
44namespace KWin
45{
46
48 : Application(mode, argc, argv)
49{
50 QStandardPaths::setTestModeEnabled(true);
51
52 const QStringList configs{
53 QStringLiteral("kaccessrc"),
54 QStringLiteral("kglobalshortcutsrc"),
55 };
56 for (const QString &config : configs) {
57 if (const QString &fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, config); !fileName.isEmpty()) {
58 QFile::remove(fileName);
59 }
60 }
61
62 QIcon::setThemeName(QStringLiteral("breeze"));
63#if KWIN_BUILD_ACTIVITIES
64 setUseKActivities(false);
65#endif
66 qputenv("KWIN_COMPOSE", QByteArrayLiteral("Q"));
67 qputenv("XDG_CURRENT_DESKTOP", QByteArrayLiteral("KDE"));
68 qunsetenv("XKB_DEFAULT_RULES");
69 qunsetenv("XKB_DEFAULT_MODEL");
70 qunsetenv("XKB_DEFAULT_LAYOUT");
71 qunsetenv("XKB_DEFAULT_VARIANT");
72 qunsetenv("XKB_DEFAULT_OPTIONS");
73
74 auto breezerc = KSharedConfig::openConfig(QStringLiteral("breezerc"));
75 breezerc->group(QStringLiteral("Common")).writeEntry(QStringLiteral("OutlineIntensity"), QStringLiteral("OutlineOff"));
76 breezerc->sync();
77
78 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
79 KConfigGroup windowsGroup = config->group(QStringLiteral("Windows"));
80 windowsGroup.writeEntry("Placement", Placement::policyToString(PlacementSmart));
81 windowsGroup.sync();
83
84 const auto ownPath = libraryPaths().last();
85 removeLibraryPath(ownPath);
86 addLibraryPath(ownPath);
87
89 setOutputBackend(std::make_unique<VirtualBackend>());
90 WaylandServer::create(this);
91 setProcessStartupEnvironment(QProcessEnvironment::systemEnvironment());
92}
93
95{
97 // need to unload all effects prior to destroying X connection as they might do X calls
98 // also before destroy Workspace, as effects might call into Workspace
99 if (effects) {
101 }
102 m_xwayland.reset();
103 destroyVirtualInputDevices();
108 destroyInput();
109}
110
111void WaylandTestApplication::createVirtualInputDevices()
112{
113 m_virtualKeyboard = std::make_unique<Test::VirtualInputDevice>();
114 m_virtualKeyboard->setName(QStringLiteral("Virtual Keyboard 1"));
115 m_virtualKeyboard->setKeyboard(true);
116
117 m_virtualPointer = std::make_unique<Test::VirtualInputDevice>();
118 m_virtualPointer->setName(QStringLiteral("Virtual Pointer 1"));
119 m_virtualPointer->setPointer(true);
120
121 m_virtualTouch = std::make_unique<Test::VirtualInputDevice>();
122 m_virtualTouch->setName(QStringLiteral("Virtual Touch 1"));
123 m_virtualTouch->setTouch(true);
124
125 input()->addInputDevice(m_virtualPointer.get());
126 input()->addInputDevice(m_virtualTouch.get());
127 input()->addInputDevice(m_virtualKeyboard.get());
128}
129
130void WaylandTestApplication::destroyVirtualInputDevices()
131{
132 if (m_virtualPointer) {
133 input()->removeInputDevice(m_virtualPointer.get());
134 }
135 if (m_virtualTouch) {
136 input()->removeInputDevice(m_virtualTouch.get());
137 }
138 if (m_virtualKeyboard) {
139 input()->removeInputDevice(m_virtualKeyboard.get());
140 }
141}
142
144{
145 if (!m_inputMethodServerToStart.isEmpty()) {
147 if (m_inputMethodServerToStart != QStringLiteral("internal")) {
148 inputMethod()->setInputMethodCommand(m_inputMethodServerToStart);
149 inputMethod()->setEnabled(true);
150 }
151 }
152
153 // first load options - done internally by a different thread
155 if (!outputBackend()->initialize()) {
156 std::exit(1);
157 }
158
159 // try creating the Wayland Backend
160 createInput();
161 createVirtualInputDevices();
163
168
169 connect(Compositor::self(), &Compositor::sceneCreated, this, &WaylandTestApplication::continueStartupWithScene);
170}
171
172void WaylandTestApplication::continueStartupWithScene()
173{
174 disconnect(Compositor::self(), &Compositor::sceneCreated, this, &WaylandTestApplication::continueStartupWithScene);
175
177
178 if (!waylandServer()->start()) {
179 qFatal("Failed to initialize the Wayland server, exiting now");
180 }
181
183 m_xwayland = std::make_unique<Xwl::Xwayland>(this);
184 m_xwayland->init();
185 }
186
188}
189
191{
192 return m_virtualPointer.get();
193}
194
196{
197 return m_virtualKeyboard.get();
198}
199
201{
202 return m_virtualTouch.get();
203}
204
206{
207 return m_xwayland.get();
208}
209
214
219
221{
222 return m_preferredScale;
223}
224
226{
227 m_preferredScale = scale;
228}
229
230void Test::setOutputConfig(const QList<QRect> &geometries)
231{
232 QList<VirtualBackend::OutputInfo> converted;
233 std::transform(geometries.begin(), geometries.end(), std::back_inserter(converted), [](const auto &geometry) {
234 return VirtualBackend::OutputInfo{
235 .geometry = geometry,
236 };
237 });
238 static_cast<VirtualBackend *>(kwinApp()->outputBackend())->setVirtualOutputs(converted);
239}
240
241void Test::setOutputConfig(const QList<OutputInfo> &infos)
242{
243 QList<VirtualBackend::OutputInfo> converted;
244 std::transform(infos.begin(), infos.end(), std::back_inserter(converted), [](const auto &info) {
245 return VirtualBackend::OutputInfo{
246 .geometry = info.geometry,
247 .scale = info.scale,
248 .internal = info.internal,
249 };
250 });
251 static_cast<VirtualBackend *>(kwinApp()->outputBackend())->setVirtualOutputs(converted);
252}
253}
254
255#include "moc_kwin_wayland_test.cpp"
void destroyWorkspace()
Definition main.cpp:313
void notifyStarted()
Definition main.cpp:146
OutputBackend * outputBackend() const
Definition main.h:242
void destroyColorManager()
Definition main.cpp:328
void createOptions()
Definition main.cpp:268
void createPlugins()
Definition main.cpp:273
void destroyInput()
Definition main.cpp:308
void createTabletModeManager()
Definition main.cpp:288
void createInput()
Definition main.cpp:253
void setSession(std::unique_ptr< Session > &&session)
Definition main.cpp:644
void setConfig(KSharedConfigPtr config)
Definition main.h:106
void setOutputBackend(std::unique_ptr< OutputBackend > &&backend)
Definition main.cpp:638
void setProcessStartupEnvironment(const QProcessEnvironment &environment)
Definition main.cpp:633
void destroyInputMethod()
Definition main.cpp:333
void createColorManager()
Definition main.cpp:278
InputMethod * inputMethod() const
Definition main.cpp:655
void createWorkspace()
Definition main.cpp:239
OperationMode operationMode() const
The operation mode used by KWin.
Definition main.cpp:97
void createInputMethod()
Definition main.cpp:283
void setTerminating()
Definition main.h:365
OperationMode
This enum provides the various operation modes of KWin depending on the available Windowing Systems a...
Definition main.h:83
@ OperationModeXwayland
KWin uses Wayland and controls a nested Xwayland server.
Definition main.h:95
void destroyCompositor()
Definition main.cpp:318
KSharedConfigPtr config
Definition main.h:74
static Compositor * self()
void setInputMethodCommand(const QString &path)
void setEnabled(bool enable)
void removeInputDevice(InputDevice *device)
Definition input.cpp:3067
void addInputDevice(InputDevice *device)
Definition input.cpp:2995
static const char * policyToString(PlacementPolicy policy)
static std::unique_ptr< Session > create()
Definition session.cpp:25
void wp_fractional_scale_v1_preferred_scale(uint32_t scale) override
static WaylandCompositor * create(QObject *parent=nullptr)
XwaylandInterface * xwayland() const override
Test::VirtualInputDevice * virtualPointer() const
Test::VirtualInputDevice * virtualTouch() const
Test::VirtualInputDevice * virtualKeyboard() const
WaylandTestApplication(OperationMode mode, int &argc, char **argv)
void setOutputConfig(const QList< QRect > &geometries)
@ PlacementSmart
Definition options.h:62
WaylandServer * waylandServer()
InputRedirection * input()
Definition input.h:549
EffectsHandler * effects