Advance Wayland and KDE package bring-up

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-14 10:51:06 +01:00
parent 51f3c21121
commit cf12defd28
15214 changed files with 20594243 additions and 269 deletions
@@ -0,0 +1,513 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2019 Martin Flöser <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "internalwindow.h"
#include "decorations/decorationbridge.h"
#include "scene/surfaceitem.h"
#include "scene/windowitem.h"
#include "workspace.h"
#include <KDecoration3/Decoration>
#include <QMouseEvent>
#include <QWindow>
#include <qpa/qwindowsysteminterface.h>
Q_DECLARE_METATYPE(NET::WindowType)
static const QByteArray s_skipClosePropertyName = QByteArrayLiteral("KWIN_SKIP_CLOSE_ANIMATION");
static const QByteArray s_shadowEnabledPropertyName = QByteArrayLiteral("kwin_shadow_enabled");
namespace KWin
{
InternalWindow::InternalWindow(QWindow *handle)
: m_handle(handle)
, m_internalWindowFlags(handle->flags())
{
// TODO: The geometry data flow is error-prone. Consider adopting the configure event design from xdg-shell.
connect(m_handle, &QWindow::xChanged, this, &InternalWindow::updateInternalWindowGeometry);
connect(m_handle, &QWindow::yChanged, this, &InternalWindow::updateInternalWindowGeometry);
connect(m_handle, &QWindow::widthChanged, this, &InternalWindow::updateInternalWindowGeometry);
connect(m_handle, &QWindow::heightChanged, this, &InternalWindow::updateInternalWindowGeometry);
connect(m_handle, &QWindow::windowTitleChanged, this, &InternalWindow::setCaption);
connect(m_handle, &QWindow::opacityChanged, this, &InternalWindow::setOpacity);
connect(m_handle, &QWindow::destroyed, this, &InternalWindow::destroyWindow);
setOutput(workspace()->activeOutput());
setMoveResizeOutput(workspace()->activeOutput());
setCaption(m_handle->title());
setIcon(QIcon::fromTheme(QStringLiteral("kwin")));
setOnAllDesktops(true);
setOpacity(m_handle->opacity());
setSkipCloseAnimation(m_handle->property(s_skipClosePropertyName).toBool());
updateColorScheme();
updateShadow();
setMoveResizeGeometry(m_handle->geometry());
commitGeometry(m_handle->geometry());
updateDecoration(true);
m_handle->installEventFilter(this);
}
InternalWindow::~InternalWindow()
{
}
std::unique_ptr<WindowItem> InternalWindow::createItem(Item *parentItem)
{
return std::make_unique<WindowItemInternal>(this, parentItem);
}
bool InternalWindow::isClient() const
{
return true;
}
bool InternalWindow::hitTest(const QPointF &point) const
{
if (!Window::hitTest(point)) {
return false;
}
const QRegion mask = m_handle->mask();
if (!mask.isEmpty() && !mask.contains(mapToLocal(point).toPoint())) {
return false;
} else if (m_handle->property("outputOnly").toBool()) {
return false;
}
return true;
}
void InternalWindow::pointerEnterEvent(const QPointF &globalPos)
{
Window::pointerEnterEvent(globalPos);
QEnterEvent enterEvent(pos(), pos(), globalPos);
QCoreApplication::sendEvent(m_handle, &enterEvent);
}
void InternalWindow::pointerLeaveEvent()
{
if (!m_handle) {
return;
}
Window::pointerLeaveEvent();
QEvent event(QEvent::Leave);
QCoreApplication::sendEvent(m_handle, &event);
}
bool InternalWindow::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_handle && event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent *>(event);
if (pe->propertyName() == s_skipClosePropertyName) {
setSkipCloseAnimation(m_handle->property(s_skipClosePropertyName).toBool());
}
if (pe->propertyName() == s_shadowEnabledPropertyName) {
updateShadow();
}
}
return false;
}
qreal InternalWindow::bufferScale() const
{
if (m_handle) {
return m_handle->devicePixelRatio();
}
return 1;
}
QString InternalWindow::captionNormal() const
{
return m_captionNormal;
}
QString InternalWindow::captionSuffix() const
{
return m_captionSuffix;
}
QSizeF InternalWindow::minSize() const
{
return m_handle->minimumSize();
}
QSizeF InternalWindow::maxSize() const
{
return m_handle->maximumSize();
}
WindowType InternalWindow::windowType() const
{
return WindowType::Normal;
}
void InternalWindow::killWindow()
{
// We don't kill our internal windows.
}
bool InternalWindow::isPopupWindow() const
{
if (Window::isPopupWindow()) {
return true;
}
return m_internalWindowFlags.testFlag(Qt::Popup);
}
QString InternalWindow::windowRole() const
{
return QString();
}
void InternalWindow::closeWindow()
{
if (!isDeleted()) {
QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(m_handle);
}
}
bool InternalWindow::isCloseable() const
{
return true;
}
bool InternalWindow::isMovable() const
{
if (!options->interactiveWindowMoveEnabled()) {
return false;
}
return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
}
bool InternalWindow::isMovableAcrossScreens() const
{
return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
}
bool InternalWindow::isResizable() const
{
return true;
}
bool InternalWindow::isPlaceable() const
{
return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
}
bool InternalWindow::noBorder() const
{
return m_userNoBorder || m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
}
bool InternalWindow::userCanSetNoBorder() const
{
return !m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
}
bool InternalWindow::wantsInput() const
{
return false;
}
bool InternalWindow::isInternal() const
{
return true;
}
bool InternalWindow::isLockScreen() const
{
if (m_handle) {
return m_handle->property("org_kde_ksld_emergency").toBool();
}
return false;
}
bool InternalWindow::isOutline() const
{
if (m_handle) {
return m_handle->property("__kwin_outline").toBool();
}
return false;
}
QRectF InternalWindow::resizeWithChecks(const QRectF &geometry, const QSizeF &size)
{
if (!m_handle) {
return geometry;
}
const QRectF area = workspace()->clientArea(WorkArea, this, geometry.center());
return QRectF(moveResizeGeometry().topLeft(), size.boundedTo(area.size()));
}
void InternalWindow::moveResizeInternal(const QRectF &rect, MoveResizeMode mode)
{
const QSize requestedClientSize = nextFrameSizeToClientSize(rect.size()).toSize();
if (clientSize() == requestedClientSize) {
commitGeometry(rect);
} else {
requestGeometry(rect);
}
}
bool InternalWindow::takeFocus()
{
return false;
}
void InternalWindow::setNoBorder(bool set)
{
if (!userCanSetNoBorder()) {
return;
}
if (m_userNoBorder == set) {
return;
}
m_userNoBorder = set;
updateDecoration(true);
}
void InternalWindow::createDecoration(const QRectF &oldGeometry)
{
std::shared_ptr<KDecoration3::Decoration> decoration(Workspace::self()->decorationBridge()->createDecoration(this));
if (decoration) {
decoration->apply(decoration->nextState()->clone());
connect(decoration.get(), &KDecoration3::Decoration::nextStateChanged, this, [this](auto state) {
if (!isDeleted()) {
m_decoration.decoration->apply(state->clone());
}
});
}
setDecoration(decoration);
moveResize(QRectF(oldGeometry.topLeft(), nextClientSizeToFrameSize(clientSize())));
}
void InternalWindow::destroyDecoration()
{
const QSizeF clientSize = nextFrameSizeToClientSize(moveResizeGeometry().size());
setDecoration(nullptr);
resize(clientSize);
}
void InternalWindow::updateDecoration(bool check_workspace_pos, bool force)
{
if (!force && isDecorated() == !noBorder()) {
return;
}
const QRectF oldFrameGeometry = frameGeometry();
if (force) {
destroyDecoration();
}
if (!noBorder()) {
createDecoration(oldFrameGeometry);
} else {
destroyDecoration();
}
updateShadow();
if (check_workspace_pos) {
checkWorkspacePosition(oldFrameGeometry);
}
}
void InternalWindow::invalidateDecoration()
{
updateDecoration(true, true);
}
void InternalWindow::destroyWindow()
{
m_handle->removeEventFilter(this);
m_handle->disconnect(this);
markAsDeleted();
stopDelayedInteractiveMoveResize();
if (isInteractiveMoveResize()) {
leaveInteractiveMoveResize();
Q_EMIT interactiveMoveResizeFinished();
}
Q_EMIT closed();
commitTile(nullptr);
workspace()->removeInternalWindow(this);
m_handle = nullptr;
unref();
}
bool InternalWindow::hasPopupGrab() const
{
return !m_handle->flags().testFlag(Qt::WindowTransparentForInput) && m_handle->flags().testFlag(Qt::Popup) && !m_handle->flags().testFlag(Qt::ToolTip);
}
void InternalWindow::popupDone()
{
m_handle->close();
}
GraphicsBuffer *InternalWindow::graphicsBuffer() const
{
return m_graphicsBufferRef.buffer();
}
GraphicsBufferOrigin InternalWindow::graphicsBufferOrigin() const
{
return m_graphicsBufferOrigin;
}
void InternalWindow::present(const InternalWindowFrame &frame)
{
const QSize bufferSize = frame.buffer->size() / bufferScale();
QRectF geometry(pos(), clientSizeToFrameSize(bufferSize));
if (isInteractiveResize()) {
geometry = gravitateGeometry(geometry, moveResizeGeometry(), interactiveMoveResizeGravity());
}
commitGeometry(geometry);
m_graphicsBufferRef = frame.buffer;
m_graphicsBufferOrigin = frame.bufferOrigin;
if (surfaceItem()) {
surfaceItem()->addDamage(frame.bufferDamage);
}
markAsMapped();
}
QWindow *InternalWindow::handle() const
{
return m_handle;
}
bool InternalWindow::acceptsFocus() const
{
return false;
}
bool InternalWindow::belongsToSameApplication(const Window *other, SameApplicationChecks checks) const
{
const InternalWindow *otherInternal = qobject_cast<const InternalWindow *>(other);
if (!otherInternal) {
return false;
}
if (otherInternal == this) {
return true;
}
return otherInternal->handle()->isAncestorOf(handle()) || handle()->isAncestorOf(otherInternal->handle());
}
void InternalWindow::doInteractiveResizeSync(const QRectF &rect)
{
moveResize(rect);
}
void InternalWindow::updateCaption()
{
const QString suffix = shortcutCaptionSuffix();
if (m_captionSuffix != suffix) {
m_captionSuffix = suffix;
Q_EMIT captionChanged();
}
}
void InternalWindow::requestGeometry(const QRectF &rect)
{
if (m_handle) {
m_handle->setGeometry(nextFrameRectToClientRect(rect).toRect());
}
}
void InternalWindow::commitGeometry(const QRectF &rect)
{
// The client geometry and the buffer geometry are the same.
const QRectF oldClientGeometry = m_clientGeometry;
const QRectF oldFrameGeometry = m_frameGeometry;
const Output *oldOutput = m_output;
Q_EMIT frameGeometryAboutToChange();
m_clientGeometry = frameRectToClientRect(rect);
m_frameGeometry = rect;
m_bufferGeometry = m_clientGeometry;
if (oldClientGeometry == m_clientGeometry && oldFrameGeometry == m_frameGeometry) {
return;
}
m_output = workspace()->outputAt(rect.center());
syncGeometryToInternalWindow();
if (oldClientGeometry != m_clientGeometry) {
Q_EMIT bufferGeometryChanged(oldClientGeometry);
Q_EMIT clientGeometryChanged(oldClientGeometry);
}
if (oldFrameGeometry != m_frameGeometry) {
Q_EMIT frameGeometryChanged(oldFrameGeometry);
}
if (oldOutput != m_output) {
Q_EMIT outputChanged();
}
}
void InternalWindow::setCaption(const QString &caption)
{
if (m_captionNormal == caption) {
return;
}
m_captionNormal = caption;
Q_EMIT captionNormalChanged();
Q_EMIT captionChanged();
}
void InternalWindow::markAsMapped()
{
if (!ready_for_painting) {
setupCompositing();
setReadyForPainting();
workspace()->addInternalWindow(this);
}
}
void InternalWindow::syncGeometryToInternalWindow()
{
if (m_handle->geometry() == frameRectToClientRect(frameGeometry()).toRect()) {
return;
}
QTimer::singleShot(0, this, [this] {
requestGeometry(frameGeometry());
});
}
void InternalWindow::updateInternalWindowGeometry()
{
if (!isInteractiveMoveResize()) {
const QRectF rect = clientRectToFrameRect(m_handle->geometry());
setMoveResizeGeometry(rect);
commitGeometry(rect);
}
}
}
#include "moc_internalwindow.cpp"