2020-08-02 22:22:19 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
2014-08-12 07:08:48 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
2014-08-12 07:08:48 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2014-08-12 07:08:48 +00:00
|
|
|
#include "main_wayland.h"
|
2022-03-23 10:13:38 +00:00
|
|
|
|
|
|
|
#include <config-kwin.h>
|
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
#include "backends/drm/drm_backend.h"
|
|
|
|
#include "backends/virtual/virtual_backend.h"
|
|
|
|
#include "backends/wayland/wayland_backend.h"
|
2022-07-22 17:25:05 +00:00
|
|
|
#include "backends/x11/windowed/x11_windowed_backend.h"
|
2016-04-14 06:51:16 +00:00
|
|
|
#include "composite.h"
|
2022-11-05 10:43:41 +00:00
|
|
|
#include "core/outputbackend.h"
|
2022-08-29 07:55:49 +00:00
|
|
|
#include "core/session.h"
|
2022-03-23 10:13:38 +00:00
|
|
|
#include "effects.h"
|
2020-09-29 14:46:32 +00:00
|
|
|
#include "inputmethod.h"
|
A basic TabletModeManager
Summary:
depends from D9521
listens to switch events and updates the tablet mode status
which is exposed to dbus in the org.kde.KWin.TabletModeManager
interface
Test Plan:
as hardware support is limited, testing of clients
so far is done by the setter in the dbus property,
which should be removed from the final version.
It has been tested to successfully work on a Thinkpad.
Reviewers: #plasma, #kwin, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: graesslin, davidedmundson, plasma-devel, kwin, #kwin
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D9764
2018-01-11 12:09:43 +00:00
|
|
|
#include "tabletmodemanager.h"
|
2022-05-16 07:31:30 +00:00
|
|
|
#include "utils/realtime.h"
|
2022-04-22 09:27:33 +00:00
|
|
|
#include "wayland/display.h"
|
|
|
|
#include "wayland/seat_interface.h"
|
2015-02-09 12:28:37 +00:00
|
|
|
#include "wayland_server.h"
|
2022-03-23 10:13:38 +00:00
|
|
|
#include "workspace.h"
|
2022-04-22 10:09:02 +00:00
|
|
|
#include "xwayland/xwayland.h"
|
|
|
|
#include "xwayland/xwaylandlauncher.h"
|
2014-08-12 07:08:48 +00:00
|
|
|
|
|
|
|
// KDE
|
2020-04-28 12:45:34 +00:00
|
|
|
#include <KCrash>
|
2020-12-23 00:41:47 +00:00
|
|
|
#include <KDesktopFile>
|
2014-08-12 07:08:48 +00:00
|
|
|
#include <KLocalizedString>
|
2020-04-28 12:45:34 +00:00
|
|
|
#include <KShell>
|
2022-09-15 15:18:44 +00:00
|
|
|
#include <KSignalHandler>
|
2017-11-01 15:45:05 +00:00
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
// Qt
|
|
|
|
#include <QCommandLineParser>
|
2022-03-23 10:13:38 +00:00
|
|
|
#include <QDBusInterface>
|
|
|
|
#include <QDebug>
|
2015-12-08 10:42:48 +00:00
|
|
|
#include <QFileInfo>
|
2015-04-21 09:21:28 +00:00
|
|
|
#include <QProcess>
|
2015-02-25 10:42:56 +00:00
|
|
|
#include <QWindow>
|
2022-03-23 10:13:38 +00:00
|
|
|
#include <qplatformdefs.h>
|
2014-08-12 07:08:48 +00:00
|
|
|
|
2017-09-10 10:05:29 +00:00
|
|
|
#include <sched.h>
|
2022-05-15 13:22:35 +00:00
|
|
|
#include <sys/resource.h>
|
2017-09-10 10:05:29 +00:00
|
|
|
|
2015-10-02 07:31:47 +00:00
|
|
|
#include <iomanip>
|
2022-03-23 10:13:38 +00:00
|
|
|
#include <iostream>
|
2014-08-12 13:27:35 +00:00
|
|
|
|
2020-11-20 14:28:47 +00:00
|
|
|
Q_IMPORT_PLUGIN(KWinIntegrationPlugin)
|
2020-11-21 10:16:59 +00:00
|
|
|
Q_IMPORT_PLUGIN(KGlobalAccelImpl)
|
2020-11-21 10:22:48 +00:00
|
|
|
Q_IMPORT_PLUGIN(KWindowSystemKWinPlugin)
|
2020-11-21 10:36:49 +00:00
|
|
|
Q_IMPORT_PLUGIN(KWinIdleTimePoller)
|
2022-02-28 19:12:30 +00:00
|
|
|
#if PipeWire_FOUND
|
2020-11-07 19:34:55 +00:00
|
|
|
Q_IMPORT_PLUGIN(ScreencastManagerFactory)
|
|
|
|
#endif
|
2020-11-20 14:28:47 +00:00
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2022-05-15 13:22:35 +00:00
|
|
|
static rlimit originalNofileLimit = {
|
|
|
|
.rlim_cur = 0,
|
|
|
|
.rlim_max = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool bumpNofileLimit()
|
|
|
|
{
|
|
|
|
if (getrlimit(RLIMIT_NOFILE, &originalNofileLimit) == -1) {
|
|
|
|
std::cerr << "Failed to bump RLIMIT_NOFILE limit, getrlimit() failed: " << strerror(errno) << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
rlimit limit = originalNofileLimit;
|
|
|
|
limit.rlim_cur = limit.rlim_max;
|
|
|
|
|
|
|
|
if (setrlimit(RLIMIT_NOFILE, &limit) == -1) {
|
|
|
|
std::cerr << "Failed to bump RLIMIT_NOFILE limit, setrlimit() failed: " << strerror(errno) << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void restoreNofileLimit()
|
|
|
|
{
|
|
|
|
if (setrlimit(RLIMIT_NOFILE, &originalNofileLimit) == -1) {
|
|
|
|
std::cerr << "Failed to restore RLIMIT_NOFILE limit, legacy apps might be broken" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-12 09:58:36 +00:00
|
|
|
void disableDrKonqi()
|
|
|
|
{
|
|
|
|
KCrash::setDrKonqiEnabled(false);
|
|
|
|
}
|
|
|
|
// run immediately, before Q_CORE_STARTUP functions
|
|
|
|
// that would enable drkonqi
|
|
|
|
Q_CONSTRUCTOR_FUNCTION(disableDrKonqi)
|
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
//************************************
|
|
|
|
// ApplicationWayland
|
|
|
|
//************************************
|
|
|
|
|
|
|
|
ApplicationWayland::ApplicationWayland(int &argc, char **argv)
|
2022-07-15 07:15:54 +00:00
|
|
|
: Application(OperationModeWaylandOnly, argc, argv)
|
2014-08-12 07:08:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ApplicationWayland::~ApplicationWayland()
|
|
|
|
{
|
2019-01-06 16:05:10 +00:00
|
|
|
setTerminating();
|
2015-11-30 14:57:22 +00:00
|
|
|
if (!waylandServer()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-21 16:13:07 +00:00
|
|
|
destroyPlugins();
|
|
|
|
|
2015-11-12 10:29:56 +00:00
|
|
|
// need to unload all effects prior to destroying X connection as they might do X calls
|
|
|
|
if (effects) {
|
2022-03-23 10:13:38 +00:00
|
|
|
static_cast<EffectsHandlerImpl *>(effects)->unloadAllEffects();
|
2015-11-12 10:29:56 +00:00
|
|
|
}
|
2022-07-05 11:43:25 +00:00
|
|
|
m_xwayland.reset();
|
2022-07-23 12:39:17 +00:00
|
|
|
destroyColorManager();
|
wayland: Terminate client connections before Workspace is destroyed
Summary:
When ShellClient tears down, it needs to access RuleBook in order to
discard temporary rules. The problem is that WaylandServer outlives
Workspace and therefore so does ShellClient.
We can't guard against the case when RuleBook::self() is nullptr as it
is vital to discard temporary rules.
This change adjusts termination sequence so all shell clients are
destroyed before Workspace(and thus RuleBook) is gone.
ASAN output:
==19922==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000142060 at pc 0x7fbc0fb878bb bp 0x7ffd7d464520 sp 0x7ffd7d464518
READ of size 8 at 0x606000142060 thread T0
#0 0x7fbc0fb878ba in QList<KWin::Rules*>::detach() /usr/include/qt5/QtCore/qlist.h:172
#1 0x7fbc0fb8538d in QList<KWin::Rules*>::begin() /usr/include/qt5/QtCore/qlist.h:324
#2 0x7fbc0fb808b6 in KWin::RuleBook::discardUsed(KWin::AbstractClient*, bool) /home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/rules.cpp:1144
#3 0x7fbc0fe36e32 in KWin::ShellClient::destroyClient() /home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/shell_client.cpp:435
#4 0x7fbc0fe7a726 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KWin::ShellClient::*)()>::call(void (KWin::ShellClient::*)(), KWin::ShellClient*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:152
#5 0x7fbc0fe784c3 in void QtPrivate::FunctionPointer<void (KWin::ShellClient::*)()>::call<QtPrivate::List<>, void>(void (KWin::ShellClient::*)(), KWin::ShellClient*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:185
#6 0x7fbc0fe74de9 in QtPrivate::QSlotObject<void (KWin::ShellClient::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (/home/jenkins/install-prefix/lib64/libkwin.so.5+0x1677de9)
#7 0x7fbc04f27357 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x2b3357)
#8 0x7fbc074e1970 in KWayland::Server::Resource::unbound() /home/jenkins/workspace/Administration/Dependency Build Plasma kf5-qt5 SUSEQt5.12/kwayland/build/src/server/KF5WaylandServer_autogen/EWIEGA46WW/moc_resource.cpp:142
#9 0x7fbc0766b4b4 in KWayland::Server::Resource::Private::unbind(wl_resource*) /home/jenkins/workspace/Administration/Dependency Build Plasma kf5-qt5 SUSEQt5.12/kwayland/src/server/resource.cpp:68
#10 0x7fbc00bdc2ae (/usr/lib64/libwayland-server.so.0+0x92ae)
#11 0x7fbc00bdc32f in wl_resource_destroy (/usr/lib64/libwayland-server.so.0+0x932f)
#12 0x7fbc0766b53f in KWayland::Server::Resource::Private::resourceDestroyedCallback(wl_client*, wl_resource*) /home/jenkins/workspace/Administration/Dependency Build Plasma kf5-qt5 SUSEQt5.12/kwayland/src/server/resource.cpp:76
#13 0x7fbbff481d8c (/usr/lib64/libffi.so.7+0x6d8c)
#14 0x7fbbff481179 (/usr/lib64/libffi.so.7+0x6179)
#15 0x7fbc00bdfa5f (/usr/lib64/libwayland-server.so.0+0xca5f)
#16 0x7fbc00bdc6d1 (/usr/lib64/libwayland-server.so.0+0x96d1)
#17 0x7fbc00bddc71 in wl_event_loop_dispatch (/usr/lib64/libwayland-server.so.0+0xac71)
#18 0x7fbc07541e50 in KWayland::Server::Display::Private::dispatch() /home/jenkins/workspace/Administration/Dependency Build Plasma kf5-qt5 SUSEQt5.12/kwayland/src/server/display.cpp:148
#19 0x7fbc075432de in KWayland::Server::Display::dispatchEvents(int) /home/jenkins/workspace/Administration/Dependency Build Plasma kf5-qt5 SUSEQt5.12/kwayland/src/server/display.cpp:220
#20 0x7fbc0fe864ca in KWin::WaylandServer::dispatch() /home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/wayland_server.cpp:616
#21 0x451ce0 in KWin::WaylandTestApplication::~WaylandTestApplication() /home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/autotests/integration/kwin_wayland_test.cpp:91
#22 0x42faa1 in main /home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/autotests/integration/globalshortcuts_test.cpp:381
#23 0x7fbc04796bca in __libc_start_main (/lib64/libc.so.6+0x26bca)
#24 0x413ea9 in _start (/home/jenkins/workspace/Plasma/kwin/kf5-qt5 SUSEQt5.12/build/bin/testGlobalShortcuts+0x413ea9)
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D22821
2019-07-30 08:40:18 +00:00
|
|
|
destroyWorkspace();
|
|
|
|
|
2021-10-14 07:40:08 +00:00
|
|
|
destroyInputMethod();
|
2015-11-10 07:52:40 +00:00
|
|
|
destroyCompositor();
|
2021-09-27 10:02:24 +00:00
|
|
|
destroyInput();
|
2014-08-12 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationWayland::performStartup()
|
|
|
|
{
|
2017-09-30 13:09:06 +00:00
|
|
|
if (m_startXWayland) {
|
|
|
|
setOperationMode(OperationModeXwayland);
|
2022-02-02 03:35:13 +00:00
|
|
|
setXwaylandScale(config()->group("Xwayland").readEntry("Scale", 1.0));
|
2017-09-30 13:09:06 +00:00
|
|
|
}
|
2015-02-23 14:57:00 +00:00
|
|
|
// first load options - done internally by a different thread
|
|
|
|
createOptions();
|
2021-01-30 13:22:07 +00:00
|
|
|
|
2022-11-05 10:43:41 +00:00
|
|
|
if (!outputBackend()->initialize()) {
|
2021-01-30 13:22:07 +00:00
|
|
|
std::exit(1);
|
|
|
|
}
|
|
|
|
|
2015-02-20 13:57:06 +00:00
|
|
|
createInput();
|
2021-10-14 07:40:08 +00:00
|
|
|
createInputMethod();
|
2022-08-03 09:27:35 +00:00
|
|
|
createTabletModeManager();
|
2015-02-20 10:53:25 +00:00
|
|
|
|
2019-08-07 17:33:20 +00:00
|
|
|
WaylandCompositor::create();
|
2021-05-18 23:05:41 +00:00
|
|
|
|
2022-11-05 10:43:41 +00:00
|
|
|
connect(Compositor::self(), &Compositor::sceneCreated, outputBackend(), &OutputBackend::sceneInitialized);
|
2019-02-23 12:17:50 +00:00
|
|
|
connect(Compositor::self(), &Compositor::sceneCreated, this, &ApplicationWayland::continueStartupWithScene);
|
2015-02-20 10:53:25 +00:00
|
|
|
}
|
|
|
|
|
2021-05-18 23:05:41 +00:00
|
|
|
void ApplicationWayland::continueStartupWithScene()
|
2017-10-01 07:06:51 +00:00
|
|
|
{
|
2021-05-18 23:05:41 +00:00
|
|
|
disconnect(Compositor::self(), &Compositor::sceneCreated, this, &ApplicationWayland::continueStartupWithScene);
|
2019-02-23 12:17:50 +00:00
|
|
|
|
2020-07-07 09:45:55 +00:00
|
|
|
// Note that we start accepting client connections after creating the Workspace.
|
|
|
|
createWorkspace();
|
2022-07-23 12:39:17 +00:00
|
|
|
createColorManager();
|
2022-07-21 16:13:07 +00:00
|
|
|
createPlugins();
|
2020-07-07 09:45:55 +00:00
|
|
|
|
|
|
|
if (!waylandServer()->start()) {
|
|
|
|
qFatal("Failed to initialze the Wayland server, exiting now");
|
|
|
|
}
|
|
|
|
|
2019-02-23 12:17:50 +00:00
|
|
|
if (operationMode() == OperationModeWaylandOnly) {
|
|
|
|
finalizeStartup();
|
|
|
|
return;
|
|
|
|
}
|
2019-02-19 08:50:20 +00:00
|
|
|
|
2022-07-05 11:43:25 +00:00
|
|
|
m_xwayland = std::make_unique<Xwl::Xwayland>(this);
|
2022-03-12 14:09:57 +00:00
|
|
|
m_xwayland->xwaylandLauncher()->setListenFDs(m_xwaylandListenFds);
|
|
|
|
m_xwayland->xwaylandLauncher()->setDisplayName(m_xwaylandDisplay);
|
|
|
|
m_xwayland->xwaylandLauncher()->setXauthority(m_xwaylandXauthority);
|
2022-07-05 11:43:25 +00:00
|
|
|
connect(m_xwayland.get(), &Xwl::Xwayland::errorOccurred, this, &ApplicationWayland::finalizeStartup);
|
|
|
|
connect(m_xwayland.get(), &Xwl::Xwayland::started, this, &ApplicationWayland::finalizeStartup);
|
2020-07-20 08:07:08 +00:00
|
|
|
m_xwayland->start();
|
2017-09-21 16:27:47 +00:00
|
|
|
}
|
|
|
|
|
2021-05-18 23:05:41 +00:00
|
|
|
void ApplicationWayland::finalizeStartup()
|
|
|
|
{
|
|
|
|
if (m_xwayland) {
|
2022-07-05 11:43:25 +00:00
|
|
|
disconnect(m_xwayland.get(), &Xwl::Xwayland::errorOccurred, this, &ApplicationWayland::finalizeStartup);
|
|
|
|
disconnect(m_xwayland.get(), &Xwl::Xwayland::started, this, &ApplicationWayland::finalizeStartup);
|
2021-05-18 23:05:41 +00:00
|
|
|
}
|
|
|
|
startSession();
|
|
|
|
notifyStarted();
|
|
|
|
}
|
|
|
|
|
2020-12-23 00:41:47 +00:00
|
|
|
void ApplicationWayland::refreshSettings(const KConfigGroup &group, const QByteArrayList &names)
|
|
|
|
{
|
2022-06-08 13:45:28 +00:00
|
|
|
if (group.name() == "Wayland" && names.contains("InputMethod")) {
|
|
|
|
KDesktopFile file(group.readPathEntry("InputMethod", QString()));
|
2022-07-20 10:14:27 +00:00
|
|
|
kwinApp()->inputMethod()->setInputMethodCommand(file.desktopGroup().readEntry("Exec", QString()));
|
2020-12-23 00:41:47 +00:00
|
|
|
}
|
|
|
|
|
2022-06-08 13:45:28 +00:00
|
|
|
if (m_startXWayland && group.name() == "Xwayland" && names.contains("Scale")) {
|
|
|
|
setXwaylandScale(group.readEntry("Scale", 1.0));
|
|
|
|
}
|
2020-12-23 00:41:47 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 16:27:47 +00:00
|
|
|
void ApplicationWayland::startSession()
|
|
|
|
{
|
2022-05-28 14:38:53 +00:00
|
|
|
KSharedConfig::Ptr kwinSettings = kwinApp()->config();
|
|
|
|
m_settingsWatcher = KConfigWatcher::create(kwinSettings);
|
|
|
|
connect(m_settingsWatcher.data(), &KConfigWatcher::configChanged, this, &ApplicationWayland::refreshSettings);
|
|
|
|
|
2015-06-13 02:06:12 +00:00
|
|
|
if (!m_inputMethodServerToStart.isEmpty()) {
|
2022-07-20 10:14:27 +00:00
|
|
|
kwinApp()->inputMethod()->setInputMethodCommand(m_inputMethodServerToStart);
|
2020-12-23 00:41:47 +00:00
|
|
|
} else {
|
2021-04-27 19:20:20 +00:00
|
|
|
refreshSettings(kwinSettings->group("Wayland"), {"InputMethod"});
|
2015-06-13 02:06:12 +00:00
|
|
|
}
|
|
|
|
|
2015-11-19 08:16:23 +00:00
|
|
|
// start session
|
|
|
|
if (!m_sessionArgument.isEmpty()) {
|
2020-04-28 12:45:34 +00:00
|
|
|
QStringList arguments = KShell::splitArgs(m_sessionArgument);
|
|
|
|
if (!arguments.isEmpty()) {
|
|
|
|
QString program = arguments.takeFirst();
|
2022-01-10 20:30:37 +00:00
|
|
|
QProcess *p = new QProcess(this);
|
2020-04-28 12:45:34 +00:00
|
|
|
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
|
|
|
p->setProcessEnvironment(processStartupEnvironment());
|
2022-03-23 10:13:38 +00:00
|
|
|
connect(p, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [p](int code, QProcess::ExitStatus status) {
|
2020-04-28 12:45:34 +00:00
|
|
|
p->deleteLater();
|
|
|
|
if (status == QProcess::CrashExit) {
|
|
|
|
qWarning() << "Session process has crashed";
|
|
|
|
QCoreApplication::exit(-1);
|
|
|
|
return;
|
|
|
|
}
|
2019-05-28 16:42:55 +00:00
|
|
|
|
2020-04-28 12:45:34 +00:00
|
|
|
if (code) {
|
|
|
|
qWarning() << "Session process exited with code" << code;
|
|
|
|
}
|
2019-05-28 16:42:55 +00:00
|
|
|
|
2020-04-28 12:45:34 +00:00
|
|
|
QCoreApplication::exit(code);
|
|
|
|
});
|
|
|
|
p->setProgram(program);
|
|
|
|
p->setArguments(arguments);
|
|
|
|
p->start();
|
|
|
|
} else {
|
|
|
|
qWarning("Failed to launch the session process: %s is an invalid command",
|
|
|
|
qPrintable(m_sessionArgument));
|
|
|
|
}
|
2015-11-19 08:16:23 +00:00
|
|
|
}
|
2015-04-21 09:21:28 +00:00
|
|
|
// start the applications passed to us as command line arguments
|
|
|
|
if (!m_applicationsToStart.isEmpty()) {
|
2022-10-31 19:02:23 +00:00
|
|
|
for (const QString &application : std::as_const(m_applicationsToStart)) {
|
2020-04-28 12:45:34 +00:00
|
|
|
QStringList arguments = KShell::splitArgs(application);
|
|
|
|
if (arguments.isEmpty()) {
|
|
|
|
qWarning("Failed to launch application: %s is an invalid command",
|
|
|
|
qPrintable(application));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
QString program = arguments.takeFirst();
|
2015-04-21 09:21:28 +00:00
|
|
|
// note: this will kill the started process when we exit
|
|
|
|
// this is going to happen anyway as we are the wayland and X server the app connects to
|
2022-01-10 20:30:37 +00:00
|
|
|
QProcess *p = new QProcess(this);
|
2015-12-15 09:08:36 +00:00
|
|
|
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
2018-08-22 00:20:16 +00:00
|
|
|
p->setProcessEnvironment(processStartupEnvironment());
|
2020-04-28 12:45:34 +00:00
|
|
|
p->setProgram(program);
|
|
|
|
p->setArguments(arguments);
|
2020-03-15 19:59:29 +00:00
|
|
|
p->startDetached();
|
|
|
|
p->deleteLater();
|
2015-04-21 09:21:28 +00:00
|
|
|
}
|
|
|
|
}
|
2014-08-12 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2022-08-03 10:31:27 +00:00
|
|
|
XwaylandInterface *ApplicationWayland::xwayland() const
|
|
|
|
{
|
|
|
|
return m_xwayland.get();
|
|
|
|
}
|
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
} // namespace
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
int main(int argc, char *argv[])
|
2014-08-12 07:08:48 +00:00
|
|
|
{
|
|
|
|
KWin::Application::setupMalloc();
|
|
|
|
KWin::Application::setupLocalizedString();
|
2017-09-10 10:05:29 +00:00
|
|
|
KWin::gainRealTime();
|
2014-08-12 07:08:48 +00:00
|
|
|
|
2016-11-18 09:02:04 +00:00
|
|
|
signal(SIGPIPE, SIG_IGN);
|
2014-08-13 11:13:44 +00:00
|
|
|
|
2022-05-15 13:22:35 +00:00
|
|
|
// It's easy to exceed the file descriptor limit because many things are backed using fds
|
|
|
|
// nowadays, e.g. dmabufs, shm buffers, etc. Bump the RLIMIT_NOFILE limit to handle that.
|
|
|
|
// Some apps may still use select(), so we reset the limit to its original value in fork().
|
|
|
|
if (KWin::bumpNofileLimit()) {
|
|
|
|
pthread_atfork(nullptr, nullptr, KWin::restoreNofileLimit);
|
|
|
|
}
|
|
|
|
|
2015-06-29 08:51:37 +00:00
|
|
|
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
|
|
|
|
|
2015-08-18 06:05:08 +00:00
|
|
|
// enforce our internal qpa plugin, unfortunately command line switch has precedence
|
|
|
|
setenv("QT_QPA_PLATFORM", "wayland-org.kde.kwin.qpa", true);
|
2015-03-17 09:31:18 +00:00
|
|
|
|
2015-04-17 16:13:39 +00:00
|
|
|
qunsetenv("QT_DEVICE_PIXEL_RATIO");
|
2015-07-10 06:57:56 +00:00
|
|
|
qputenv("QSG_RENDER_LOOP", "basic");
|
2019-01-11 22:48:04 +00:00
|
|
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
2014-08-12 07:08:48 +00:00
|
|
|
KWin::ApplicationWayland a(argc, argv);
|
|
|
|
a.setupTranslator();
|
2022-02-11 23:41:34 +00:00
|
|
|
// reset QT_QPA_PLATFORM so we don't propagate it to our children (e.g. apps launched from the overview effect)
|
|
|
|
qunsetenv("QT_QPA_PLATFORM");
|
2015-02-09 12:28:37 +00:00
|
|
|
|
2022-09-15 15:18:44 +00:00
|
|
|
KSignalHandler::self()->watchSignal(SIGTERM);
|
|
|
|
KSignalHandler::self()->watchSignal(SIGINT);
|
|
|
|
KSignalHandler::self()->watchSignal(SIGHUP);
|
|
|
|
QObject::connect(KSignalHandler::self(), &KSignalHandler::signalReceived,
|
|
|
|
&a, &QCoreApplication::exit);
|
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
KWin::Application::createAboutData();
|
|
|
|
|
2015-01-09 15:00:16 +00:00
|
|
|
QCommandLineOption xwaylandOption(QStringLiteral("xwayland"),
|
2015-02-09 12:40:01 +00:00
|
|
|
i18n("Start a rootless Xwayland server."));
|
2015-02-09 12:28:37 +00:00
|
|
|
QCommandLineOption waylandSocketOption(QStringList{QStringLiteral("s"), QStringLiteral("socket")},
|
|
|
|
i18n("Name of the Wayland socket to listen on. If not set \"wayland-0\" is used."),
|
|
|
|
QStringLiteral("socket"));
|
2015-03-19 07:29:34 +00:00
|
|
|
QCommandLineOption x11DisplayOption(QStringLiteral("x11-display"),
|
|
|
|
i18n("The X11 Display to use in windowed mode on platform X11."),
|
|
|
|
QStringLiteral("display"));
|
2015-03-23 11:45:21 +00:00
|
|
|
QCommandLineOption waylandDisplayOption(QStringLiteral("wayland-display"),
|
|
|
|
i18n("The Wayland Display to use in windowed mode on platform Wayland."),
|
|
|
|
QStringLiteral("display"));
|
2015-10-02 08:44:29 +00:00
|
|
|
QCommandLineOption virtualFbOption(QStringLiteral("virtual"), i18n("Render to a virtual framebuffer."));
|
2015-03-19 07:29:34 +00:00
|
|
|
QCommandLineOption widthOption(QStringLiteral("width"),
|
|
|
|
i18n("The width for windowed mode. Default width is 1024."),
|
|
|
|
QStringLiteral("width"));
|
|
|
|
widthOption.setDefaultValue(QString::number(1024));
|
|
|
|
QCommandLineOption heightOption(QStringLiteral("height"),
|
|
|
|
i18n("The height for windowed mode. Default height is 768."),
|
|
|
|
QStringLiteral("height"));
|
|
|
|
heightOption.setDefaultValue(QString::number(768));
|
2016-10-25 23:36:02 +00:00
|
|
|
|
|
|
|
QCommandLineOption scaleOption(QStringLiteral("scale"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("The scale for windowed mode. Default value is 1."),
|
|
|
|
QStringLiteral("scale"));
|
2016-10-25 23:36:02 +00:00
|
|
|
scaleOption.setDefaultValue(QString::number(1));
|
|
|
|
|
2015-11-24 12:11:29 +00:00
|
|
|
QCommandLineOption outputCountOption(QStringLiteral("output-count"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("The number of windows to open as outputs in windowed mode. Default value is 1"),
|
|
|
|
QStringLiteral("count"));
|
2015-11-24 12:11:29 +00:00
|
|
|
outputCountOption.setDefaultValue(QString::number(1));
|
2014-08-12 13:27:35 +00:00
|
|
|
|
2021-12-02 14:02:22 +00:00
|
|
|
QCommandLineOption waylandSocketFdOption(QStringLiteral("wayland-fd"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("Wayland socket to use for incoming connections. This can be combined with --socket to name the socket"),
|
|
|
|
QStringLiteral("wayland-fd"));
|
2020-11-17 18:09:28 +00:00
|
|
|
|
2021-07-28 10:03:10 +00:00
|
|
|
QCommandLineOption xwaylandListenFdOption(QStringLiteral("xwayland-fd"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("XWayland socket to use for Xwayland's incoming connections. This can be set multiple times"),
|
|
|
|
QStringLiteral("xwayland-fds"));
|
2021-07-28 10:03:10 +00:00
|
|
|
|
|
|
|
QCommandLineOption xwaylandDisplayOption(QStringLiteral("xwayland-display"),
|
|
|
|
i18n("Name of the xwayland display that has been pre-set up"),
|
|
|
|
"xwayland-display");
|
|
|
|
|
|
|
|
QCommandLineOption xwaylandXAuthorityOption(QStringLiteral("xwayland-xauthority"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("Name of the xauthority file "),
|
|
|
|
"xwayland-xauthority");
|
2021-07-28 10:03:10 +00:00
|
|
|
|
2021-01-30 00:37:13 +00:00
|
|
|
QCommandLineOption replaceOption(QStringLiteral("replace"),
|
2022-03-23 10:13:38 +00:00
|
|
|
i18n("Exits this instance so it can be restarted by kwin_wayland_wrapper."));
|
2021-01-30 00:37:13 +00:00
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
|
2022-09-08 22:18:12 +00:00
|
|
|
QCommandLineOption locale1Option(QStringLiteral("locale1"), i18n("Extract locale information from locale1 rather than the user's configuration"));
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
|
2014-08-12 07:08:48 +00:00
|
|
|
QCommandLineParser parser;
|
|
|
|
a.setupCommandLine(&parser);
|
2015-01-09 15:00:16 +00:00
|
|
|
parser.addOption(xwaylandOption);
|
2015-02-09 12:28:37 +00:00
|
|
|
parser.addOption(waylandSocketOption);
|
2020-11-17 18:09:28 +00:00
|
|
|
parser.addOption(waylandSocketFdOption);
|
2021-07-28 10:03:10 +00:00
|
|
|
parser.addOption(xwaylandListenFdOption);
|
|
|
|
parser.addOption(xwaylandDisplayOption);
|
|
|
|
parser.addOption(xwaylandXAuthorityOption);
|
2021-01-30 00:37:13 +00:00
|
|
|
parser.addOption(replaceOption);
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
parser.addOption(x11DisplayOption);
|
|
|
|
parser.addOption(waylandDisplayOption);
|
|
|
|
parser.addOption(virtualFbOption);
|
|
|
|
parser.addOption(widthOption);
|
|
|
|
parser.addOption(heightOption);
|
|
|
|
parser.addOption(scaleOption);
|
|
|
|
parser.addOption(outputCountOption);
|
|
|
|
parser.addOption(drmOption);
|
2022-09-08 22:18:12 +00:00
|
|
|
parser.addOption(locale1Option);
|
2015-06-13 02:06:12 +00:00
|
|
|
|
|
|
|
QCommandLineOption inputMethodOption(QStringLiteral("inputmethod"),
|
|
|
|
i18n("Input method that KWin starts."),
|
|
|
|
QStringLiteral("path/to/imserver"));
|
|
|
|
parser.addOption(inputMethodOption);
|
|
|
|
|
2022-02-28 18:58:35 +00:00
|
|
|
#if KWIN_BUILD_SCREENLOCKER
|
2015-11-05 13:09:23 +00:00
|
|
|
QCommandLineOption screenLockerOption(QStringLiteral("lockscreen"),
|
|
|
|
i18n("Starts the session in locked mode."));
|
|
|
|
parser.addOption(screenLockerOption);
|
|
|
|
|
2018-12-01 12:17:02 +00:00
|
|
|
QCommandLineOption noScreenLockerOption(QStringLiteral("no-lockscreen"),
|
|
|
|
i18n("Starts the session without lock screen support."));
|
|
|
|
parser.addOption(noScreenLockerOption);
|
2022-02-23 13:27:05 +00:00
|
|
|
#endif
|
2018-12-01 12:17:02 +00:00
|
|
|
|
2018-12-02 12:09:37 +00:00
|
|
|
QCommandLineOption noGlobalShortcutsOption(QStringLiteral("no-global-shortcuts"),
|
|
|
|
i18n("Starts the session without global shortcuts support."));
|
2019-02-01 14:29:04 +00:00
|
|
|
parser.addOption(noGlobalShortcutsOption);
|
2018-12-02 12:09:37 +00:00
|
|
|
|
2022-02-28 18:58:35 +00:00
|
|
|
#if KWIN_BUILD_ACTIVITIES
|
2021-03-05 12:52:58 +00:00
|
|
|
QCommandLineOption noActivitiesOption(QStringLiteral("no-kactivities"),
|
|
|
|
i18n("Disable KActivities integration."));
|
|
|
|
parser.addOption(noActivitiesOption);
|
|
|
|
#endif
|
|
|
|
|
2015-11-19 08:16:23 +00:00
|
|
|
QCommandLineOption exitWithSessionOption(QStringLiteral("exit-with-session"),
|
|
|
|
i18n("Exit after the session application, which is started by KWin, closed."),
|
|
|
|
QStringLiteral("/path/to/session"));
|
|
|
|
parser.addOption(exitWithSessionOption);
|
|
|
|
|
2015-04-21 09:21:28 +00:00
|
|
|
parser.addPositionalArgument(QStringLiteral("applications"),
|
|
|
|
i18n("Applications to start once Wayland and Xwayland server are started"),
|
|
|
|
QStringLiteral("[/path/to/application...]"));
|
2014-08-12 07:08:48 +00:00
|
|
|
|
|
|
|
parser.process(a);
|
|
|
|
a.processCommandLine(&parser);
|
|
|
|
|
2022-02-28 18:58:35 +00:00
|
|
|
#if KWIN_BUILD_ACTIVITIES
|
2021-03-05 12:52:58 +00:00
|
|
|
if (parser.isSet(noActivitiesOption)) {
|
|
|
|
a.setUseKActivities(false);
|
|
|
|
}
|
2015-11-24 08:01:46 +00:00
|
|
|
#endif
|
|
|
|
|
2021-01-30 00:37:13 +00:00
|
|
|
if (parser.isSet(replaceOption)) {
|
|
|
|
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/KWin"),
|
2022-03-23 10:13:38 +00:00
|
|
|
QStringLiteral("org.kde.KWin"), QStringLiteral("replace"));
|
2021-01-30 00:37:13 +00:00
|
|
|
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
|
|
|
|
return 0;
|
|
|
|
}
|
2015-10-02 07:31:47 +00:00
|
|
|
|
2015-11-19 08:16:23 +00:00
|
|
|
if (parser.isSet(exitWithSessionOption)) {
|
|
|
|
a.setSessionArgument(parser.value(exitWithSessionOption));
|
|
|
|
}
|
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
enum class BackendType {
|
|
|
|
Kms,
|
|
|
|
X11,
|
|
|
|
Wayland,
|
|
|
|
Virtual,
|
|
|
|
};
|
|
|
|
|
|
|
|
BackendType backendType;
|
2015-05-05 15:58:09 +00:00
|
|
|
QString pluginName;
|
|
|
|
QSize initialWindowSize;
|
2015-11-24 12:11:29 +00:00
|
|
|
int outputCount = 1;
|
2016-10-25 23:36:02 +00:00
|
|
|
qreal outputScale = 1;
|
2015-10-03 18:14:16 +00:00
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
// Decide what backend to use.
|
|
|
|
if (parser.isSet(drmOption)) {
|
|
|
|
backendType = BackendType::Kms;
|
|
|
|
} else if (parser.isSet(x11DisplayOption)) {
|
|
|
|
backendType = BackendType::X11;
|
|
|
|
} else if (parser.isSet(waylandDisplayOption)) {
|
|
|
|
backendType = BackendType::Wayland;
|
|
|
|
} else if (parser.isSet(virtualFbOption)) {
|
|
|
|
backendType = BackendType::Virtual;
|
|
|
|
} else {
|
|
|
|
if (qEnvironmentVariableIsSet("WAYLAND_DISPLAY")) {
|
2022-08-04 19:23:47 +00:00
|
|
|
qWarning("No backend specified, automatically choosing Wayland because WAYLAND_DISPLAY is set");
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
backendType = BackendType::Wayland;
|
|
|
|
} else if (qEnvironmentVariableIsSet("DISPLAY")) {
|
2022-08-04 19:23:47 +00:00
|
|
|
qWarning("No backend specified, automatically choosing X11 because DISPLAY is set");
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
backendType = BackendType::X11;
|
|
|
|
} else {
|
2022-08-04 19:23:47 +00:00
|
|
|
qWarning("No backend specified, automatically choosing drm");
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
backendType = BackendType::Kms;
|
2016-10-25 23:36:02 +00:00
|
|
|
}
|
2015-06-29 09:59:27 +00:00
|
|
|
}
|
|
|
|
|
2022-09-08 22:18:12 +00:00
|
|
|
if (parser.isSet(locale1Option)) {
|
|
|
|
a.setFollowLocale1(true);
|
|
|
|
}
|
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
bool ok = false;
|
|
|
|
const int width = parser.value(widthOption).toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
std::cerr << "FATAL ERROR incorrect value for width" << std::endl;
|
|
|
|
return 1;
|
2015-11-24 12:11:29 +00:00
|
|
|
}
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
const int height = parser.value(heightOption).toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
std::cerr << "FATAL ERROR incorrect value for height" << std::endl;
|
|
|
|
return 1;
|
2015-03-19 07:29:34 +00:00
|
|
|
}
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
const qreal scale = parser.value(scaleOption).toDouble(&ok);
|
|
|
|
if (!ok || scale <= 0) {
|
|
|
|
std::cerr << "FATAL ERROR incorrect value for scale" << std::endl;
|
|
|
|
return 1;
|
2015-10-02 08:44:29 +00:00
|
|
|
}
|
2015-05-05 15:58:09 +00:00
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
outputScale = scale;
|
|
|
|
initialWindowSize = QSize(width, height);
|
2015-06-29 09:59:27 +00:00
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
const int count = parser.value(outputCountOption).toInt(&ok);
|
|
|
|
if (ok) {
|
2022-11-12 14:25:23 +00:00
|
|
|
outputCount = std::max(1, count);
|
2015-05-05 15:58:09 +00:00
|
|
|
}
|
2015-08-20 10:54:23 +00:00
|
|
|
|
|
|
|
// TODO: create backend without having the server running
|
|
|
|
KWin::WaylandServer *server = KWin::WaylandServer::create(&a);
|
2015-11-05 13:09:23 +00:00
|
|
|
|
2020-03-17 05:48:05 +00:00
|
|
|
KWin::WaylandServer::InitializationFlags flags;
|
2022-02-28 18:58:35 +00:00
|
|
|
#if KWIN_BUILD_SCREENLOCKER
|
2015-11-05 13:09:23 +00:00
|
|
|
if (parser.isSet(screenLockerOption)) {
|
2020-03-17 05:48:05 +00:00
|
|
|
flags = KWin::WaylandServer::InitializationFlag::LockScreen;
|
2018-12-01 12:17:02 +00:00
|
|
|
} else if (parser.isSet(noScreenLockerOption)) {
|
2020-03-17 05:48:05 +00:00
|
|
|
flags = KWin::WaylandServer::InitializationFlag::NoLockScreenIntegration;
|
2015-11-05 13:09:23 +00:00
|
|
|
}
|
2022-02-23 13:27:05 +00:00
|
|
|
#endif
|
2018-12-02 12:09:37 +00:00
|
|
|
if (parser.isSet(noGlobalShortcutsOption)) {
|
2020-03-17 05:48:05 +00:00
|
|
|
flags |= KWin::WaylandServer::InitializationFlag::NoGlobalShortcuts;
|
2018-12-02 12:09:37 +00:00
|
|
|
}
|
2020-11-17 18:09:28 +00:00
|
|
|
|
2021-08-16 16:38:02 +00:00
|
|
|
const QString socketName = parser.value(waylandSocketOption);
|
2020-11-17 18:09:28 +00:00
|
|
|
if (parser.isSet(waylandSocketFdOption)) {
|
|
|
|
bool ok;
|
|
|
|
int fd = parser.value(waylandSocketFdOption).toInt(&ok);
|
2022-03-23 10:13:38 +00:00
|
|
|
if (ok) {
|
2020-11-17 18:09:28 +00:00
|
|
|
// make sure we don't leak this FD to children
|
|
|
|
fcntl(fd, F_SETFD, O_CLOEXEC);
|
2021-08-16 16:38:02 +00:00
|
|
|
server->display()->addSocketFileDescriptor(fd, socketName);
|
2020-11-17 18:09:28 +00:00
|
|
|
} else {
|
|
|
|
std::cerr << "FATAL ERROR: could not parse socket FD" << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
2021-08-16 16:38:02 +00:00
|
|
|
// socketName empty is fine here, addSocketName will automatically pick one
|
2020-11-17 18:09:28 +00:00
|
|
|
if (!server->display()->addSocketName(socketName)) {
|
|
|
|
std::cerr << "FATAL ERROR: could not add wayland socket " << qPrintable(socketName) << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!server->init(flags)) {
|
2016-07-04 07:09:03 +00:00
|
|
|
std::cerr << "FATAL ERROR: could not create Wayland server" << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
2015-08-20 10:54:23 +00:00
|
|
|
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
switch (backendType) {
|
|
|
|
case BackendType::Kms:
|
2022-07-23 13:22:54 +00:00
|
|
|
a.setSession(KWin::Session::create());
|
|
|
|
if (!a.session()) {
|
|
|
|
std::cerr << "FATAl ERROR: could not acquire a session" << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
2022-11-05 10:43:41 +00:00
|
|
|
a.setOutputBackend(std::make_unique<KWin::DrmBackend>(a.session()));
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
break;
|
2022-12-06 13:20:43 +00:00
|
|
|
case BackendType::Virtual: {
|
|
|
|
auto outputBackend = std::make_unique<KWin::VirtualBackend>();
|
|
|
|
for (int i = 0; i < outputCount; ++i) {
|
|
|
|
outputBackend->addOutput(initialWindowSize, outputScale);
|
|
|
|
}
|
2022-07-23 13:22:54 +00:00
|
|
|
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
2022-12-06 13:20:43 +00:00
|
|
|
a.setOutputBackend(std::move(outputBackend));
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
break;
|
2022-12-06 13:20:43 +00:00
|
|
|
}
|
2022-11-16 20:42:02 +00:00
|
|
|
case BackendType::X11: {
|
|
|
|
QString display = parser.value(x11DisplayOption);
|
|
|
|
if (display.isEmpty()) {
|
|
|
|
display = qgetenv("DISPLAY");
|
2022-11-10 19:07:54 +00:00
|
|
|
}
|
2022-07-23 13:22:54 +00:00
|
|
|
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
2022-11-16 20:42:02 +00:00
|
|
|
a.setOutputBackend(std::make_unique<KWin::X11WindowedBackend>(KWin::X11WindowedBackendOptions{
|
|
|
|
.display = display,
|
|
|
|
.outputCount = outputCount,
|
|
|
|
.outputScale = outputScale,
|
|
|
|
.outputSize = initialWindowSize,
|
|
|
|
}));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BackendType::Wayland: {
|
|
|
|
QString socketName = parser.value(waylandDisplayOption);
|
|
|
|
if (socketName.isEmpty()) {
|
|
|
|
socketName = qgetenv("WAYLAND_DISPLAY");
|
2022-11-10 19:07:54 +00:00
|
|
|
}
|
2022-11-16 20:42:02 +00:00
|
|
|
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
|
|
|
a.setOutputBackend(std::make_unique<KWin::Wayland::WaylandBackend>(KWin::Wayland::WaylandBackendOptions{
|
|
|
|
.socketName = socketName,
|
|
|
|
.outputCount = outputCount,
|
|
|
|
.outputScale = outputScale,
|
|
|
|
.outputSize = initialWindowSize,
|
|
|
|
}));
|
Make backends part of libkwin
Platform backends are provided as plugins. This is great for
extensibility, but the disadvantages of this design outweigh the
benefits.
The number of backends will be limited, it's safe to say that we will
have to maintain three backends for many years to come - kms/drm,
virtual, and wayland. The plugin system adds unnecessary complexity.
Startup logic is affected too. At the moment, platform backends provide
the session object, which is awkward as it starts adding dependencies
between backends. It will be nicer if the session is created depending
on the loaded session type.
In some cases, wayland code needs to talk to the backend directly, e.g.
for drm leasing, etc. With the plugin architecture it's hard to do that.
Not impossible though, we can approach it as in Qt 6, but it's still
harder than linking the code directly.
Of course, the main disadvantage of shipping backends in a lib is that
you will need to patch kwin if you need a custom platform, however such
cases will be rare.
Despite that disadvantage, I still think that it's a step in the right
direction where the goal is to have multi-purpose backends and other
reusable components of kwin.
The legacy X11 standalone platform is linked directly to kwin_x11
executable, while the remaining backends are linked to libkwin.
2022-07-22 14:22:09 +00:00
|
|
|
break;
|
2015-05-05 15:58:09 +00:00
|
|
|
}
|
2015-03-31 09:00:46 +00:00
|
|
|
}
|
2015-03-19 07:29:34 +00:00
|
|
|
|
2015-06-12 23:48:11 +00:00
|
|
|
QObject::connect(&a, &KWin::Application::workspaceCreated, server, &KWin::WaylandServer::initWorkspace);
|
2020-11-17 18:09:28 +00:00
|
|
|
if (!server->socketName().isEmpty()) {
|
|
|
|
environment.insert(QStringLiteral("WAYLAND_DISPLAY"), server->socketName());
|
2021-08-19 09:09:24 +00:00
|
|
|
qputenv("WAYLAND_DISPLAY", server->socketName().toUtf8());
|
2020-11-17 18:09:28 +00:00
|
|
|
}
|
2015-08-20 10:54:23 +00:00
|
|
|
a.setProcessStartupEnvironment(environment);
|
2021-07-28 10:03:10 +00:00
|
|
|
|
|
|
|
if (parser.isSet(xwaylandOption)) {
|
|
|
|
a.setStartXwayland(true);
|
|
|
|
|
|
|
|
if (parser.isSet(xwaylandListenFdOption)) {
|
|
|
|
const QStringList fdStrings = parser.values(xwaylandListenFdOption);
|
2022-03-23 10:13:38 +00:00
|
|
|
for (const QString &fdString : fdStrings) {
|
2021-07-28 10:03:10 +00:00
|
|
|
bool ok;
|
|
|
|
int fd = fdString.toInt(&ok);
|
2022-03-23 10:13:38 +00:00
|
|
|
if (ok) {
|
2021-07-28 10:03:10 +00:00
|
|
|
// make sure we don't leak this FD to children
|
|
|
|
fcntl(fd, F_SETFD, O_CLOEXEC);
|
|
|
|
a.addXwaylandSocketFileDescriptor(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parser.isSet(xwaylandDisplayOption)) {
|
|
|
|
a.setXwaylandDisplay(parser.value(xwaylandDisplayOption));
|
|
|
|
} else {
|
|
|
|
std::cerr << "Using xwayland-fd without xwayland-display is undefined" << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (parser.isSet(xwaylandXAuthorityOption)) {
|
|
|
|
a.setXwaylandXauthority(parser.value(xwaylandXAuthorityOption));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-21 09:21:28 +00:00
|
|
|
a.setApplicationsToStart(parser.positionalArguments());
|
2015-06-13 02:06:12 +00:00
|
|
|
a.setInputMethodServerToStart(parser.value(inputMethodOption));
|
2015-02-20 10:53:25 +00:00
|
|
|
a.start();
|
2014-08-12 07:08:48 +00:00
|
|
|
|
|
|
|
return a.exec();
|
|
|
|
}
|