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.
This commit is contained in:
Vlad Zahorodnii 2022-07-22 17:22:09 +03:00
parent 0fbd5fa377
commit 045da603a4
32 changed files with 117 additions and 623 deletions

View file

@ -8,6 +8,7 @@
*/
#include "kwin_wayland_test.h"
#include "backends/virtual/virtual_backend.h"
#include "composite.h"
#include "effects.h"
#include "inputmethod.h"
@ -67,12 +68,7 @@ WaylandTestApplication::WaylandTestApplication(OperationMode mode, int &argc, ch
removeLibraryPath(ownPath);
addLibraryPath(ownPath);
const KPluginMetaData plugin = KPluginMetaData::findPluginById(QStringLiteral("org.kde.kwin.waylandbackends"), "KWinWaylandVirtualBackend");
if (!plugin.isValid()) {
quit();
return;
}
initPlatform(plugin);
setPlatform(std::make_unique<VirtualBackend>());
WaylandServer::create(this);
setProcessStartupEnvironment(QProcessEnvironment::systemEnvironment());
}

View file

@ -14,8 +14,6 @@
#include <QX11Info>
#endif
#include <KPluginMetaData>
#include "main.h"
#include "utils/common.h"
@ -38,20 +36,6 @@ X11TestApplication::X11TestApplication(int &argc, char **argv)
{
setX11Connection(QX11Info::connection());
setX11RootWindow(QX11Info::appRootWindow());
// move directory containing executable to front, so that KPluginMetaData::findPluginById prefers the plugins in
// the build dir over system installed ones
const auto ownPath = libraryPaths().last();
removeLibraryPath(ownPath);
addLibraryPath(ownPath);
const KPluginMetaData plugin = KPluginMetaData::findPluginById(QStringLiteral("org.kde.kwin.platforms"),
QStringLiteral("KWinX11Platform"));
if (!plugin.isValid()) {
quit();
return;
}
initPlatform(plugin);
}
X11TestApplication::~X11TestApplication()

View file

@ -287,6 +287,7 @@ generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h)
add_executable(kwin_x11 main_x11.cpp)
target_link_libraries(kwin_x11
KWinX11Platform
kwin
KF5::Crash
)

View file

@ -1,4 +1,4 @@
set(DRM_SOURCES
target_sources(kwin PRIVATE
drm_backend.cpp
drm_object.cpp
drm_property.cpp
@ -31,13 +31,4 @@ set(DRM_SOURCES
egl_gbm_cursor_layer.cpp
)
add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES})
set_target_properties(KWinWaylandDrmBackend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm gbm::gbm PkgConfig::Libxcvt)
install(
TARGETS
KWinWaylandDrmBackend
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.waylandbackends/
)
target_link_libraries(kwin Libdrm::Libdrm gbm::gbm PkgConfig::Libxcvt)

View file

@ -1,92 +0,0 @@
{
"KPlugin": {
"Description": "Render through drm node.",
"Description[ar]": "التصيير عن طريق drm.",
"Description[az]": "DRM vasitəsi ilə formalaşdırmaq.",
"Description[bg]": "Рендериране през drm възел.",
"Description[ca@valencia]": "Renderitza mitjançant el node del DRM.",
"Description[ca]": "Renderitza mitjançant el node del DRM.",
"Description[da]": "Render igennem drm-knude.",
"Description[de]": "In DRM-Knoten rendern.",
"Description[el]": "Αποτύπωση μέσω λειτουργίας drm.",
"Description[en_GB]": "Render through drm node.",
"Description[es]": "Renderizar a través del nodo DRM.",
"Description[et]": "Renderdamine drm režiimis.",
"Description[eu]": "Errendatu DRM-korapilunea erabiliz.",
"Description[fi]": "Hahmonna DRM-solmun läpi.",
"Description[fr]": "Rendre par le biais d'un nœud de rendu « DRM ».",
"Description[gl]": "Renderizar a través dun nodo de DRM.",
"Description[hu]": "Renderelés drm node-on.",
"Description[ia]": "Render a transverso nodo drm.",
"Description[id]": "Render melalui simpul drm.",
"Description[it]": "Resa tramite nodo drm.",
"Description[ko]": "DRM 노드로 렌더링합니다.",
"Description[lt]": "Atvaizduoti per drm veikseną.",
"Description[nl]": "Via drm-node renderen.",
"Description[nn]": "Teikn opp gjennom drm-node.",
"Description[pa]": "ਡੀਆਰਐਮ ਨੋਡ ਰਾਹੀਂ ਰੈਂਡਰ।",
"Description[pl]": "Wyświetlaj przez węzeł drm.",
"Description[pt]": "Desenhar através de um nó DRM.",
"Description[pt_BR]": "Renderizar pelo nó de DRM.",
"Description[ro]": "Randează prin nod DRM.",
"Description[ru]": "Отрисовка через DRM",
"Description[sk]": "Renderovať cez režim drm.",
"Description[sl]": "Izriši preko vozlišča drm.",
"Description[sr@ijekavian]": "Рендеровање кроз ДРМ чвор.",
"Description[sr@ijekavianlatin]": "Renderovanje kroz DRM čvor.",
"Description[sr@latin]": "Renderovanje kroz DRM čvor.",
"Description[sr]": "Рендеровање кроз ДРМ чвор.",
"Description[sv]": "Återge via DRM-nod.",
"Description[tr]": "Drm düğümü aracılığıyla gerçekle.",
"Description[uk]": "Обробляти через вузол DRM.",
"Description[vi]": "Kết xuất qua nút drm.",
"Description[x-test]": "xxRender through drm node.xx",
"Description[zh_CN]": "通过 drm 节点渲染。",
"Description[zh_TW]": "透過 drm 節點成像。",
"Id": "KWinWaylandDrmBackend",
"Name": "drm",
"Name[ar]": "drm",
"Name[az]": "drm",
"Name[bg]": "drm",
"Name[ca@valencia]": "DRM",
"Name[ca]": "DRM",
"Name[cs]": "drm",
"Name[da]": "drm",
"Name[de]": "DRM",
"Name[el]": "drm",
"Name[en_GB]": "drm",
"Name[es]": "drm",
"Name[et]": "drm",
"Name[eu]": "DRM",
"Name[fi]": "drm",
"Name[fr]": "drm",
"Name[gl]": "drm",
"Name[hu]": "drm",
"Name[ia]": "drm",
"Name[id]": "drm",
"Name[it]": "drm",
"Name[ko]": "drm",
"Name[lt]": "drm",
"Name[nl]": "drm",
"Name[nn]": "drm",
"Name[pa]": "ਡੀਆਰਐਮ",
"Name[pl]": "drm",
"Name[pt]": "DRM",
"Name[pt_BR]": "drm",
"Name[ro]": "drm",
"Name[ru]": "drm",
"Name[sk]": "drm",
"Name[sl]": "drm",
"Name[sr@ijekavian]": "ДРМ",
"Name[sr@ijekavianlatin]": "DRM",
"Name[sr@latin]": "DRM",
"Name[sr]": "ДРМ",
"Name[sv]": "DRM",
"Name[tr]": "drm",
"Name[uk]": "drm",
"Name[vi]": "drm",
"Name[x-test]": "xxdrmxx",
"Name[zh_CN]": "drm",
"Name[zh_TW]": "drm"
}
}

View file

@ -37,8 +37,7 @@ class DrmRenderBackend;
class KWIN_EXPORT DrmBackend : public Platform
{
Q_OBJECT
Q_INTERFACES(KWin::Platform)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Platform" FILE "drm.json")
public:
explicit DrmBackend(QObject *parent = nullptr);
~DrmBackend() override;

View file

@ -1,18 +1,7 @@
add_library(KWinWaylandVirtualBackend MODULE)
target_sources(KWinWaylandVirtualBackend PRIVATE
target_sources(kwin PRIVATE
egl_gbm_backend.cpp
logging.cpp
scene_qpainter_virtual_backend.cpp
virtual_backend.cpp
virtual_output.cpp
)
set_target_properties(KWinWaylandVirtualBackend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandVirtualBackend kwin)
install(
TARGETS
KWinWaylandVirtualBackend
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.waylandbackends/
)

View file

@ -10,10 +10,10 @@
// kwin
#include "basiceglsurfacetexture_internal.h"
#include "basiceglsurfacetexture_wayland.h"
#include "logging.h"
#include "softwarevsyncmonitor.h"
#include "virtual_backend.h"
#include "virtual_output.h"
#include <logging.h>
// kwin libs
#include <kwinglutils.h>

View file

@ -1,92 +0,0 @@
{
"KPlugin": {
"Description": "Render to a virtual framebuffer.",
"Description[ar]": "التصيير إلى framebuffer افتراضي",
"Description[az]": "Virtual çərçivə tamponunun formalaşdırılması.",
"Description[bg]": "Рендериране към виртуален framebuffer.",
"Description[ca@valencia]": "Renderitza a un «framebuffer» virtual.",
"Description[ca]": "Renderitza a un «framebuffer» virtual.",
"Description[da]": "Rendér til en virtuel framebuffer.",
"Description[de]": "In virtuellen Framebuffer rendern.",
"Description[el]": "Αποτύπωση σε εικονική ενδιάμεση μνήμη πλαισίων.",
"Description[en_GB]": "Render to a virtual framebuffer.",
"Description[es]": "Renderizar en un «framebuffer» virtual.",
"Description[et]": "Renderdamine virtuaalses kaadripuhvris.",
"Description[eu]": "Errendatu alegiazko framebuffer batera.",
"Description[fi]": "Hahmonna virtuaaliseen framebufferiin.",
"Description[fr]": "Rendre sur un « framebuffer » factice.",
"Description[gl]": "Renderizar nun búfer de fotogramas virtual.",
"Description[hu]": "Renderelés egy virtuális framebufferbe.",
"Description[ia]": "Render a un framebuffer virtual.",
"Description[id]": "Render untuk sebuah virtual framebuffer.",
"Description[it]": "Resa su un framebuffer virtuale.",
"Description[ko]": "가상 프레임버퍼에 렌더링합니다.",
"Description[lt]": "Atvaizduoti į virtualų vaizdų atnaujinimo buferį.",
"Description[nl]": "Naar een virtuele framebuffer renderen.",
"Description[nn]": "Teikn opp til virtuell biletbuffer.",
"Description[pa]": "ਵਰਚੁਅਲ ਫ਼ਰੇਮਬਫ਼ਰ ਲਈ ਰੈਂਡਰ।",
"Description[pl]": "Wyświetlaj w wirtualnym buforze klatek.",
"Description[pt]": "Desenhar num 'framebuffer' virtual.",
"Description[pt_BR]": "Renderizar no framebuffer virtual.",
"Description[ro]": "Randează pe framebuffer virtual.",
"Description[ru]": "Отрисовка в виртуальный фреймбуфер",
"Description[sk]": "Renderovať na virtuálny framebuffer.",
"Description[sl]": "Izriši v navidezni medpomnilnik sličic.",
"Description[sr@ijekavian]": "Рендеровање у виртуелни кадробафер.",
"Description[sr@ijekavianlatin]": "Renderovanje u virtuelni kadrobafer.",
"Description[sr@latin]": "Renderovanje u virtuelni kadrobafer.",
"Description[sr]": "Рендеровање у виртуелни кадробафер.",
"Description[sv]": "Återge i en virtuell rambuffer.",
"Description[tr]": "Sanal bir çerçeve tamponuna gerçekle.",
"Description[uk]": "Обробляти до віртуального буфера кадрів.",
"Description[vi]": "Kết xuất vào một framebuffer ảo.",
"Description[x-test]": "xxRender to a virtual framebuffer.xx",
"Description[zh_CN]": "渲染到虚拟帧缓冲区。",
"Description[zh_TW]": "成像到虛擬影格緩衝區。",
"Id": "KWinWaylandVirtualBackend",
"Name": "virtual",
"Name[ar]": "افتراضي",
"Name[az]": "virtual",
"Name[bg]": "виртуален",
"Name[ca@valencia]": "Virtual",
"Name[ca]": "Virtual",
"Name[cs]": "virtuální",
"Name[da]": "virtuel",
"Name[de]": "Virtuell",
"Name[el]": "εικονικό",
"Name[en_GB]": "virtual",
"Name[es]": "virtual",
"Name[et]": "virtual",
"Name[eu]": "alegiazkoa",
"Name[fi]": "virtual",
"Name[fr]": "virtual",
"Name[gl]": "virtual",
"Name[hu]": "virtuális",
"Name[ia]": "virtual",
"Name[id]": "virtual",
"Name[it]": "virtual",
"Name[ko]": "virtual",
"Name[lt]": "virtualus",
"Name[nl]": "virtueel",
"Name[nn]": "virtuell",
"Name[pa]": "ਵਰਚੁਅਲ",
"Name[pl]": "wirtualne",
"Name[pt]": "virtual",
"Name[pt_BR]": "virtual",
"Name[ro]": "virtual",
"Name[ru]": "virtual",
"Name[sk]": "virtual",
"Name[sl]": "navidezno",
"Name[sr@ijekavian]": "Виртуелно",
"Name[sr@ijekavianlatin]": "Virtuelno",
"Name[sr@latin]": "Virtuelno",
"Name[sr]": "Виртуелно",
"Name[sv]": "virtuell",
"Name[tr]": "sanal",
"Name[uk]": "virtual",
"Name[vi]": "ảo",
"Name[x-test]": "xxvirtualxx",
"Name[zh_CN]": "virtual",
"Name[zh_TW]": "虛擬"
}
}

View file

@ -25,8 +25,6 @@ class VirtualOutput;
class KWIN_EXPORT VirtualBackend : public Platform
{
Q_OBJECT
Q_INTERFACES(KWin::Platform)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Platform" FILE "virtual.json")
public:
VirtualBackend(QObject *parent = nullptr);

View file

@ -1,4 +1,4 @@
set(WAYLAND_BACKEND_SOURCES
target_sources(kwin PRIVATE
logging.cpp
scene_qpainter_wayland_backend.cpp
wayland_backend.cpp
@ -6,20 +6,10 @@ set(WAYLAND_BACKEND_SOURCES
)
if (HAVE_WAYLAND_EGL)
set(WAYLAND_BACKEND_SOURCES egl_wayland_backend.cpp ${WAYLAND_BACKEND_SOURCES})
target_sources(kwin PRIVATE egl_wayland_backend.cpp)
endif()
add_library(KWinWaylandWaylandBackend MODULE ${WAYLAND_BACKEND_SOURCES})
set_target_properties(KWinWaylandWaylandBackend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandWaylandBackend kwin KF5::WaylandClient)
target_link_libraries(kwin KF5::WaylandClient)
if (HAVE_WAYLAND_EGL)
target_link_libraries(KWinWaylandWaylandBackend Wayland::Egl gbm::gbm)
target_link_libraries(kwin Wayland::Egl gbm::gbm)
endif()
install(
TARGETS
KWinWaylandWaylandBackend
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.waylandbackends/
)

View file

@ -1,91 +0,0 @@
{
"KPlugin": {
"Description": "Render to a nested window on running Wayland compositor.",
"Description[ar]": "التصيير إلى نافذة متداخلة تعمل على مؤلف ويلاند.",
"Description[az]": "Wayland birləşdiricisində iç-içə keçmiş pəncərələri formalaşdırmaq.",
"Description[bg]": "Рендериране към вложен прозорец на Wayland",
"Description[ca@valencia]": "Renderitza a una finestra imbricada en un compositor Wayland en execució.",
"Description[ca]": "Renderitza a una finestra imbricada en un compositor Wayland en execució.",
"Description[da]": "Rendér til et indlejret vindue på kørende Wayland-compositor.",
"Description[de]": "In ein eingebettetes Fenster auf dem laufenden Wayland-Kompositor rendern.",
"Description[el]": "Αποτύπωση σε εμφωλευμένο παράθυρο κατά την εκτέλεση του συνθέτη Wayland.",
"Description[en_GB]": "Render to a nested window on running Wayland compositor.",
"Description[es]": "Renderizar en una ventana anidada en el compositor Wayland en ejecución.",
"Description[et]": "Renderdamine töötava Waylandi komposiitori pesastatud aknas.",
"Description[eu]": "Errendatu Wayland konposatzailean habiaratutako leiho batera.",
"Description[fi]": "Hahmonna sisäkkäiseen ikkunaan, jota hallitsee Wayland-koostin.",
"Description[fr]": "Rendre sur une fenêtre imbriquée sur un compositeur Wayland en cours de fonctionnement.",
"Description[gl]": "Renderizar unha xanela aniñada no compositor de Wayland en execución.",
"Description[hu]": "Renderelés egy Wayland kompozitoron futó beágyazott ablakba.",
"Description[ia]": "Render a un fenestra annidate sur compositor Wayland executante. ",
"Description[id]": "Render untuk sebuah window tersarang pada Wayland compositor yang berjalan.",
"Description[it]": "Resa in una finestra nidificata su compositore Wayland in esecuzione.",
"Description[ko]": "Wayland 컴포지터에서 실행 중인 창에 렌더링합니다.",
"Description[lt]": "Atvaizduoti į įdėtinį langą, veikiančiame Wayland kompozitoriuje.",
"Description[nl]": "Render naar een genest venster in een werkende Wayland-compositor.",
"Description[nn]": "Teikn opp til innebygd vindauge på køyrande Wayland-samansetjar.",
"Description[pl]": "Wyświetlaj w zagnieżdżonym oknie w kompozytorze Wayland.",
"Description[pt]": "Desenhar numa janela encadeada no compositor de Wayland em execução.",
"Description[pt_BR]": "Renderizar uma janela encadeada no compositor Wayland em execução.",
"Description[ro]": "Randează într-o fereastră imbricată pe compozitorul Wayland activ.",
"Description[ru]": "Отрисовка во вложенное окно компоновщика Wayland.",
"Description[sk]": "Renderovať na vnorené okno na bežiaci kompozítor Wayland.",
"Description[sl]": "Izriši v gnezdeno okno na upravljalniku skladnje Wayland.",
"Description[sr@ijekavian]": "Рендеровање у угнежђени прозор на вејланд слагачу.",
"Description[sr@ijekavianlatin]": "Renderovanje u ugnežđeni prozor na Wayland slagaču.",
"Description[sr@latin]": "Renderovanje u ugnežđeni prozor na Wayland slagaču.",
"Description[sr]": "Рендеровање у угнежђени прозор на вејланд слагачу.",
"Description[sv]": "Återge till ett nästlat fönster på Wayland-sammansättare som kör.",
"Description[tr]": "Wayland bileşikleştiricisi çalıştıran iç içe geçmiş bir pencerede gerçekle.",
"Description[uk]": "Обробляти у вкладене вікно запущеного засобу композиції Wayland.",
"Description[vi]": "Kết xuất vào một cửa sổ lồng trong trình kết hợp Wayland đang chạy.",
"Description[x-test]": "xxRender to a nested window on running Wayland compositor.xx",
"Description[zh_CN]": "渲染到运行在 Wayland 显示特效合成器中的嵌套窗口。",
"Description[zh_TW]": "成像到執行中的 Wayland 的巢狀視窗。",
"Id": "KWinWaylandWaylandBackend",
"Name": "wayland",
"Name[ar]": "ويلاند",
"Name[az]": "wayland",
"Name[bg]": "wayland",
"Name[ca@valencia]": "Wayland",
"Name[ca]": "Wayland",
"Name[cs]": "wayland",
"Name[da]": "wayland",
"Name[de]": "Wayland",
"Name[el]": "wayland",
"Name[en_GB]": "wayland",
"Name[es]": "wayland",
"Name[et]": "wayland",
"Name[eu]": "wayland",
"Name[fi]": "wayland",
"Name[fr]": "wayland",
"Name[gl]": "wayland",
"Name[hu]": "wayland",
"Name[ia]": "wayland",
"Name[id]": "wayland",
"Name[it]": "wayland",
"Name[ko]": "wayland",
"Name[lt]": "wayland",
"Name[nl]": "wayland",
"Name[nn]": "wayland",
"Name[pa]": "ਵੇਲੈਂਡ",
"Name[pl]": "wayland",
"Name[pt]": "Wayland",
"Name[pt_BR]": "wayland",
"Name[ro]": "wayland",
"Name[ru]": "wayland",
"Name[sk]": "wayland",
"Name[sl]": "wayland",
"Name[sr@ijekavian]": "Вејланд",
"Name[sr@ijekavianlatin]": "Wayland",
"Name[sr@latin]": "Wayland",
"Name[sr]": "Вејланд",
"Name[sv]": "Wayland",
"Name[tr]": "wayland",
"Name[uk]": "wayland",
"Name[vi]": "wayland",
"Name[x-test]": "xxwaylandxx",
"Name[zh_CN]": "wayland",
"Name[zh_TW]": "wayland"
}
}

View file

@ -247,8 +247,7 @@ private:
class KWIN_EXPORT WaylandBackend : public Platform
{
Q_OBJECT
Q_INTERFACES(KWin::Platform)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Platform" FILE "wayland.json")
public:
explicit WaylandBackend(QObject *parent = nullptr);
~WaylandBackend() override;

View file

@ -4,9 +4,8 @@ endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-int-to-void-pointer-cast")
endif()
add_library(eglx11common STATIC
target_sources(kwin PRIVATE
eglonxbackend.cpp
kwinxrenderutils.cpp
logging.cpp
)
target_link_libraries(eglx11common kwin)

View file

@ -14,12 +14,8 @@
#include "options.h"
#include "overlaywindow.h"
#include "platform.h"
#include "utils/common.h"
#include "utils/xcbutils.h"
// Qt
#include <QDebug>
#include <QLoggingCategory>
Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core", QtWarningMsg)
namespace KWin
{

View file

@ -15,9 +15,8 @@ set(X11PLATFORM_SOURCES
xfixes_cursor_event_filter.cpp
)
add_library(KWinX11Platform MODULE ${X11PLATFORM_SOURCES})
set_target_properties(KWinX11Platform PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.platforms/")
target_link_libraries(KWinX11Platform eglx11common kwin KF5::Crash X11::X11)
add_library(KWinX11Platform OBJECT ${X11PLATFORM_SOURCES})
target_link_libraries(KWinX11Platform kwin KF5::Crash X11::X11)
if (QT_MAJOR_VERSION EQUAL "5")
target_link_libraries(KWinX11Platform Qt::X11Extras)
endif()
@ -39,10 +38,3 @@ endif()
if (HAVE_DL_LIBRARY)
target_link_libraries(KWinX11Platform ${DL_LIBRARY})
endif()
install(
TARGETS
KWinX11Platform
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.platforms/
)

View file

@ -6,7 +6,7 @@
#pragma once
#include "eglonxbackend.h"
#include "../common/eglonxbackend.h"
#include "openglsurfacetexture_x11.h"
#include "outputlayer.h"
#include "utils/damagejournal.h"

View file

@ -20,6 +20,9 @@
#include "sgivideosyncvsyncmonitor.h"
#include "softwarevsyncmonitor.h"
#include "x11_platform.h"
#include "../common/kwinxrenderutils.h"
// kwin
#include "composite.h"
#include "options.h"
@ -34,7 +37,6 @@
#include <kwinglplatform.h>
#include <kwinglutils.h>
#include <kwinoffscreenquickview.h>
#include <kwinxrenderutils.h>
// Qt
#include <QDebug>
#include <QOpenGLContext>

View file

@ -10,7 +10,7 @@
// own
#include "non_composited_outline.h"
// KWin libs
#include <kwinxrenderutils.h>
#include "../common/kwinxrenderutils.h"
// xcb
#include <xcb/render.h>

View file

@ -1,90 +0,0 @@
{
"KPlugin": {
"Description": "Platform plugin for standalone x11 in kwin_x11.",
"Description[ar]": "ملحقة النظام لأكس ١١ المفرد في kwin_x11.",
"Description[az]": "Kwin_x11 -də müstəqil X11 üçün platforma əlavəsi.",
"Description[bg]": "Приставка за самостоятелна платформа на x11 в kwin_x11.",
"Description[ca@valencia]": "Connector de plataforma per a una X11 autònoma en el kwin_x11.",
"Description[ca]": "Connector de plataforma per a una X11 autònoma en el kwin_x11.",
"Description[da]": "Platform-plugin til standalone x11 i kwin_x11.",
"Description[de]": "Plattform-Modul für ein selbstständiges X11 in kwin_x11.",
"Description[el]": "Πρόσθετο πλατφόρμας για αυτόνομο x11 και kwin_x11.",
"Description[en_GB]": "Platform plugin for standalone x11 in kwin_x11.",
"Description[es]": "Complemento de Platform para X11 autónomo en kwin_x11.",
"Description[et]": "Autonoomse x11 platvormi plugin kwin_x11-s",
"Description[eu]": "Plataformaren plugina x11 autonomoarentzako, kwin_x11 barruan.",
"Description[fi]": "Alustaliitännäinen itsenäiselle x11:lle kwin_x11:ssä.",
"Description[fr]": "Module de plate-forme pour x11 autonomes, au sein de kwin_x11",
"Description[gl]": "Complemento de plataforma para x11 independente en kwin_x11.",
"Description[hu]": "Platformbővítmény önálló x11-hez a kwin_x11-ben.",
"Description[ia]": "Plugin de platteforma per singule X11 in kwin_x11.",
"Description[id]": "Plugin platform untuk standalone x11 dalam kwin_x11.",
"Description[it]": "Estensione di piattaforma per x11 autonomo in kwin_x11.",
"Description[ko]": "kwin_x11의 단독 X11 플러그인입니다.",
"Description[lt]": "Platformos priedas, skirtas kwin_x11 viduje esančiam, atskiram x11.",
"Description[nl]": "Platform plug-in voor alleenstaande x11 in kwin_x11.",
"Description[nn]": "Plattformtillegg for frittståande X11 i kwin_x11.",
"Description[pl]": "Wtyczka platformy dla wolnostojącego x11 w kwin_x11.",
"Description[pt]": "'Plugin' de plataformas para um X11 autónomo no X11 do KWin.",
"Description[pt_BR]": "Plugin de plataforma para um x11 independente no kwin_x11.",
"Description[ro]": "Extensie de platformă pentru x11 de sine stătător în kwin_x11.",
"Description[ru]": "Подключаемый модуль выделенного х11 в kwin_x11.",
"Description[sk]": "Platformový plugin pre standalone x11 v kwin_x11.",
"Description[sl]": "Okoljski vstavek za samostojni x11 v kwin_x11.",
"Description[sr@ijekavian]": "Платформски прикључак за самостални Икс11 у К‑вину.",
"Description[sr@ijekavianlatin]": "Platformski priključak za samostalni X11 u KWinu.",
"Description[sr@latin]": "Platformski priključak za samostalni X11 u KWinu.",
"Description[sr]": "Платформски прикључак за самостални Икс11 у К‑вину.",
"Description[sv]": "Plattforminsticksprogram för fristående X11 i kwin_x11",
"Description[tr]": "Kwin_x11'de bağımsız x11 için platform eklentisi.",
"Description[uk]": "Додаток платформи для окремого x11 у kwin_x11.",
"Description[vi]": "Phần cài cắm nền tảng cho x11 độc lập trong kwin_x11.",
"Description[x-test]": "xxPlatform plugin for standalone x11 in kwin_x11.xx",
"Description[zh_CN]": "kwin_x11 中的独立 x11 的平台插件",
"Description[zh_TW]": "在 kwin_x11 中供 standalone 的 x11 使用的平臺外掛程式。",
"Id": "KWinX11Platform",
"Name": "x11-standalone",
"Name[ar]": "اكس ١١ مفرد",
"Name[az]": "x11-standalone",
"Name[bg]": "x11-standalone",
"Name[ca@valencia]": "X11-autònoma",
"Name[ca]": "X11-autònoma",
"Name[da]": "x11-standalone",
"Name[de]": "Selbständiges-x11",
"Name[el]": "x11-αυτόνομος",
"Name[en_GB]": "x11-standalone",
"Name[es]": "x11-autónomo",
"Name[et]": "x11-standalone",
"Name[eu]": "x11-autonomoa",
"Name[fi]": "x11-standalone",
"Name[fr]": "x11-standalone",
"Name[gl]": "x11-independente",
"Name[hu]": "x11-standalone",
"Name[ia]": "x11-standalone",
"Name[id]": "x11-standalone",
"Name[it]": "X11-alone",
"Name[ko]": "x11-standalone",
"Name[lt]": "x11-atskiras",
"Name[nl]": "x11-alleenstaand",
"Name[nn]": "X11 frittståande",
"Name[pa]": "x11-ਸਟੈਡਅਲੋਨ",
"Name[pl]": "x11-wolnostojący",
"Name[pt]": "x11-autónomo",
"Name[pt_BR]": "x11-standalone",
"Name[ro]": "x11-standalone",
"Name[ru]": "x11-standalone",
"Name[sk]": "x11-standalone",
"Name[sl]": "x11-samostojno",
"Name[sr@ijekavian]": "Икс11 самостални",
"Name[sr@ijekavianlatin]": "X11 samostalni",
"Name[sr@latin]": "X11 samostalni",
"Name[sr]": "Икс11 самостални",
"Name[sv]": "Fristående X11",
"Name[tr]": "x11-standalone",
"Name[uk]": "x11-окремий",
"Name[vi]": "x11-độc-lập",
"Name[x-test]": "xxx11-standalonexx",
"Name[zh_CN]": "x11-standalone",
"Name[zh_TW]": "x11-standalone"
}
}

View file

@ -39,7 +39,7 @@
#include "workspace.h"
#include "x11_output.h"
#include "kwinxrenderutils.h"
#include "../common/kwinxrenderutils.h"
#include <KConfigGroup>
#include <KCrash>

View file

@ -30,8 +30,7 @@ class X11Output;
class KWIN_EXPORT X11StandalonePlatform : public Platform
{
Q_OBJECT
Q_INTERFACES(KWin::Platform)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Platform" FILE "x11.json")
public:
X11StandalonePlatform(QObject *parent = nullptr);
~X11StandalonePlatform() override;

View file

@ -7,7 +7,6 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "xinputintegration.h"
#include "ge_event_mem_mover.h"
#include "gestures.h"
#include "keyboard_input.h"
#include "logging.h"
@ -17,6 +16,8 @@
#include "screenedge.h"
#include "x11cursor.h"
#include "../common/ge_event_mem_mover.h"
#include "input.h"
#include "modifier_only_shortcuts.h"
#include "x11eventfilter.h"

View file

@ -1,4 +1,4 @@
set(X11BACKEND_SOURCES
target_sources(kwin PRIVATE
egl_x11_backend.cpp
logging.cpp
scene_qpainter_x11_backend.cpp
@ -6,16 +6,7 @@ set(X11BACKEND_SOURCES
x11windowed_output.cpp
)
add_library(KWinWaylandX11Backend MODULE ${X11BACKEND_SOURCES})
set_target_properties(KWinWaylandX11Backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandX11Backend eglx11common kwin X11::XCB X11::X11)
target_link_libraries(kwin X11::XCB X11::X11)
if (X11_Xi_FOUND)
target_link_libraries(KWinWaylandX11Backend X11::Xi)
target_link_libraries(kwin X11::Xi)
endif()
install(
TARGETS
KWinWaylandX11Backend
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.waylandbackends/
)

View file

@ -8,7 +8,7 @@
*/
#pragma once
#include "eglonxbackend.h"
#include "../common/eglonxbackend.h"
#include "kwinglutils.h"
#include "outputlayer.h"

View file

@ -7,6 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "x11windowed_backend.h"
#include "../common/kwinxrenderutils.h"
#include <config-kwin.h>
@ -18,7 +19,6 @@
#include "wayland_server.h"
#include "x11windowed_output.h"
#include <cursor.h>
#include <kwinxrenderutils.h>
#include <pointer_input.h>
// KDE
#include <KLocalizedString>
@ -29,7 +29,7 @@
#include <xcb/xcb_keysyms.h>
// X11
#if HAVE_X11_XINPUT
#include "ge_event_mem_mover.h"
#include "../common/ge_event_mem_mover.h"
#include <X11/extensions/XI2proto.h>
#include <X11/extensions/XInput2.h>
#endif

View file

@ -83,8 +83,7 @@ private:
class KWIN_EXPORT X11WindowedBackend : public Platform
{
Q_OBJECT
Q_INTERFACES(KWin::Platform)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Platform" FILE "x11.json")
public:
X11WindowedBackend(QObject *parent = nullptr);
~X11WindowedBackend() override;

View file

@ -34,7 +34,6 @@
// KDE
#include <KAboutData>
#include <KLocalizedString>
#include <KPluginMetaData>
// Qt
#include <QCommandLineParser>
#include <QLibraryInfo>
@ -141,8 +140,7 @@ void Application::destroyAtoms()
void Application::destroyPlatform()
{
delete m_platform;
m_platform = nullptr;
m_platform.reset();
}
void Application::resetCrashesCount()
@ -549,16 +547,10 @@ void Application::setProcessStartupEnvironment(const QProcessEnvironment &enviro
m_processEnvironment = environment;
}
void Application::initPlatform(const KPluginMetaData &plugin)
void Application::setPlatform(std::unique_ptr<Platform> &&platform)
{
Q_ASSERT(!m_platform);
QPluginLoader loader(plugin.fileName());
m_platform = qobject_cast<Platform *>(loader.instance());
if (m_platform) {
m_platform->setParent(this);
} else {
qCWarning(KWIN_CORE) << "Could not create plugin" << plugin.name() << "error:" << loader.errorString();
}
m_platform = std::move(platform);
}
PluginManager *Application::pluginManager() const

View file

@ -222,11 +222,11 @@ public:
QProcessEnvironment processStartupEnvironment() const;
void setProcessStartupEnvironment(const QProcessEnvironment &environment);
void initPlatform(const KPluginMetaData &plugin);
Platform *platform() const
{
return m_platform;
return m_platform.get();
}
void setPlatform(std::unique_ptr<Platform> &&platform);
bool isTerminating() const
{
@ -297,7 +297,7 @@ private:
#if KWIN_BUILD_ACTIVITIES
bool m_useKActivities = true;
#endif
Platform *m_platform = nullptr;
std::unique_ptr<Platform> m_platform;
bool m_terminating = false;
qreal m_xwaylandScale = 1;
QProcessEnvironment m_processEnvironment;

View file

@ -10,6 +10,10 @@
#include <config-kwin.h>
#include "backends/drm/drm_backend.h"
#include "backends/virtual/virtual_backend.h"
#include "backends/wayland/wayland_backend.h"
#include "backends/x11/windowed/x11windowed_backend.h"
#include "composite.h"
#include "effects.h"
#include "inputmethod.h"
@ -27,7 +31,6 @@
#include <KCrash>
#include <KDesktopFile>
#include <KLocalizedString>
#include <KPluginMetaData>
#include <KShell>
// Qt
@ -272,22 +275,6 @@ void ApplicationWayland::startSession()
}
}
static const QString s_waylandPlugin = QStringLiteral("KWinWaylandWaylandBackend");
static const QString s_x11Plugin = QStringLiteral("KWinWaylandX11Backend");
static const QString s_drmPlugin = QStringLiteral("KWinWaylandDrmBackend");
static const QString s_virtualPlugin = QStringLiteral("KWinWaylandVirtualBackend");
static QString automaticBackendSelection()
{
if (qEnvironmentVariableIsSet("WAYLAND_DISPLAY")) {
return s_waylandPlugin;
}
if (qEnvironmentVariableIsSet("DISPLAY")) {
return s_x11Plugin;
}
return s_drmPlugin;
}
} // namespace
int main(int argc, char *argv[])
@ -329,20 +316,6 @@ int main(int argc, char *argv[])
KWin::Application::createAboutData();
const auto availablePlugins = KPluginMetaData::findPlugins(QStringLiteral("org.kde.kwin.waylandbackends"));
auto hasPlugin = [&availablePlugins](const QString &name) {
return std::any_of(availablePlugins.begin(), availablePlugins.end(),
[name](const KPluginMetaData &plugin) {
return plugin.pluginId() == name;
});
};
const bool hasSizeOption = hasPlugin(KWin::s_x11Plugin) || hasPlugin(KWin::s_virtualPlugin);
const bool hasOutputCountOption = hasPlugin(KWin::s_x11Plugin);
const bool hasX11Option = hasPlugin(KWin::s_x11Plugin);
const bool hasVirtualOption = hasPlugin(KWin::s_virtualPlugin);
const bool hasWaylandOption = hasPlugin(KWin::s_waylandPlugin);
const bool hasDrmOption = hasPlugin(KWin::s_drmPlugin);
QCommandLineOption xwaylandOption(QStringLiteral("xwayland"),
i18n("Start a rootless Xwayland server."));
QCommandLineOption waylandSocketOption(QStringList{QStringLiteral("s"), QStringLiteral("socket")},
@ -393,6 +366,8 @@ int main(int argc, char *argv[])
QCommandLineOption replaceOption(QStringLiteral("replace"),
i18n("Exits this instance so it can be restarted by kwin_wayland_wrapper."));
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
QCommandLineParser parser;
a.setupCommandLine(&parser);
parser.addOption(xwaylandOption);
@ -402,38 +377,20 @@ int main(int argc, char *argv[])
parser.addOption(xwaylandDisplayOption);
parser.addOption(xwaylandXAuthorityOption);
parser.addOption(replaceOption);
if (hasX11Option) {
parser.addOption(x11DisplayOption);
}
if (hasWaylandOption) {
parser.addOption(waylandDisplayOption);
}
if (hasVirtualOption) {
parser.addOption(virtualFbOption);
}
if (hasSizeOption) {
parser.addOption(widthOption);
parser.addOption(heightOption);
parser.addOption(scaleOption);
}
if (hasOutputCountOption) {
parser.addOption(outputCountOption);
}
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
if (hasDrmOption) {
parser.addOption(drmOption);
}
parser.addOption(x11DisplayOption);
parser.addOption(waylandDisplayOption);
parser.addOption(virtualFbOption);
parser.addOption(widthOption);
parser.addOption(heightOption);
parser.addOption(scaleOption);
parser.addOption(outputCountOption);
parser.addOption(drmOption);
QCommandLineOption inputMethodOption(QStringLiteral("inputmethod"),
i18n("Input method that KWin starts."),
QStringLiteral("path/to/imserver"));
parser.addOption(inputMethodOption);
QCommandLineOption listBackendsOption(QStringLiteral("list-backends"),
i18n("List all available backends and quit."));
parser.addOption(listBackendsOption);
#if KWIN_BUILD_SCREENLOCKER
QCommandLineOption screenLockerOption(QStringLiteral("lockscreen"),
i18n("Starts the session in locked mode."));
@ -478,82 +435,70 @@ int main(int argc, char *argv[])
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
return 0;
}
if (parser.isSet(listBackendsOption)) {
for (const auto &plugin : availablePlugins) {
std::cout << std::setw(40) << std::left << qPrintable(plugin.name()) << qPrintable(plugin.description()) << std::endl;
}
return 0;
}
if (parser.isSet(exitWithSessionOption)) {
a.setSessionArgument(parser.value(exitWithSessionOption));
}
enum class BackendType {
Kms,
X11,
Wayland,
Virtual,
};
BackendType backendType;
QString pluginName;
QSize initialWindowSize;
QByteArray deviceIdentifier;
int outputCount = 1;
qreal outputScale = 1;
if (hasDrmOption && parser.isSet(drmOption)) {
pluginName = KWin::s_drmPlugin;
}
if (hasSizeOption) {
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;
}
const int height = parser.value(heightOption).toInt(&ok);
if (!ok) {
std::cerr << "FATAL ERROR incorrect value for height" << std::endl;
return 1;
}
const qreal scale = parser.value(scaleOption).toDouble(&ok);
if (!ok || scale <= 0) {
std::cerr << "FATAL ERROR incorrect value for scale" << std::endl;
return 1;
}
outputScale = scale;
initialWindowSize = QSize(width, height);
}
if (hasOutputCountOption) {
bool ok = false;
const int count = parser.value(outputCountOption).toInt(&ok);
if (ok) {
outputCount = qMax(1, count);
}
}
if (hasX11Option && parser.isSet(x11DisplayOption)) {
// Decide what backend to use.
if (parser.isSet(drmOption)) {
backendType = BackendType::Kms;
} else if (parser.isSet(x11DisplayOption)) {
backendType = BackendType::X11;
deviceIdentifier = parser.value(x11DisplayOption).toUtf8();
pluginName = KWin::s_x11Plugin;
} else if (hasWaylandOption && parser.isSet(waylandDisplayOption)) {
} else if (parser.isSet(waylandDisplayOption)) {
backendType = BackendType::Wayland;
deviceIdentifier = parser.value(waylandDisplayOption).toUtf8();
pluginName = KWin::s_waylandPlugin;
} else if (parser.isSet(virtualFbOption)) {
backendType = BackendType::Virtual;
} else {
if (qEnvironmentVariableIsSet("WAYLAND_DISPLAY")) {
backendType = BackendType::Wayland;
} else if (qEnvironmentVariableIsSet("DISPLAY")) {
backendType = BackendType::X11;
} else {
backendType = BackendType::Kms;
}
}
if (hasVirtualOption && parser.isSet(virtualFbOption)) {
pluginName = KWin::s_virtualPlugin;
}
if (pluginName.isEmpty()) {
std::cerr << "No backend specified through command line argument, trying auto resolution" << std::endl;
pluginName = KWin::automaticBackendSelection();
}
auto pluginIt = std::find_if(availablePlugins.begin(), availablePlugins.end(),
[&pluginName](const KPluginMetaData &plugin) {
return plugin.pluginId() == pluginName;
});
if (pluginIt == availablePlugins.end()) {
std::cerr << "FATAL ERROR: could not find a backend" << std::endl;
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;
}
const int height = parser.value(heightOption).toInt(&ok);
if (!ok) {
std::cerr << "FATAL ERROR incorrect value for height" << std::endl;
return 1;
}
const qreal scale = parser.value(scaleOption).toDouble(&ok);
if (!ok || scale <= 0) {
std::cerr << "FATAL ERROR incorrect value for scale" << std::endl;
return 1;
}
outputScale = scale;
initialWindowSize = QSize(width, height);
const int count = parser.value(outputCountOption).toInt(&ok);
if (ok) {
outputCount = qMax(1, count);
}
// TODO: create backend without having the server running
KWin::WaylandServer *server = KWin::WaylandServer::create(&a);
@ -595,11 +540,21 @@ int main(int argc, char *argv[])
return 1;
}
a.initPlatform(*pluginIt);
if (!a.platform()) {
std::cerr << "FATAL ERROR: could not instantiate a backend" << std::endl;
return 1;
switch (backendType) {
case BackendType::Kms:
a.setPlatform(std::make_unique<KWin::DrmBackend>());
break;
case BackendType::Virtual:
a.setPlatform(std::make_unique<KWin::VirtualBackend>());
break;
case BackendType::X11:
a.setPlatform(std::make_unique<KWin::X11WindowedBackend>());
break;
case BackendType::Wayland:
a.setPlatform(std::make_unique<KWin::Wayland::WaylandBackend>());
break;
}
if (!deviceIdentifier.isEmpty()) {
a.platform()->setDeviceIdentifier(deviceIdentifier);
}

View file

@ -12,6 +12,7 @@
#include <config-kwin.h>
#include "backends/x11/standalone/x11_platform.h"
#include "platform.h"
#include "sm.h"
#include "tabletmodemanager.h"
@ -21,7 +22,6 @@
#include <KConfigGroup>
#include <KCrash>
#include <KLocalizedString>
#include <KPluginMetaData>
#include <KSelectionOwner>
#include <QComboBox>
@ -410,19 +410,7 @@ int main(int argc, char *argv[])
exit(1);
}
// find and load the X11 platform plugin
const KPluginMetaData plugin = KPluginMetaData::findPluginById(QStringLiteral("org.kde.kwin.platforms"), QStringLiteral("KWinX11Platform"));
if (!plugin.isValid()) {
std::cerr << "FATAL ERROR: KWin could not find the KWinX11Platform plugin" << std::endl;
return 1;
}
a.initPlatform(plugin);
if (!a.platform()) {
std::cerr << "FATAL ERROR: could not instantiate the platform plugin" << std::endl;
return 1;
}
a.setPlatform(std::make_unique<KWin::X11StandalonePlatform>());
a.start();
return a.exec();

View file

@ -439,8 +439,6 @@ private:
Output *m_primaryOutput = nullptr;
};
}
Q_DECLARE_INTERFACE(KWin::Platform, "org.kde.kwin.Platform")
} // namespace KWin
#endif