2021-02-04 09:07:20 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "windowitem.h"
|
|
|
|
#include "abstract_client.h"
|
|
|
|
#include "decorationitem.h"
|
2021-08-12 09:07:38 +00:00
|
|
|
#include "deleted.h"
|
2021-11-16 07:38:51 +00:00
|
|
|
#include "internal_client.h"
|
2021-02-04 09:07:20 +00:00
|
|
|
#include "shadowitem.h"
|
|
|
|
#include "surfaceitem_internal.h"
|
|
|
|
#include "surfaceitem_wayland.h"
|
|
|
|
#include "surfaceitem_x11.h"
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
WindowItem::WindowItem(Toplevel *window, Item *parent)
|
|
|
|
: Item(parent)
|
|
|
|
, m_window(window)
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2022-04-14 13:50:12 +00:00
|
|
|
auto client = static_cast<AbstractClient *>(window->isClient() ? window : nullptr);
|
2021-02-04 09:07:20 +00:00
|
|
|
if (client) {
|
|
|
|
connect(client, &AbstractClient::decorationChanged, this, &WindowItem::updateDecorationItem);
|
|
|
|
updateDecorationItem();
|
|
|
|
}
|
2021-09-03 10:24:17 +00:00
|
|
|
connect(window, &Toplevel::shadowChanged, this, &WindowItem::updateShadowItem);
|
|
|
|
updateShadowItem();
|
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
connect(window, &Toplevel::windowClosed, this, &WindowItem::handleWindowClosed);
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SurfaceItem *WindowItem::surfaceItem() const
|
|
|
|
{
|
|
|
|
return m_surfaceItem.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
DecorationItem *WindowItem::decorationItem() const
|
|
|
|
{
|
|
|
|
return m_decorationItem.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
ShadowItem *WindowItem::shadowItem() const
|
|
|
|
{
|
|
|
|
return m_shadowItem.data();
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
Toplevel *WindowItem::window() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2021-08-12 09:07:38 +00:00
|
|
|
return m_window;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowItem::handleWindowClosed(Toplevel *original, Deleted *deleted)
|
|
|
|
{
|
|
|
|
Q_UNUSED(original)
|
|
|
|
m_window = deleted;
|
|
|
|
}
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
void WindowItem::updateSurfaceItem(SurfaceItem *surfaceItem)
|
|
|
|
{
|
2021-02-04 09:07:20 +00:00
|
|
|
m_surfaceItem.reset(surfaceItem);
|
|
|
|
|
2021-09-29 08:29:39 +00:00
|
|
|
if (m_surfaceItem) {
|
|
|
|
connect(m_window, &Toplevel::shadeChanged, this, &WindowItem::updateSurfaceVisibility);
|
|
|
|
connect(m_window, &Toplevel::bufferGeometryChanged, this, &WindowItem::updateSurfacePosition);
|
|
|
|
connect(m_window, &Toplevel::frameGeometryChanged, this, &WindowItem::updateSurfacePosition);
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2021-09-29 08:29:39 +00:00
|
|
|
updateSurfacePosition();
|
|
|
|
updateSurfaceVisibility();
|
|
|
|
} else {
|
|
|
|
disconnect(m_window, &Toplevel::shadeChanged, this, &WindowItem::updateSurfaceVisibility);
|
|
|
|
disconnect(m_window, &Toplevel::bufferGeometryChanged, this, &WindowItem::updateSurfacePosition);
|
|
|
|
disconnect(m_window, &Toplevel::frameGeometryChanged, this, &WindowItem::updateSurfacePosition);
|
|
|
|
}
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WindowItem::updateSurfacePosition()
|
|
|
|
{
|
2021-08-12 09:07:38 +00:00
|
|
|
const QRect bufferGeometry = m_window->bufferGeometry();
|
|
|
|
const QRect frameGeometry = m_window->frameGeometry();
|
2021-02-04 09:07:20 +00:00
|
|
|
|
|
|
|
m_surfaceItem->setPosition(bufferGeometry.topLeft() - frameGeometry.topLeft());
|
|
|
|
}
|
|
|
|
|
2021-05-26 09:27:27 +00:00
|
|
|
void WindowItem::updateSurfaceVisibility()
|
|
|
|
{
|
2021-08-12 09:07:38 +00:00
|
|
|
m_surfaceItem->setVisible(!m_window->isShade());
|
2021-05-26 09:27:27 +00:00
|
|
|
}
|
|
|
|
|
2021-09-03 10:24:17 +00:00
|
|
|
void WindowItem::updateShadowItem()
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2021-09-03 10:24:17 +00:00
|
|
|
Shadow *shadow = m_window->shadow();
|
2021-02-04 09:07:20 +00:00
|
|
|
if (shadow) {
|
|
|
|
if (!m_shadowItem || m_shadowItem->shadow() != shadow) {
|
2021-08-12 09:07:38 +00:00
|
|
|
m_shadowItem.reset(new ShadowItem(shadow, m_window, this));
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
if (m_decorationItem) {
|
|
|
|
m_shadowItem->stackBefore(m_decorationItem.data());
|
|
|
|
} else if (m_surfaceItem) {
|
|
|
|
m_shadowItem->stackBefore(m_decorationItem.data());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m_shadowItem.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowItem::updateDecorationItem()
|
|
|
|
{
|
2022-04-14 13:50:12 +00:00
|
|
|
auto client = static_cast<AbstractClient *>(m_window->isClient() ? m_window : nullptr);
|
2021-02-04 09:07:20 +00:00
|
|
|
if (!client || client->isZombie()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (client->decoration()) {
|
2021-08-12 09:07:38 +00:00
|
|
|
m_decorationItem.reset(new DecorationItem(client->decoration(), client, this));
|
2021-02-04 09:07:20 +00:00
|
|
|
if (m_shadowItem) {
|
|
|
|
m_decorationItem->stackAfter(m_shadowItem.data());
|
|
|
|
} else if (m_surfaceItem) {
|
|
|
|
m_decorationItem->stackBefore(m_surfaceItem.data());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m_decorationItem.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
WindowItemX11::WindowItemX11(Toplevel *window, Item *parent)
|
2021-02-04 09:07:20 +00:00
|
|
|
: WindowItem(window, parent)
|
2021-09-29 08:29:39 +00:00
|
|
|
{
|
|
|
|
initialize();
|
|
|
|
|
|
|
|
// Xwayland windows and Wayland surfaces are associated asynchronously.
|
|
|
|
connect(window, &Toplevel::surfaceChanged, this, &WindowItemX11::initialize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowItemX11::initialize()
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
|
|
|
switch (kwinApp()->operationMode()) {
|
|
|
|
case Application::OperationModeX11:
|
2021-09-29 08:29:39 +00:00
|
|
|
updateSurfaceItem(new SurfaceItemX11(window(), this));
|
2021-02-04 09:07:20 +00:00
|
|
|
break;
|
|
|
|
case Application::OperationModeXwayland:
|
2021-09-29 08:29:39 +00:00
|
|
|
if (!window()->surface()) {
|
|
|
|
updateSurfaceItem(nullptr);
|
2021-02-04 09:07:20 +00:00
|
|
|
} else {
|
2021-09-29 08:29:39 +00:00
|
|
|
updateSurfaceItem(new SurfaceItemXwayland(window(), this));
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Application::OperationModeWaylandOnly:
|
|
|
|
Q_UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:07:38 +00:00
|
|
|
WindowItemWayland::WindowItemWayland(Toplevel *window, Item *parent)
|
2021-02-04 09:07:20 +00:00
|
|
|
: WindowItem(window, parent)
|
|
|
|
{
|
2021-08-12 09:07:38 +00:00
|
|
|
updateSurfaceItem(new SurfaceItemWayland(window->surface(), window, this));
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
2021-11-16 07:38:51 +00:00
|
|
|
WindowItemInternal::WindowItemInternal(InternalClient *window, Item *parent)
|
2021-02-04 09:07:20 +00:00
|
|
|
: WindowItem(window, parent)
|
|
|
|
{
|
|
|
|
updateSurfaceItem(new SurfaceItemInternal(window, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace KWin
|