feat: add KWin compositor integration with QML-free build

Add P0-disable-qml-quick.patch for building KWin without QML/Quick
dependencies. Update greeter scripts to prefer kwin_wayland. Enable
kwin in redbear-full config.
This commit is contained in:
2026-05-11 10:09:58 +01:00
parent 49f9cb2f29
commit b35977b654
4 changed files with 804 additions and 12 deletions
+2 -1
View File
@@ -117,7 +117,8 @@ icu = {}
konsole = {}
kglobalacceld = {}
# kwin = {} # Blocked: Qt6 Wayland plugin import error (QML gate)
# kwin (real KWin compositor, QML-free build via KWIN_BUILD_QML_UI=OFF)
kwin = {}
# Plasma + app packages — blocked on kirigami (QML gate)
# plasma-framework = {}
@@ -0,0 +1,764 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,7 +34,9 @@
include(KDEClangFormat)
include(KDEGitCommitHooks)
-include(ECMFindQmlModule)
+if(KWIN_BUILD_QML_UI)
+ include(ECMFindQmlModule)
+endif()
include(ECMInstallIcons)
include(ECMOptionalAddSubdirectory)
include(ECMConfiguredInstall)
@@ -42,7 +44,9 @@
include(ECMSetupQtPluginMacroNames)
include(ECMSetupVersion)
include(ECMQmlModule)
-include(ECMGenerateQmlTypes)
+if(KWIN_BUILD_QML_UI)
+ include(ECMGenerateQmlTypes)
+endif()
include(ECMDeprecationSettings)
option(KWIN_BUILD_DECORATIONS "Enable building of KWin decorations." ON)
@@ -54,18 +58,25 @@
option(KWIN_BUILD_X11_BACKEND "Enable building kwin_x11" ON)
option(KWIN_BUILD_GLOBALSHORTCUTS "Enable building of KWin with global shortcuts support" ON)
option(KWIN_BUILD_RUNNERS "Enable building of KWin with krunner support" ON)
-
-find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
+option(KWIN_BUILD_QML_UI "Enable building of KWin QML UI components (OSD, outline, scripted effects). Requires Qt6::Quick." ON)
+
+set(KWIN_QT6_REQUIRED_COMPONENTS
Concurrent
Core
Core5Compat
DBus
WaylandClient
Widgets
Sensors
Svg
+)
+if(KWIN_BUILD_QML_UI)
+ list(APPEND KWIN_QT6_REQUIRED_COMPONENTS Quick)
+endif()
+
+find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
+ ${KWIN_QT6_REQUIRED_COMPONENTS}
)
find_package(Qt6Test ${QT_MIN_VERSION} CONFIG QUIET)
@@ -144,18 +155,20 @@
)
add_feature_info("KF6DocTools" KF6DocTools_FOUND "Enable building documentation")
-find_package(KF6Kirigami ${KF6_MIN_VERSION} CONFIG)
-set_package_properties(KF6Kirigami PROPERTIES
- DESCRIPTION "A QtQuick based components set"
- PURPOSE "Required at runtime for several QML effects"
- TYPE RUNTIME
-)
-find_package(Plasma ${PROJECT_DEP_VERSION} CONFIG)
-set_package_properties(Plasma PROPERTIES
- DESCRIPTION "A QtQuick based components set"
- PURPOSE "Required at runtime for several QML effects"
- TYPE RUNTIME
-)
+if(KWIN_BUILD_QML_UI)
+ find_package(KF6Kirigami ${KF6_MIN_VERSION} CONFIG)
+ set_package_properties(KF6Kirigami PROPERTIES
+ DESCRIPTION "A QtQuick based components set"
+ PURPOSE "Required at runtime for several QML effects"
+ TYPE RUNTIME
+ )
+ find_package(Plasma ${PROJECT_DEP_VERSION} CONFIG)
+ set_package_properties(Plasma PROPERTIES
+ DESCRIPTION "A QtQuick based components set"
+ PURPOSE "Required at runtime for several QML effects"
+ TYPE RUNTIME
+ )
+endif()
find_package(KDecoration3 ${PROJECT_DEP_VERSION} CONFIG REQUIRED)
@@ -415,14 +428,16 @@
)
endif()
-ecm_find_qmlmodule(QtQuick 2.3)
-ecm_find_qmlmodule(QtQuick.Controls 2.15)
-ecm_find_qmlmodule(QtQuick.Layouts 1.3)
-ecm_find_qmlmodule(QtQuick.Window 2.1)
-ecm_find_qmlmodule(QtMultimedia 5.0)
-ecm_find_qmlmodule(org.kde.kquickcontrolsaddons 2.0)
-ecm_find_qmlmodule(org.kde.plasma.core 2.0)
-ecm_find_qmlmodule(org.kde.plasma.components 2.0)
+if(KWIN_BUILD_QML_UI)
+ ecm_find_qmlmodule(QtQuick 2.3)
+ ecm_find_qmlmodule(QtQuick.Controls 2.15)
+ ecm_find_qmlmodule(QtQuick.Layouts 1.3)
+ ecm_find_qmlmodule(QtQuick.Window 2.1)
+ ecm_find_qmlmodule(QtMultimedia 5.0)
+ ecm_find_qmlmodule(org.kde.kquickcontrolsaddons 2.0)
+ ecm_find_qmlmodule(org.kde.plasma.core 2.0)
+ ecm_find_qmlmodule(org.kde.plasma.components 2.0)
+endif()
cmake_dependent_option(KWIN_BUILD_ACTIVITIES "Enable building of KWin with kactivities support" ON "PlasmaActivities_FOUND" OFF)
cmake_dependent_option(KWIN_BUILD_EIS "Enable building KWin with libeis support" ON "Libeis-1.0_FOUND" OFF)
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -16,7 +16,26 @@
target_link_libraries(KWinEffectsInterface Qt::DBus)
add_subdirectory(helpers)
-add_subdirectory(qml)
+if(KWIN_BUILD_QML_UI)
+ add_subdirectory(qml)
+endif()
+
+set(kwin_qml_ui_effect_sources)
+set(kwin_qml_ui_scripting_sources)
+if(KWIN_BUILD_QML_UI)
+ list(APPEND kwin_qml_ui_effect_sources
+ effect/effectframe.cpp
+ effect/offscreenquickview.cpp
+ effect/quickeffect.cpp
+ )
+ list(APPEND kwin_qml_ui_scripting_sources
+ scripting/desktopbackgrounditem.cpp
+ scripting/gesturehandler.cpp
+ scripting/scriptedquicksceneeffect.cpp
+ scripting/shortcuthandler.cpp
+ scripting/windowthumbnailitem.cpp
+ )
+endif()
if (KWIN_BUILD_KCMS)
add_subdirectory(kcms)
@@ -87,15 +106,13 @@
effect/anidata.cpp
effect/animationeffect.cpp
effect/effect.cpp
- effect/effectframe.cpp
effect/effecthandler.cpp
effect/effectloader.cpp
effect/effecttogglablestate.cpp
effect/effectwindow.cpp
effect/logging.cpp
effect/offscreeneffect.cpp
- effect/offscreenquickview.cpp
- effect/quickeffect.cpp
+ ${kwin_qml_ui_effect_sources}
effect/timeline.cpp
focuschain.cpp
ftrace.cpp
@@ -183,19 +200,15 @@
scene/workspacescene_qpainter.cpp
screenedge.cpp
scripting/dbuscall.cpp
- scripting/desktopbackgrounditem.cpp
- scripting/gesturehandler.cpp
+ ${kwin_qml_ui_scripting_sources}
scripting/screenedgehandler.cpp
scripting/scriptedeffect.cpp
- scripting/scriptedquicksceneeffect.cpp
scripting/scripting.cpp
scripting/scripting_logging.cpp
scripting/scriptingutils.cpp
- scripting/shortcuthandler.cpp
scripting/tilemodel.cpp
scripting/virtualdesktopmodel.cpp
scripting/windowmodel.cpp
- scripting/windowthumbnailitem.cpp
scripting/workspace_wrapper.cpp
shadow.cpp
sm.cpp
@@ -227,7 +240,6 @@
target_link_libraries(kwin
PUBLIC
Qt::DBus
- Qt::Quick
Qt::Widgets
Wayland::Server
KF6::ConfigCore
@@ -243,11 +255,9 @@
KF6::ColorScheme
KF6::ConfigGui
- KF6::ConfigQml
KF6::Crash
KF6::GlobalAccel
KF6::I18n
- KF6::I18nQml
KF6::Package
KF6::Service
@@ -263,6 +273,15 @@
lcms2::lcms2
PkgConfig::libdisplayinfo
)
+
+if(KWIN_BUILD_QML_UI)
+ target_link_libraries(kwin
+ PRIVATE
+ Qt::Quick
+ KF6::ConfigQml
+ KF6::I18nQml
+ )
+endif()
if (TARGET K::KGlobalAccelD)
target_link_libraries(kwin PRIVATE K::KGlobalAccelD)
@@ -617,11 +636,16 @@
effect/effectwindow.h
effect/globals.h
effect/offscreeneffect.h
- effect/offscreenquickview.h
- effect/quickeffect.h
effect/timeline.h
effect/xcb.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kwin/effect COMPONENT Devel)
+
+if(KWIN_BUILD_QML_UI)
+ install(FILES
+ effect/offscreenquickview.h
+ effect/quickeffect.h
+ DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kwin/effect COMPONENT Devel)
+endif()
install(FILES
opengl/abstract_opengl_context_attribute_builder.h
--- a/src/config-kwin.h.cmake
+++ b/src/config-kwin.h.cmake
@@ -10,6 +10,7 @@
#cmakedefine01 KWIN_BUILD_TABBOX
#cmakedefine01 KWIN_BUILD_ACTIVITIES
#cmakedefine01 KWIN_BUILD_GLOBALSHORTCUTS
+#cmakedefine01 KWIN_BUILD_QML_UI
#cmakedefine01 KWIN_BUILD_X11
constexpr QLatin1String KWIN_CONFIG("kwinrc");
constexpr QLatin1String KWIN_VERSION_STRING("${PROJECT_VERSION}");
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -53,7 +53,9 @@
#include <KLocalizedString>
// Qt
#include <QCommandLineParser>
+#if KWIN_BUILD_QML_UI
#include <QQuickWindow>
+#endif
#if KWIN_BUILD_X11
#include <private/qtx11extras_p.h>
#endif
@@ -245,7 +247,9 @@
void Application::createWorkspace()
{
// we want all QQuickWindows with an alpha buffer, do here as Workspace might create QQuickWindows
+#if KWIN_BUILD_QML_UI
QQuickWindow::setDefaultAlphaBuffer(true);
+#endif
// This tries to detect compositing options and can use GLX. GLX problems
// (X errors) shouldn't cause kwin to abort, so this is out of the
@@ -357,9 +361,13 @@
std::unique_ptr<OutlineVisual> Application::createOutline(Outline *outline)
{
+#if KWIN_BUILD_QML_UI
if (Compositor::compositing()) {
return std::make_unique<CompositedOutlineVisual>(outline);
}
+#else
+ Q_UNUSED(outline)
+#endif
return nullptr;
}
--- a/src/compositor_wayland.cpp
+++ b/src/compositor_wayland.cpp
@@ -35,7 +35,9 @@
#include <KNotification>
#endif
#include <KLocalizedString>
+#if KWIN_BUILD_QML_UI
#include <QQuickWindow>
+#endif
namespace KWin
{
@@ -207,6 +209,7 @@
if (m_selectedCompositor == NoCompositing) {
m_selectedCompositor = m_backend->compositingType();
+#if KWIN_BUILD_QML_UI
switch (m_selectedCompositor) {
case NoCompositing:
break;
@@ -217,6 +220,7 @@
QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
break;
}
+#endif
}
createScene();
--- a/src/onscreennotification.cpp
+++ b/src/onscreennotification.cpp
@@ -13,10 +13,12 @@
#include "input_event_spy.h"
#include <QPropertyAnimation>
+#if KWIN_BUILD_QML_UI
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickWindow>
+#endif
#include <QStandardPaths>
#include <QTimer>
@@ -67,10 +69,12 @@
OnScreenNotification::~OnScreenNotification()
{
+#if KWIN_BUILD_QML_UI
if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
w->hide();
w->destroy();
}
+#endif
}
void OnScreenNotification::setConfig(KSharedConfigPtr config)
@@ -80,7 +84,11 @@
void OnScreenNotification::setEngine(QQmlEngine *engine)
{
+#if KWIN_BUILD_QML_UI
m_qmlEngine = engine;
+#else
+ Q_UNUSED(engine)
+#endif
}
bool OnScreenNotification::isVisible() const
@@ -142,9 +150,11 @@
void OnScreenNotification::show()
{
Q_ASSERT(m_visible);
+#if KWIN_BUILD_QML_UI
ensureQmlContext();
ensureQmlComponent();
createInputSpy();
+#endif
if (m_timer->interval() != 0) {
m_timer->start();
}
@@ -152,16 +162,19 @@
void OnScreenNotification::ensureQmlContext()
{
+#if KWIN_BUILD_QML_UI
Q_ASSERT(m_qmlEngine);
if (m_qmlContext) {
return;
}
m_qmlContext = std::make_unique<QQmlContext>(m_qmlEngine);
m_qmlContext->setContextProperty(QStringLiteral("osd"), this);
+#endif
}
void OnScreenNotification::ensureQmlComponent()
{
+#if KWIN_BUILD_QML_UI
Q_ASSERT(m_config);
Q_ASSERT(m_qmlEngine);
if (m_qmlComponent) {
@@ -179,10 +192,12 @@
} else {
m_qmlComponent.reset();
}
+#endif
}
void OnScreenNotification::createInputSpy()
{
+#if KWIN_BUILD_QML_UI
Q_ASSERT(!m_spy);
if (auto w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
m_spy = std::make_unique<OnScreenNotificationInputEventSpy>(this);
@@ -195,13 +210,16 @@
m_animation->setEasingCurve(QEasingCurve::InOutCubic);
}
}
+#endif
}
QRect OnScreenNotification::geometry() const
{
+#if KWIN_BUILD_QML_UI
if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
return w->geometry();
}
+#endif
return QRect();
}
@@ -220,9 +238,13 @@
void OnScreenNotification::setSkipCloseAnimation(bool skip)
{
+#if KWIN_BUILD_QML_UI
if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
w->setProperty("KWIN_SKIP_CLOSE_ANIMATION", skip);
}
+#else
+ Q_UNUSED(skip)
+#endif
}
} // namespace KWin
--- a/src/outline.cpp
+++ b/src/outline.cpp
@@ -18,10 +18,12 @@
#include <KConfigGroup>
// Qt
#include <QDebug>
+#if KWIN_BUILD_QML_UI
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickWindow>
+#endif
#include <QStandardPaths>
namespace KWin
@@ -153,14 +155,17 @@
void CompositedOutlineVisual::hide()
{
+#if KWIN_BUILD_QML_UI
if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
w->hide();
w->destroy();
}
+#endif
}
void CompositedOutlineVisual::show()
{
+#if KWIN_BUILD_QML_UI
if (!m_qmlContext) {
m_qmlContext = std::make_unique<QQmlContext>(Scripting::self()->qmlEngine());
m_qmlContext->setContextProperty(QStringLiteral("outline"), m_outline);
@@ -183,6 +188,7 @@
w->setProperty("__kwin_outline", true);
}
}
+#endif
}
} // namespace
--- a/src/osd.cpp
+++ b/src/osd.cpp
@@ -10,7 +10,9 @@
#include "scripting/scripting.h"
#include "workspace.h"
+#if KWIN_BUILD_QML_UI
#include <QQmlEngine>
+#endif
#include <QThread>
namespace KWin
@@ -22,7 +24,9 @@
{
auto osd = new OnScreenNotification(workspace());
osd->setConfig(kwinApp()->config());
+#if KWIN_BUILD_QML_UI
osd->setEngine(Scripting::self()->qmlEngine());
+#endif
return osd;
}
--- a/src/effect/effectloader.cpp
+++ b/src/effect/effectloader.cpp
@@ -15,7 +15,9 @@
#include "effect/effecthandler.h"
#include "plugin.h"
#include "scripting/scriptedeffect.h"
+#if KWIN_BUILD_QML_UI
#include "scripting/scriptedquicksceneeffect.h"
+#endif
#include "scripting/scripting.h"
#include "utils/common.h"
// KDE
@@ -26,8 +28,10 @@
#include <QDebug>
#include <QFutureWatcher>
#include <QPluginLoader>
+#if KWIN_BUILD_QML_UI
#include <QQmlComponent>
#include <QQmlEngine>
+#endif
#include <QStaticPlugin>
#include <QStringList>
#include <QtConcurrentRun>
@@ -131,7 +135,12 @@
if (api == QLatin1String("javascript")) {
return loadJavascriptEffect(effect);
} else if (api == QLatin1String("declarativescript")) {
+#if KWIN_BUILD_QML_UI
return loadDeclarativeEffect(effect);
+#else
+ qCDebug(KWIN_CORE) << "Skipping declarative effect because KWIN_BUILD_QML_UI is OFF:" << name;
+ return false;
+#endif
} else {
qCWarning(KWIN_CORE, "Failed to load %s effect: invalid X-Plasma-API field: %s. "
"Available options are javascript, and declarativescript", qPrintable(name), qPrintable(api));
@@ -165,6 +174,10 @@
bool ScriptedEffectLoader::loadDeclarativeEffect(const KPluginMetaData &metadata)
{
+#if !KWIN_BUILD_QML_UI
+ Q_UNUSED(metadata)
+ return false;
+#else
const QString name = metadata.pluginId();
const QString scriptFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QLatin1String("kwin/effects/") + name + QLatin1String("/contents/ui/main.qml"));
@@ -199,6 +212,7 @@
Q_EMIT effectLoaded(effect, name);
m_loadedEffects << name;
return true;
+#endif
}
void ScriptedEffectLoader::queryAndLoadAll()
--- a/src/effect/offscreenquickview.cpp
+++ b/src/effect/offscreenquickview.cpp
@@ -8,6 +8,9 @@
*/
#include "effect/offscreenquickview.h"
+#include "config-kwin.h"
+
+#if KWIN_BUILD_QML_UI
#include "effect/effecthandler.h"
#include "logging_p.h"
@@ -643,3 +646,4 @@
} // namespace KWin
#include "moc_offscreenquickview.cpp"
+#endif
--- a/src/effect/quickeffect.cpp
+++ b/src/effect/quickeffect.cpp
@@ -5,6 +5,9 @@
*/
#include "effect/quickeffect.h"
+#include "config-kwin.h"
+
+#if KWIN_BUILD_QML_UI
#include "core/output.h"
#include "effect/effecthandler.h"
@@ -629,3 +632,4 @@
} // namespace KWin
#include "moc_quickeffect.cpp"
+#endif
--- a/src/scripting/scriptedquicksceneeffect.cpp
+++ b/src/scripting/scriptedquicksceneeffect.cpp
@@ -5,6 +5,9 @@
*/
#include "scripting/scriptedquicksceneeffect.h"
+#include "config-kwin.h"
+
+#if KWIN_BUILD_QML_UI
#include "main.h"
#include <KConfigGroup>
@@ -130,3 +133,4 @@
} // namespace KWin
#include "moc_scriptedquicksceneeffect.cpp"
+#endif
--- a/src/scripting/scripting.cpp
+++ b/src/scripting/scripting.cpp
@@ -12,17 +12,19 @@
#include "scripting.h"
// own
#include "dbuscall.h"
+#if KWIN_BUILD_QML_UI
#include "desktopbackgrounditem.h"
#include "effect/quickeffect.h"
#include "gesturehandler.h"
+#include "scriptedquicksceneeffect.h"
+#include "shortcuthandler.h"
+#include "windowthumbnailitem.h"
+#endif
#include "screenedgehandler.h"
-#include "scriptedquicksceneeffect.h"
#include "scripting_logging.h"
#include "scriptingutils.h"
-#include "shortcuthandler.h"
#include "virtualdesktopmodel.h"
#include "windowmodel.h"
-#include "windowthumbnailitem.h"
#include "workspace_wrapper.h"
#include "core/output.h"
@@ -35,10 +37,14 @@
#include "workspace.h"
// KDE
#include <KConfigGroup>
+#if KWIN_BUILD_QML_UI
#include <KConfigPropertyMap>
+#endif
#include <KGlobalAccel>
#include <KLocalizedContext>
+#if KWIN_BUILD_QML_UI
#include <KLocalizedQmlContext>
+#endif
#include <KPackage/PackageLoader>
// Qt
#include <QDBusConnection>
@@ -46,10 +52,12 @@
#include <QDebug>
#include <QFutureWatcher>
#include <QMenu>
+#if KWIN_BUILD_QML_UI
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlExpression>
#include <QQuickWindow>
+#endif
#include <QSettings>
#include <QStandardPaths>
#include <QtConcurrentRun>
@@ -561,6 +569,7 @@
return menu->menuAction();
}
+#if KWIN_BUILD_QML_UI
KWin::DeclarativeScript::DeclarativeScript(int id, QString scriptName, QString pluginName, QObject *parent)
: AbstractScript(id, scriptName, pluginName, parent)
, m_context(new QQmlContext(Scripting::self()->declarativeScriptSharedContext(), this))
@@ -598,6 +607,7 @@
}
setRunning(true);
}
+#endif
KWin::JSEngineGlobalMethodsWrapper::JSEngineGlobalMethodsWrapper(KWin::DeclarativeScript *parent)
: QObject(parent)
@@ -626,12 +636,19 @@
KWin::Scripting::Scripting(QObject *parent)
: QObject(parent)
, m_scriptsLock(new QRecursiveMutex)
+#if KWIN_BUILD_QML_UI
, m_qmlEngine(new QQmlEngine(this))
, m_declarativeScriptSharedContext(new QQmlContext(m_qmlEngine, this))
+#else
+ , m_qmlEngine(nullptr)
+ , m_declarativeScriptSharedContext(nullptr)
+#endif
, m_workspaceWrapper(new QtScriptWorkspaceWrapper(this))
{
+#if KWIN_BUILD_QML_UI
m_qmlEngine->setProperty("_kirigamiTheme", QStringLiteral("KirigamiPlasmaStyle"));
m_qmlEngine->rootContext()->setContextObject(new KLocalizedQmlContext(m_qmlEngine));
+#endif
init();
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Scripting"), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportScriptableInvokables);
connect(Workspace::self(), &Workspace::configChanged, this, &Scripting::start);
@@ -644,6 +661,7 @@
qRegisterMetaType<QList<KWin::Window *>>();
qRegisterMetaType<QList<KWin::VirtualDesktop *>>();
+#if KWIN_BUILD_QML_UI
qmlRegisterType<DesktopBackgroundItem>("org.kde.kwin", 3, 0, "DesktopBackground");
qmlRegisterType<WindowThumbnailItem>("org.kde.kwin", 3, 0, "WindowThumbnail");
qmlRegisterType<DBusCall>("org.kde.kwin", 3, 0, "DBusCall");
@@ -671,6 +689,7 @@
// TODO: call the qml types as the C++ types?
qmlRegisterUncreatableType<KWin::CustomTile>("org.kde.kwin", 3, 0, "CustomTile", QStringLiteral("Cannot create objects of type Tile"));
qmlRegisterUncreatableType<KWin::Tile>("org.kde.kwin", 3, 0, "Tile", QStringLiteral("Cannot create objects of type AbstractTile"));
+#endif
}
void KWin::Scripting::start()
@@ -821,6 +840,7 @@
int KWin::Scripting::loadDeclarativeScript(const QString &filePath, const QString &pluginName)
{
+#if KWIN_BUILD_QML_UI
QMutexLocker locker(m_scriptsLock.get());
if (isScriptLoaded(pluginName)) {
return -1;
@@ -830,6 +850,11 @@
connect(script, &QObject::destroyed, this, &Scripting::scriptDestroyed);
scripts.append(script);
return id;
+#else
+ Q_UNUSED(filePath)
+ Q_UNUSED(pluginName)
+ return -1;
+#endif
}
KWin::Scripting::~Scripting()
--- a/src/scripting/workspace_wrapper.h
+++ b/src/scripting/workspace_wrapper.h
@@ -10,9 +10,12 @@
#pragma once
+#include "config-kwin.h"
#include "effect/globals.h"
#include <QObject>
+#if KWIN_BUILD_QML_UI
#include <QQmlListProperty>
+#endif
#include <QRect>
#include <QSize>
#include <QStringList>
@@ -406,6 +409,7 @@
explicit QtScriptWorkspaceWrapper(QObject *parent = nullptr);
};
+#if KWIN_BUILD_QML_UI
class DeclarativeScriptWorkspaceWrapper : public WorkspaceWrapper
{
Q_OBJECT
@@ -418,5 +422,6 @@
explicit DeclarativeScriptWorkspaceWrapper(QObject *parent = nullptr);
};
+#endif
}
--- a/src/scripting/workspace_wrapper.cpp
+++ b/src/scripting/workspace_wrapper.cpp
@@ -437,6 +437,7 @@
return workspace()->windows();
}
+#if KWIN_BUILD_QML_UI
QQmlListProperty<KWin::Window> DeclarativeScriptWorkspaceWrapper::windows()
{
return QQmlListProperty<KWin::Window>(this, nullptr, &DeclarativeScriptWorkspaceWrapper::countWindowList, &DeclarativeScriptWorkspaceWrapper::atWindowList);
@@ -456,6 +457,7 @@
: WorkspaceWrapper(parent)
{
}
+#endif
} // KWin
@@ -81,13 +81,18 @@ if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && command -v dbus-launch >/dev/null 2
eval "$(dbus-launch --sh-syntax)"
fi
if ! command -v redbear-compositor >/dev/null 2>&1; then
# Fall back to redbear-compositor (simpler Rust compositor)
if command -v /usr/bin/redbear-compositor >/dev/null 2>&1 || command -v redbear-compositor >/dev/null 2>&1; then
echo "redbear-greeter-compositor: redbear-compositor not found, using redbear-compositor" >&2
exec /usr/bin/redbear-compositor
fi
echo "redbear-greeter-compositor: redbear-compositor not found, and redbear-compositor not found either" >&2
# Prefer kwin_wayland (real KWin compositor). Fall back to redbear-compositor only if
# KWin is not installed (e.g. text-only target accidentally includes greeter).
COMPOSITOR=""
if command -v kwin_wayland >/dev/null 2>&1; then
COMPOSITOR="kwin_wayland"
elif command -v /usr/bin/kwin_wayland >/dev/null 2>&1; then
COMPOSITOR="/usr/bin/kwin_wayland"
elif command -v redbear-compositor >/dev/null 2>&1; then
COMPOSITOR="redbear-compositor"
echo "redbear-greeter-compositor: kwin_wayland not found, falling back to redbear-compositor" >&2
else
echo "redbear-greeter-compositor: no compositor found (need kwin_wayland or redbear-compositor)" >&2
exit 1
fi
@@ -102,9 +107,17 @@ fi
if wait_for_drm_devices "$desired_drm_devices"; then
export KWIN_DRM_DEVICES="${KWIN_DRM_DEVICES:-/scheme/drm/card0}"
echo "redbear-greeter-compositor: using DRM compositor backend (KWIN_DRM_DEVICES=${KWIN_DRM_DEVICES})" >&2
exec redbear-compositor --drm
if [ "$COMPOSITOR" = "kwin_wayland" ] || [ "$COMPOSITOR" = "/usr/bin/kwin_wayland" ]; then
exec "$COMPOSITOR" --drm
else
exec "$COMPOSITOR" --drm
fi
else
unset KWIN_DRM_DEVICES
echo "redbear-greeter-compositor: DRM device not ready after wait, using virtual compositor backend" >&2
exec redbear-compositor --virtual
if [ "$COMPOSITOR" = "kwin_wayland" ] || [ "$COMPOSITOR" = "/usr/bin/kwin_wayland" ]; then
exec "$COMPOSITOR" --virtual
else
exec "$COMPOSITOR" --virtual
fi
fi
@@ -231,6 +231,20 @@ launch_optional_component() {
fi
}
# Prefer kwin_wayland (real KWin compositor). Fall back to redbear-compositor.
COMPOSITOR=""
if command -v kwin_wayland >/dev/null 2>&1; then
COMPOSITOR="kwin_wayland"
elif command -v /usr/bin/kwin_wayland >/dev/null 2>&1; then
COMPOSITOR="/usr/bin/kwin_wayland"
elif command -v redbear-compositor >/dev/null 2>&1; then
COMPOSITOR="redbear-compositor"
echo "redbear-kde-session: kwin_wayland not found, falling back to redbear-compositor" >&2
else
echo "redbear-kde-session: no compositor found (need kwin_wayland or redbear-compositor)" >&2
exit 1
fi
kwin_args=()
if [ "$kwin_mode" = "drm" ]; then
kwin_args+=(--drm)
@@ -238,11 +252,11 @@ else
kwin_args+=(--virtual)
fi
redbear-compositor "${kwin_args[@]}" &
"$COMPOSITOR" "${kwin_args[@]}" &
kwin_pid=$!
if ! wait_for_wayland_socket; then
printf '%s\n' "redbear-kde-session: redbear-compositor failed to expose $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" >&2
printf '%s\n' "redbear-kde-session: $COMPOSITOR failed to expose $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" >&2
exit 1
fi