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.
This commit is contained in:
Vlad Zahorodnii 2023-09-19 15:30:45 +03:00
parent f223362ddf
commit 72aad0881d
5 changed files with 42 additions and 49 deletions

View file

@ -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<CompositorSelectionOwner>("_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<CompositorSelectionOwner>("_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);
}

View file

@ -173,9 +173,6 @@ private Q_SLOTS:
void handleFrameRequested(RenderLoop *renderLoop);
private:
void initializeX11();
void cleanupX11();
void releaseCompositorSelection();
void deleteUnusedSupportProperties();

View file

@ -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()

View file

@ -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<KSelectionOwner>("_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<KSelectionOwner>("WM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
connect(m_selectionOwner.get(), &KSelectionOwner::lostOwnership,
m_windowManagerSelectionOwner = std::make_unique<KSelectionOwner>("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<DataBridge>();

View file

@ -84,7 +84,8 @@ private:
QSocketNotifier *m_socketNotifier = nullptr;
Application *m_app;
std::unique_ptr<KSelectionOwner> m_selectionOwner;
std::unique_ptr<KSelectionOwner> m_windowManagerSelectionOwner;
std::unique_ptr<KSelectionOwner> m_compositingManagerSelectionOwner;
std::unique_ptr<DataBridge> m_dataBridge;
XrandrEventFilter *m_xrandrEventsFilter = nullptr;