466f2fe8ba
This installs a socket notifier onto our xwayland socket, when a user connects we launch xwayland. The client then connections once kwin has established itself as the compositor. For a full desktop plasma session this patch effectively does nothing too useful as we still start kcminit and make xrdb calls on startup which in turn will launch X, but for the same reason this patch should be harmless now as we're still processing the xrdb calls before any clients will connect.
208 lines
5.8 KiB
C++
208 lines
5.8 KiB
C++
/*
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
#include "kwin_wayland_test.h"
|
|
|
|
#include "backends/virtual/virtual_backend.h"
|
|
#include "composite.h"
|
|
#include "core/outputbackend.h"
|
|
#include "core/session.h"
|
|
#include "effects.h"
|
|
#include "inputmethod.h"
|
|
#include "placement.h"
|
|
#include "pluginmanager.h"
|
|
#include "utils/xcbutils.h"
|
|
#include "wayland_server.h"
|
|
#include "workspace.h"
|
|
#include "xwayland/xwayland.h"
|
|
#include "xwayland/xwaylandlauncher.h"
|
|
|
|
#include <KPluginMetaData>
|
|
|
|
#include <QAbstractEventDispatcher>
|
|
#include <QPluginLoader>
|
|
#include <QSocketNotifier>
|
|
#include <QThread>
|
|
#include <QtConcurrentRun>
|
|
|
|
// system
|
|
#include <iostream>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
|
|
Q_IMPORT_PLUGIN(KWinIntegrationPlugin)
|
|
Q_IMPORT_PLUGIN(KGlobalAccelImpl)
|
|
Q_IMPORT_PLUGIN(KWindowSystemKWinPlugin)
|
|
Q_IMPORT_PLUGIN(KWinIdleTimePoller)
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
WaylandTestApplication::WaylandTestApplication(OperationMode mode, int &argc, char **argv)
|
|
: Application(mode, argc, argv)
|
|
{
|
|
QStandardPaths::setTestModeEnabled(true);
|
|
// TODO: add a test move to kglobalaccel instead?
|
|
QFile{QStandardPaths::locate(QStandardPaths::ConfigLocation, QStringLiteral("kglobalshortcutsrc"))}.remove();
|
|
QIcon::setThemeName(QStringLiteral("breeze"));
|
|
#if KWIN_BUILD_ACTIVITIES
|
|
setUseKActivities(false);
|
|
#endif
|
|
qputenv("KWIN_COMPOSE", QByteArrayLiteral("Q"));
|
|
qputenv("XDG_CURRENT_DESKTOP", QByteArrayLiteral("KDE"));
|
|
qunsetenv("XKB_DEFAULT_RULES");
|
|
qunsetenv("XKB_DEFAULT_MODEL");
|
|
qunsetenv("XKB_DEFAULT_LAYOUT");
|
|
qunsetenv("XKB_DEFAULT_VARIANT");
|
|
qunsetenv("XKB_DEFAULT_OPTIONS");
|
|
|
|
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
|
|
KConfigGroup windowsGroup = config->group("Windows");
|
|
windowsGroup.writeEntry("Placement", Placement::policyToString(PlacementSmart));
|
|
windowsGroup.sync();
|
|
setConfig(config);
|
|
|
|
const auto ownPath = libraryPaths().last();
|
|
removeLibraryPath(ownPath);
|
|
addLibraryPath(ownPath);
|
|
|
|
setSession(Session::create(Session::Type::Noop));
|
|
setOutputBackend(std::make_unique<VirtualBackend>());
|
|
WaylandServer::create(this);
|
|
setProcessStartupEnvironment(QProcessEnvironment::systemEnvironment());
|
|
}
|
|
|
|
WaylandTestApplication::~WaylandTestApplication()
|
|
{
|
|
setTerminating();
|
|
// need to unload all effects prior to destroying X connection as they might do X calls
|
|
// also before destroy Workspace, as effects might call into Workspace
|
|
if (effects) {
|
|
static_cast<EffectsHandlerImpl *>(effects)->unloadAllEffects();
|
|
}
|
|
m_xwayland.reset();
|
|
destroyVirtualInputDevices();
|
|
destroyColorManager();
|
|
destroyWorkspace();
|
|
destroyInputMethod();
|
|
destroyCompositor();
|
|
destroyInput();
|
|
}
|
|
|
|
void WaylandTestApplication::createVirtualInputDevices()
|
|
{
|
|
m_virtualKeyboard.reset(new Test::VirtualInputDevice());
|
|
m_virtualKeyboard->setName(QStringLiteral("Virtual Keyboard 1"));
|
|
m_virtualKeyboard->setKeyboard(true);
|
|
|
|
m_virtualPointer.reset(new Test::VirtualInputDevice());
|
|
m_virtualPointer->setName(QStringLiteral("Virtual Pointer 1"));
|
|
m_virtualPointer->setPointer(true);
|
|
|
|
m_virtualTouch.reset(new Test::VirtualInputDevice());
|
|
m_virtualTouch->setName(QStringLiteral("Virtual Touch 1"));
|
|
m_virtualTouch->setTouch(true);
|
|
|
|
input()->addInputDevice(m_virtualPointer.get());
|
|
input()->addInputDevice(m_virtualTouch.get());
|
|
input()->addInputDevice(m_virtualKeyboard.get());
|
|
}
|
|
|
|
void WaylandTestApplication::destroyVirtualInputDevices()
|
|
{
|
|
input()->removeInputDevice(m_virtualPointer.get());
|
|
input()->removeInputDevice(m_virtualTouch.get());
|
|
input()->removeInputDevice(m_virtualKeyboard.get());
|
|
}
|
|
|
|
void WaylandTestApplication::performStartup()
|
|
{
|
|
if (!m_inputMethodServerToStart.isEmpty()) {
|
|
createInputMethod();
|
|
if (m_inputMethodServerToStart != QStringLiteral("internal")) {
|
|
inputMethod()->setInputMethodCommand(m_inputMethodServerToStart);
|
|
inputMethod()->setEnabled(true);
|
|
}
|
|
}
|
|
|
|
// first load options - done internally by a different thread
|
|
createOptions();
|
|
if (!outputBackend()->initialize()) {
|
|
std::exit(1);
|
|
}
|
|
|
|
// try creating the Wayland Backend
|
|
createInput();
|
|
createVirtualInputDevices();
|
|
|
|
WaylandCompositor::create();
|
|
connect(Compositor::self(), &Compositor::sceneCreated, this, &WaylandTestApplication::continueStartupWithScene);
|
|
}
|
|
|
|
void WaylandTestApplication::continueStartupWithScene()
|
|
{
|
|
disconnect(Compositor::self(), &Compositor::sceneCreated, this, &WaylandTestApplication::continueStartupWithScene);
|
|
|
|
createWorkspace();
|
|
createColorManager();
|
|
createPlugins();
|
|
|
|
waylandServer()->initWorkspace();
|
|
|
|
if (!waylandServer()->start()) {
|
|
qFatal("Failed to initialize the Wayland server, exiting now");
|
|
}
|
|
|
|
if (operationMode() == OperationModeXwayland) {
|
|
m_xwayland = std::make_unique<Xwl::Xwayland>(this);
|
|
m_xwayland->init();
|
|
}
|
|
|
|
notifyStarted();
|
|
}
|
|
|
|
Test::VirtualInputDevice *WaylandTestApplication::virtualPointer() const
|
|
{
|
|
return m_virtualPointer.get();
|
|
}
|
|
|
|
Test::VirtualInputDevice *WaylandTestApplication::virtualKeyboard() const
|
|
{
|
|
return m_virtualKeyboard.get();
|
|
}
|
|
|
|
Test::VirtualInputDevice *WaylandTestApplication::virtualTouch() const
|
|
{
|
|
return m_virtualTouch.get();
|
|
}
|
|
|
|
XwaylandInterface *WaylandTestApplication::xwayland() const
|
|
{
|
|
return m_xwayland.get();
|
|
}
|
|
|
|
Test::FractionalScaleManagerV1::~FractionalScaleManagerV1()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
Test::FractionalScaleV1::~FractionalScaleV1()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
int Test::FractionalScaleV1::preferredScale()
|
|
{
|
|
return m_preferredScale;
|
|
}
|
|
|
|
void Test::FractionalScaleV1::wp_fractional_scale_v1_preferred_scale(uint32_t scale)
|
|
{
|
|
m_preferredScale = scale;
|
|
}
|
|
}
|