treeland/waylib/examples/tinywl/layersurfacecontainer.cpp

133 lines
3.9 KiB
C++

// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "layersurfacecontainer.h"
#include "surfacewrapper.h"
#include "output.h"
#include "helper.h"
#include "rootsurfacecontainer.h"
#include <wlayersurface.h>
#include <woutputitem.h>
WAYLIB_SERVER_USE_NAMESPACE
OutputLayerSurfaceContainer::OutputLayerSurfaceContainer(Output *output, LayerSurfaceContainer *parent)
: SurfaceContainer(parent)
, m_output(output)
{
}
Output *OutputLayerSurfaceContainer::output() const
{
return m_output;
}
void OutputLayerSurfaceContainer::addSurface(SurfaceWrapper *surface)
{
SurfaceContainer::addSurface(surface);
surface->setOwnsOutput(m_output);
}
void OutputLayerSurfaceContainer::removeSurface(SurfaceWrapper *surface)
{
SurfaceContainer::removeSurface(surface);
if (surface->ownsOutput() == m_output)
surface->setOwnsOutput(nullptr);
}
LayerSurfaceContainer::LayerSurfaceContainer(SurfaceContainer *parent)
: SurfaceContainer(parent)
{
}
void LayerSurfaceContainer::addOutput(Output *output)
{
Q_ASSERT(!getSurfaceContainer(output));
auto container = new OutputLayerSurfaceContainer(output, this);
m_surfaceContainers.append(container);
updateSurfacesContainer();
}
void LayerSurfaceContainer::removeOutput(Output *output)
{
OutputLayerSurfaceContainer *container = getSurfaceContainer(output);
Q_ASSERT(container);
m_surfaceContainers.removeOne(container);
for (SurfaceWrapper *surface : container->surfaces()) {
container->removeSurface(surface);
auto layerSurface = qobject_cast<WLayerSurface*>(surface->shellSurface());
Q_ASSERT(layerSurface);
// Needs to be moved to the new primary output
if (!layerSurface->output())
addSurfaceToContainer(surface);
}
container->deleteLater();
}
OutputLayerSurfaceContainer *LayerSurfaceContainer::getSurfaceContainer(const Output *output) const
{
for (OutputLayerSurfaceContainer *container : std::as_const(m_surfaceContainers)) {
if (container->output() == output)
return container;
}
return nullptr;
}
OutputLayerSurfaceContainer *LayerSurfaceContainer::getSurfaceContainer(const WOutput *output) const
{
for (OutputLayerSurfaceContainer *container : std::as_const(m_surfaceContainers)) {
if (container->output()->output() == output)
return container;
}
return nullptr;
}
void LayerSurfaceContainer::addSurface(SurfaceWrapper *surface)
{
Q_ASSERT(surface->type() == SurfaceWrapper::Type::Layer);
if (!SurfaceContainer::doAddSurface(surface, false))
return;
addSurfaceToContainer(surface);
}
void LayerSurfaceContainer::removeSurface(SurfaceWrapper *surface)
{
if (!SurfaceContainer::doRemoveSurface(surface, false))
return;
auto shell = qobject_cast<WLayerSurface*>(surface->shellSurface());
auto output = shell->output();
auto container = getSurfaceContainer(output);
Q_ASSERT(container);
Q_ASSERT(container->surfaces().contains(surface));
container->removeSurface(surface);
}
void LayerSurfaceContainer::addSurfaceToContainer(SurfaceWrapper *surface)
{
Q_ASSERT(!surface->container());
auto shell = qobject_cast<WLayerSurface*>(surface->shellSurface());
auto output = shell->output() ? shell->output() : rootContainer()->primaryOutput()->output();
if (!output) {
qCWarning(qLcLayerShell) << "No output, will close layer surface!";
shell->closed();
return;
}
auto container = getSurfaceContainer(output);
Q_ASSERT(container);
Q_ASSERT(!container->surfaces().contains(surface));
container->addSurface(surface);
}
void LayerSurfaceContainer::updateSurfacesContainer()
{
for (SurfaceWrapper *surface : surfaces()) {
if (!surface->container())
addSurfaceToContainer(surface);
}
}