From 72aad0881d134270d35841e8dedbde7fc343b158 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 19 Sep 2023 15:30:45 +0300 Subject: [PATCH] xwayland: Initialize X11 compositing in Xwayland If somebody else claims the compositing selection, we definitely do not want to stop compositing. It will also help with encapsulating X11-specific code and splitting it out in the future. --- src/compositor.cpp | 63 +++++++++++++++---------------------- src/compositor.h | 3 -- src/xwayland/CMakeLists.txt | 2 +- src/xwayland/xwayland.cpp | 20 ++++++++---- src/xwayland/xwayland.h | 3 +- 5 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/compositor.cpp b/src/compositor.cpp index e3aecc8122..f767527afa 100644 --- a/src/compositor.cpp +++ b/src/compositor.cpp @@ -104,9 +104,6 @@ Compositor::Compositor(QObject *workspace) // in undefined behavior. This is fixed by using a delayed invocation. QTimer::singleShot(0, this, &Compositor::start); - connect(kwinApp(), &Application::x11ConnectionChanged, this, &Compositor::initializeX11); - connect(kwinApp(), &Application::x11ConnectionAboutToBeDestroyed, this, &Compositor::cleanupX11); - // register DBus new CompositorDBusInterface(this); FTraceLogger::create(); @@ -204,7 +201,21 @@ bool Compositor::setupStart() } m_state = State::Starting; - initializeX11(); + if (kwinApp()->operationMode() == Application::OperationModeX11) { + if (!m_selectionOwner) { + m_selectionOwner = std::make_unique("_NET_WM_CM_S0"); + connect(m_selectionOwner.get(), &CompositorSelectionOwner::lostOwnership, this, &Compositor::stop); + } + if (!m_selectionOwner->owning()) { + // Force claim ownership. + m_selectionOwner->claim(true); + m_selectionOwner->setOwning(true); + } + + xcb_composite_redirect_subwindows(kwinApp()->x11Connection(), + kwinApp()->x11RootWindow(), + XCB_COMPOSITE_REDIRECT_MANUAL); + } Q_EMIT aboutToToggleCompositing(); @@ -254,13 +265,14 @@ bool Compositor::setupStart() if (!m_backend) { m_state = State::Off; - if (auto *con = kwinApp()->x11Connection()) { - xcb_composite_unredirect_subwindows(con, kwinApp()->x11RootWindow(), + if (kwinApp()->operationMode() == Application::OperationModeX11) { + xcb_composite_unredirect_subwindows(kwinApp()->x11Connection(), + kwinApp()->x11RootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL); - } - if (m_selectionOwner) { - m_selectionOwner->setOwning(false); - m_selectionOwner->release(); + if (m_selectionOwner) { + m_selectionOwner->setOwning(false); + m_selectionOwner->release(); + } } if (!availableCompositors.contains(NoCompositing)) { qCCritical(KWIN_CORE) << "The used windowing system requires compositing"; @@ -282,32 +294,6 @@ bool Compositor::setupStart() return true; } -void Compositor::initializeX11() -{ - xcb_connection_t *connection = kwinApp()->x11Connection(); - if (!connection) { - return; - } - - if (!m_selectionOwner) { - m_selectionOwner = std::make_unique("_NET_WM_CM_S0"); - connect(m_selectionOwner.get(), &CompositorSelectionOwner::lostOwnership, this, &Compositor::stop); - } - if (!m_selectionOwner->owning()) { - // Force claim ownership. - m_selectionOwner->claim(true); - m_selectionOwner->setOwning(true); - } - - xcb_composite_redirect_subwindows(connection, kwinApp()->x11RootWindow(), - XCB_COMPOSITE_REDIRECT_MANUAL); -} - -void Compositor::cleanupX11() -{ - m_selectionOwner.reset(); -} - void Compositor::startupWithWorkspace() { Q_ASSERT(m_scene); @@ -512,8 +498,9 @@ void Compositor::stop() for (Window *window : windows) { window->finishCompositing(); } - if (auto *con = kwinApp()->x11Connection()) { - xcb_composite_unredirect_subwindows(con, kwinApp()->x11RootWindow(), + if (kwinApp()->operationMode() == Application::OperationModeX11) { + xcb_composite_unredirect_subwindows(kwinApp()->x11Connection(), + kwinApp()->x11RootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL); } diff --git a/src/compositor.h b/src/compositor.h index 2d7363926b..ef46954d7f 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -173,9 +173,6 @@ private Q_SLOTS: void handleFrameRequested(RenderLoop *renderLoop); private: - void initializeX11(); - void cleanupX11(); - void releaseCompositorSelection(); void deleteUnusedSupportProperties(); diff --git a/src/xwayland/CMakeLists.txt b/src/xwayland/CMakeLists.txt index f954f7436d..2e2db0d504 100644 --- a/src/xwayland/CMakeLists.txt +++ b/src/xwayland/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(KWinXwaylandServerModule OBJECT xwldrophandler.cpp xwaylandlauncher.cpp ) -target_link_libraries(KWinXwaylandServerModule PUBLIC kwin KWinXwaylandCommon XCB::XCB XCB::RANDR XCB::XFIXES XKB::XKB) +target_link_libraries(KWinXwaylandServerModule PUBLIC kwin KWinXwaylandCommon XCB::XCB XCB::RANDR XCB::XFIXES XCB::COMPOSITE XKB::XKB) if(TARGET KF6::Notifications) target_link_libraries(KWinXwaylandServerModule PUBLIC KF6::Notifications) endif() diff --git a/src/xwayland/xwayland.cpp b/src/xwayland/xwayland.cpp index ed7d1c063e..9cad1a2ebd 100644 --- a/src/xwayland/xwayland.cpp +++ b/src/xwayland/xwayland.cpp @@ -290,7 +290,8 @@ void Xwayland::handleXwaylandFinished() uninstallSocketNotifier(); m_dataBridge.reset(); - m_selectionOwner.reset(); + m_compositingManagerSelectionOwner.reset(); + m_windowManagerSelectionOwner.reset(); m_inputSpy.reset(); disconnect(options, &Options::xwaylandEavesdropsChanged, this, &Xwayland::refreshEavesdropping); @@ -307,15 +308,22 @@ void Xwayland::handleXwaylandReady() qCInfo(KWIN_XWL) << "Xwayland server started on display" << m_launcher->displayName(); + m_compositingManagerSelectionOwner = std::make_unique("_NET_WM_CM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow()); + m_compositingManagerSelectionOwner->claim(true); + + xcb_composite_redirect_subwindows(kwinApp()->x11Connection(), + kwinApp()->x11RootWindow(), + XCB_COMPOSITE_REDIRECT_MANUAL); + // create selection owner for WM_S0 - magic X display number expected by XWayland - m_selectionOwner = std::make_unique("WM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow()); - connect(m_selectionOwner.get(), &KSelectionOwner::lostOwnership, + m_windowManagerSelectionOwner = std::make_unique("WM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow()); + connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::lostOwnership, this, &Xwayland::handleSelectionLostOwnership); - connect(m_selectionOwner.get(), &KSelectionOwner::claimedOwnership, + connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::claimedOwnership, this, &Xwayland::handleSelectionClaimedOwnership); - connect(m_selectionOwner.get(), &KSelectionOwner::failedToClaimOwnership, + connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::failedToClaimOwnership, this, &Xwayland::handleSelectionFailedToClaimOwnership); - m_selectionOwner->claim(true); + m_windowManagerSelectionOwner->claim(true); m_dataBridge = std::make_unique(); diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index 1ebd8da925..b3b853c356 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -84,7 +84,8 @@ private: QSocketNotifier *m_socketNotifier = nullptr; Application *m_app; - std::unique_ptr m_selectionOwner; + std::unique_ptr m_windowManagerSelectionOwner; + std::unique_ptr m_compositingManagerSelectionOwner; std::unique_ptr m_dataBridge; XrandrEventFilter *m_xrandrEventsFilter = nullptr;