Do not hard runtime depend on X11 in composite startup

Summary:
The compositor needs to claim the X11 compositor selection and redirect
the X11 windows. This of course only makes sense when having X11 support.

This change refactors the code so that if X11 support is missing the code
is not executed, but as soon as X11 support comes available the selection
gets claimed.

Also if the connection goes away the selection is deleted, though it
might be that this does not work as KSelectionOwner might call into xcb
and cause a crash. This needs to be tested once we start supporting
XWayland going away.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7504
This commit is contained in:
Martin Flöser 2017-08-24 10:43:38 +02:00
parent 51561052ec
commit 2892fad5b6
2 changed files with 20 additions and 5 deletions

View file

@ -190,7 +190,7 @@ extern bool is_multihead;
void Compositor::slotCompositingOptionsInitialized() void Compositor::slotCompositingOptionsInitialized()
{ {
claimCompositorSelection(); setupX11Support();
// There might still be a deleted around, needs to be cleared before creating the scene (BUG 333275) // There might still be a deleted around, needs to be cleared before creating the scene (BUG 333275)
if (Workspace::self()) { if (Workspace::self()) {
@ -290,7 +290,7 @@ void Compositor::slotCompositingOptionsInitialized()
void Compositor::claimCompositorSelection() void Compositor::claimCompositorSelection()
{ {
if (!cm_selection && kwinApp()->x11Connection()) { if (!cm_selection) {
char selection_name[ 100 ]; char selection_name[ 100 ];
sprintf(selection_name, "_NET_WM_CM_S%d", Application::x11ScreenNumber()); sprintf(selection_name, "_NET_WM_CM_S%d", Application::x11ScreenNumber());
cm_selection = new CompositorSelectionOwner(selection_name); cm_selection = new CompositorSelectionOwner(selection_name);
@ -306,15 +306,28 @@ void Compositor::claimCompositorSelection()
} }
} }
void Compositor::setupX11Support()
{
auto c = kwinApp()->x11Connection();
if (!c) {
delete cm_selection;
cm_selection = nullptr;
return;
}
claimCompositorSelection();
xcb_composite_redirect_subwindows(c, kwinApp()->x11RootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL);
}
void Compositor::startupWithWorkspace() void Compositor::startupWithWorkspace()
{ {
if (!m_starting) { if (!m_starting) {
return; return;
} }
connect(kwinApp(), &Application::x11ConnectionChanged, this, &Compositor::setupX11Support, Qt::UniqueConnection);
Workspace::self()->markXStackingOrderAsDirty(); Workspace::self()->markXStackingOrderAsDirty();
Q_ASSERT(m_scene); Q_ASSERT(m_scene);
connect(workspace(), &Workspace::destroyed, this, [this] { compositeTimer.stop(); }); connect(workspace(), &Workspace::destroyed, this, [this] { compositeTimer.stop(); });
claimCompositorSelection(); setupX11Support();
m_xrrRefreshRate = KWin::currentRefreshRate(); m_xrrRefreshRate = KWin::currentRefreshRate();
fpsInterval = options->maxFpsInterval(); fpsInterval = options->maxFpsInterval();
if (m_scene->syncsToVBlank()) { // if we do vsync, set the fps to the next multiple of the vblank rate if (m_scene->syncsToVBlank()) { // if we do vsync, set the fps to the next multiple of the vblank rate
@ -324,7 +337,6 @@ void Compositor::startupWithWorkspace()
vBlankInterval = milliToNano(1); // no sync - DO NOT set "0", would cause div-by-zero segfaults. vBlankInterval = milliToNano(1); // no sync - DO NOT set "0", would cause div-by-zero segfaults.
m_timeSinceLastVBlank = fpsInterval - (options->vBlankTime() + 1); // means "start now" - we don't have even a slight idea when the first vsync will occur m_timeSinceLastVBlank = fpsInterval - (options->vBlankTime() + 1); // means "start now" - we don't have even a slight idea when the first vsync will occur
scheduleRepaint(); scheduleRepaint();
xcb_composite_redirect_subwindows(connection(), rootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL);
new EffectsHandlerImpl(this, m_scene); // sets also the 'effects' pointer new EffectsHandlerImpl(this, m_scene); // sets also the 'effects' pointer
connect(Workspace::self(), &Workspace::deletedRemoved, m_scene, &Scene::windowDeleted); connect(Workspace::self(), &Workspace::deletedRemoved, m_scene, &Scene::windowDeleted);
connect(effects, SIGNAL(screenGeometryChanged(QSize)), SLOT(addRepaintFull())); connect(effects, SIGNAL(screenGeometryChanged(QSize)), SLOT(addRepaintFull()));
@ -392,7 +404,9 @@ void Compositor::finish()
c->finishCompositing(); c->finishCompositing();
foreach (Deleted * c, Workspace::self()->deletedList()) foreach (Deleted * c, Workspace::self()->deletedList())
c->finishCompositing(); c->finishCompositing();
xcb_composite_unredirect_subwindows(connection(), rootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL); if (auto c = kwinApp()->x11Connection()) {
xcb_composite_unredirect_subwindows(c, kwinApp()->x11RootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL);
}
} }
if (waylandServer()) { if (waylandServer()) {
foreach (ShellClient *c, waylandServer()->clients()) { foreach (ShellClient *c, waylandServer()->clients()) {

View file

@ -207,6 +207,7 @@ private:
* Continues the startup after Scene And Workspace are created * Continues the startup after Scene And Workspace are created
**/ **/
void startupWithWorkspace(); void startupWithWorkspace();
void setupX11Support();
/** /**
* Whether the Compositor is currently suspended, 8 bits encoding the reason * Whether the Compositor is currently suspended, 8 bits encoding the reason