wayland: Setup compositing when window is mapped ready for painting

This prevents creating a WindowItem until we know that the window is
actually going to be visible on the screen.
remotes/origin/work/zzag/xwayland-potential-fd-leak
Vlad Zahorodnii 3 years ago
parent 5cd99b27fd
commit c191902026
  1. 20
      src/composite.cpp
  2. 2
      src/inputpanelv1window.cpp
  3. 2
      src/layershellv1window.cpp
  4. 9
      src/waylandwindow.cpp
  5. 1
      src/waylandwindow.h
  6. 6
      src/xdgshellwindow.cpp

@ -384,7 +384,8 @@ void Compositor::startupWithWorkspace()
m_state = State::On; m_state = State::On;
for (X11Window *window : Workspace::self()->clientList()) { const auto windows = workspace()->allClientList();
for (Window *window : windows) {
window->setupCompositing(); window->setupCompositing();
} }
for (Unmanaged *window : Workspace::self()->unmanagedList()) { for (Unmanaged *window : Workspace::self()->unmanagedList()) {
@ -394,13 +395,6 @@ void Compositor::startupWithWorkspace()
window->setupCompositing(); window->setupCompositing();
} }
if (auto *server = waylandServer()) {
const auto windows = server->windows();
for (Window *window : windows) {
window->setupCompositing();
}
}
// Sets also the 'effects' pointer. // Sets also the 'effects' pointer.
kwinApp()->createEffectsHandler(this, m_scene.get()); kwinApp()->createEffectsHandler(this, m_scene.get());
@ -515,7 +509,8 @@ void Compositor::stop()
effects = nullptr; effects = nullptr;
if (Workspace::self()) { if (Workspace::self()) {
for (X11Window *window : Workspace::self()->clientList()) { const auto windows = workspace()->allClientList();
for (Window *window : windows) {
window->finishCompositing(); window->finishCompositing();
} }
for (Unmanaged *window : Workspace::self()->unmanagedList()) { for (Unmanaged *window : Workspace::self()->unmanagedList()) {
@ -536,13 +531,6 @@ void Compositor::stop()
disconnect(workspace(), &Workspace::outputRemoved, this, &Compositor::removeOutput); disconnect(workspace(), &Workspace::outputRemoved, this, &Compositor::removeOutput);
} }
if (waylandServer()) {
const QList<Window *> toFinishCompositing = waylandServer()->windows();
for (Window *window : toFinishCompositing) {
window->finishCompositing();
}
}
const auto superlayers = m_superlayers; const auto superlayers = m_superlayers;
for (auto it = superlayers.begin(); it != superlayers.end(); ++it) { for (auto it = superlayers.begin(); it != superlayers.end(); ++it) {
removeSuperLayer(*it); removeSuperLayer(*it);

@ -189,7 +189,7 @@ void InputPanelV1Window::maybeShow()
{ {
const bool shouldShow = m_mode == Mode::Overlay || (m_mode == Mode::VirtualKeyboard && m_allowed && m_virtualKeyboardShouldBeShown); const bool shouldShow = m_mode == Mode::Overlay || (m_mode == Mode::VirtualKeyboard && m_allowed && m_virtualKeyboardShouldBeShown);
if (shouldShow && !isZombie() && surface()->isMapped()) { if (shouldShow && !isZombie() && surface()->isMapped()) {
setReadyForPainting(); markAsMapped();
reposition(); reposition();
showClient(); showClient();
} }

@ -250,7 +250,7 @@ void LayerShellV1Window::handleUnmapped()
void LayerShellV1Window::handleCommitted() void LayerShellV1Window::handleCommitted()
{ {
if (surface()->buffer()) { if (surface()->buffer()) {
setReadyForPainting(); markAsMapped();
} }
} }

@ -38,7 +38,6 @@ WaylandWindow::WaylandWindow(SurfaceInterface *surface)
{ {
setSurface(surface); setSurface(surface);
setDepth(32); setDepth(32);
setupCompositing();
connect(surface, &SurfaceInterface::shadowChanged, connect(surface, &SurfaceInterface::shadowChanged,
this, &WaylandWindow::updateShadow); this, &WaylandWindow::updateShadow);
@ -323,4 +322,12 @@ void WaylandWindow::updateGeometry(const QRectF &rect)
Q_EMIT geometryShapeChanged(oldFrameGeometry); Q_EMIT geometryShapeChanged(oldFrameGeometry);
} }
void WaylandWindow::markAsMapped()
{
if (Q_UNLIKELY(!ready_for_painting)) {
setupCompositing();
setReadyForPainting();
}
}
} // namespace KWin } // namespace KWin

@ -47,6 +47,7 @@ protected:
void cleanGrouping(); void cleanGrouping();
void updateGeometry(const QRectF &rect); void updateGeometry(const QRectF &rect);
void markAsMapped();
private: private:
void updateClientOutputs(); void updateClientOutputs();

@ -52,10 +52,6 @@ XdgSurfaceWindow::XdgSurfaceWindow(XdgSurfaceInterface *shellSurface)
this, &XdgSurfaceWindow::destroyWindow); this, &XdgSurfaceWindow::destroyWindow);
connect(shellSurface->surface(), &SurfaceInterface::committed, connect(shellSurface->surface(), &SurfaceInterface::committed,
this, &XdgSurfaceWindow::handleCommit); this, &XdgSurfaceWindow::handleCommit);
#if 0 // TODO: Refactor kwin core in order to uncomment this code.
connect(shellSurface->surface(), &SurfaceInterface::mapped,
this, &XdgSurfaceWindow::setReadyForPainting);
#endif
connect(shellSurface, &XdgSurfaceInterface::aboutToBeDestroyed, connect(shellSurface, &XdgSurfaceInterface::aboutToBeDestroyed,
this, &XdgSurfaceWindow::destroyWindow); this, &XdgSurfaceWindow::destroyWindow);
connect(shellSurface->surface(), &SurfaceInterface::aboutToBeDestroyed, connect(shellSurface->surface(), &SurfaceInterface::aboutToBeDestroyed,
@ -174,7 +170,7 @@ void XdgSurfaceWindow::handleCommit()
m_lastAcknowledgedConfigure.reset(); m_lastAcknowledgedConfigure.reset();
m_lastAcknowledgedConfigureSerial.reset(); m_lastAcknowledgedConfigureSerial.reset();
setReadyForPainting(); markAsMapped();
} }
void XdgSurfaceWindow::handleRolePrecommit() void XdgSurfaceWindow::handleRolePrecommit()

Loading…
Cancel
Save