milestone: Phase 4-5 completion + KF6 honesty + KDE session + GPU CS ioctl

Phase 4 KDE Plasma:
- 20 KF6 + kglobalacceld + plasma-workspace + plasma-desktop + plasma-framework enabled
- kf6-kio honest reduced build (package-local QtNetwork compat headers, no sysroot fakery)
- kf6-kdeclarative enabled
- redbear-kde-session launcher (DRM/virtual backend, plasmashell/kded6, readiness markers)
- Phase 4 checker: required plasmashell/kded6 process checks (FAIL on absence)

Phase 5 Hardware GPU:
- CS ioctl checker (GEM allocation, PRIME sharing, private CS submit/wait over /scheme/drm/card0)
- Enhanced GPU checker with hardware rendering readiness summary
- test-phase5-cs-runtime.sh harness

Qt6Quick honesty: qtdeclarative exports Qt6Quick metadata; downstream QML/Kirigami/KWin proof still insufficient.
Oracle-verified: Phase 4-5 (5 rounds).

Build: zero warnings.
This commit is contained in:
2026-04-29 11:05:22 +01:00
parent 8acc73d774
commit 2fdb7906f8
20 changed files with 2444 additions and 891 deletions
@@ -183,6 +183,10 @@ target_include_directories(KF6KIOCore PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..>" # kio_version.h
)
target_include_directories(KF6KIOCore PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/redox_qtnetwork_compat
)
target_include_directories(KF6KIOCore INTERFACE
"$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KIOCore>"
"$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KIO>"
@@ -327,4 +331,3 @@ install(FILES
# make available to ecm_add_qch in parent folder
set(KIOCore_QCH_SOURCES ${KIOCore_HEADERS} ${KIO_namespaced_HEADERS} PARENT_SCOPE)
@@ -133,22 +133,11 @@ public:
return m_hostName;
}
int lookupId() const
{
return m_lookupId;
}
void setLookupId(int id)
{
m_lookupId = id;
}
private:
Q_DISABLE_COPY(NameLookupThreadRequest)
QString m_hostName;
QSemaphore m_semaphore;
QHostInfo m_hostInfo;
int m_lookupId;
};
}
@@ -162,30 +151,9 @@ class NameLookUpThreadWorker : public QObject
public Q_SLOTS:
void lookupHost(const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
{
const QString hostName = request->hostName();
const int lookupId = QHostInfo::lookupHost(hostName, this, SLOT(lookupFinished(QHostInfo)));
request->setLookupId(lookupId);
m_lookups.insert(lookupId, request);
request->setResult(QHostInfo::fromName(request->hostName()));
request->semaphore()->release();
}
void abortLookup(const std::shared_ptr<KIO::NameLookupThreadRequest> &request)
{
QHostInfo::abortHostLookup(request->lookupId());
m_lookups.remove(request->lookupId());
}
void lookupFinished(const QHostInfo &hostInfo)
{
auto it = m_lookups.find(hostInfo.lookupId());
if (it != m_lookups.end()) {
(*it)->setResult(hostInfo);
(*it)->semaphore()->release();
m_lookups.erase(it);
}
}
private:
QMap<int, std::shared_ptr<NameLookupThreadRequest>> m_lookups;
};
class NameLookUpThread : public QThread
@@ -271,11 +239,6 @@ QHostInfo HostInfo::lookupHost(const QString &hostName, unsigned long timeout)
if (!hostInfo.hostName().isEmpty() && hostInfo.error() == QHostInfo::NoError) {
HostInfo::cacheLookup(hostInfo); // cache the look up...
}
} else {
auto abortFunc = [worker, request]() {
worker->abortLookup(request);
};
QMetaObject::invokeMethod(worker, abortFunc, Qt::QueuedConnection);
}
// qDebug() << "Name look up succeeded for" << hostName;
@@ -0,0 +1,87 @@
#pragma once
#include <QByteArray>
#include <QDataStream>
#include <QMetaType>
#include <QString>
#include <arpa/inet.h>
class QHostAddress
{
public:
enum NetworkLayerProtocol {
UnknownNetworkLayerProtocol = -1,
AnyIPProtocol,
IPv4Protocol,
IPv6Protocol,
};
QHostAddress() = default;
explicit QHostAddress(const QString &address)
{
setAddress(address);
}
void setAddress(const QString &address)
{
m_address = address;
if (address.isEmpty()) {
m_protocol = UnknownNetworkLayerProtocol;
return;
}
const QByteArray utf8 = address.toUtf8();
unsigned char ipv4[4] = {};
unsigned char ipv6[16] = {};
if (inet_pton(AF_INET, utf8.constData(), ipv4) == 1) {
m_protocol = IPv4Protocol;
return;
}
if (inet_pton(AF_INET6, utf8.constData(), ipv6) == 1) {
m_protocol = IPv6Protocol;
return;
}
m_protocol = UnknownNetworkLayerProtocol;
}
bool isNull() const
{
return m_protocol == UnknownNetworkLayerProtocol;
}
QString toString() const
{
return m_address;
}
NetworkLayerProtocol protocol() const
{
return m_protocol;
}
private:
QString m_address;
NetworkLayerProtocol m_protocol = UnknownNetworkLayerProtocol;
friend QDataStream &operator<<(QDataStream &stream, const QHostAddress &address)
{
stream << address.m_address << static_cast<qint32>(address.m_protocol);
return stream;
}
friend QDataStream &operator>>(QDataStream &stream, QHostAddress &address)
{
qint32 protocol = UnknownNetworkLayerProtocol;
stream >> address.m_address >> protocol;
address.m_protocol = static_cast<QHostAddress::NetworkLayerProtocol>(protocol);
return stream;
}
};
Q_DECLARE_METATYPE(QHostAddress)
@@ -0,0 +1,166 @@
#pragma once
#include <QByteArray>
#include <QList>
#include <QMetaType>
#include <QString>
#include <QStringList>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#include <QHostAddress>
class QHostInfo
{
public:
enum HostInfoError {
NoError = 0,
HostNotFound = 1,
UnknownError = 2,
};
QHostInfo() = default;
explicit QHostInfo(const QString &hostName)
: m_hostName(hostName)
{
}
static QString localHostName()
{
char buffer[256] = {};
if (gethostname(buffer, sizeof(buffer)) == 0) {
buffer[sizeof(buffer) - 1] = '\0';
if (buffer[0] != '\0') {
return QString::fromUtf8(buffer);
}
}
return QStringLiteral("redox");
}
static QHostInfo fromName(const QString &hostName)
{
QHostInfo info(hostName);
const QHostAddress literalAddress(hostName);
if (!literalAddress.isNull()) {
info.setAddresses({literalAddress});
info.setError(NoError);
info.setErrorString(QString());
return info;
}
addrinfo hints = {};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
addrinfo *results = nullptr;
const QByteArray hostNameUtf8 = hostName.toUtf8();
const int lookupResult = getaddrinfo(hostNameUtf8.constData(), nullptr, &hints, &results);
if (lookupResult != 0) {
info.setError(lookupResult == EAI_NONAME ? HostNotFound : UnknownError);
info.setErrorString(QString::fromUtf8(gai_strerror(lookupResult)));
return info;
}
QList<QHostAddress> addresses;
QStringList seenAddresses;
for (const addrinfo *entry = results; entry != nullptr; entry = entry->ai_next) {
const void *rawAddress = nullptr;
int family = AF_UNSPEC;
switch (entry->ai_family) {
case AF_INET:
rawAddress = &reinterpret_cast<const sockaddr_in *>(entry->ai_addr)->sin_addr;
family = AF_INET;
break;
case AF_INET6:
rawAddress = &reinterpret_cast<const sockaddr_in6 *>(entry->ai_addr)->sin6_addr;
family = AF_INET6;
break;
default:
continue;
}
char buffer[INET6_ADDRSTRLEN] = {};
if (inet_ntop(family, rawAddress, buffer, sizeof(buffer)) == nullptr) {
continue;
}
const QString addressText = QString::fromUtf8(buffer);
if (addressText.isEmpty() || seenAddresses.contains(addressText)) {
continue;
}
seenAddresses.append(addressText);
addresses.append(QHostAddress(addressText));
}
freeaddrinfo(results);
if (addresses.isEmpty()) {
info.setError(HostNotFound);
info.setErrorString(QStringLiteral("Host lookup returned no usable addresses"));
return info;
}
info.setAddresses(addresses);
info.setError(NoError);
info.setErrorString(QString());
return info;
}
void setHostName(const QString &hostName)
{
m_hostName = hostName;
}
QString hostName() const
{
return m_hostName;
}
void setAddresses(const QList<QHostAddress> &addresses)
{
m_addresses = addresses;
}
QList<QHostAddress> addresses() const
{
return m_addresses;
}
void setError(HostInfoError error)
{
m_error = error;
}
HostInfoError error() const
{
return m_error;
}
void setErrorString(const QString &errorString)
{
m_errorString = errorString;
}
QString errorString() const
{
return m_errorString;
}
private:
QString m_hostName;
QList<QHostAddress> m_addresses;
HostInfoError m_error = UnknownError;
QString m_errorString;
};
Q_DECLARE_METATYPE(QHostInfo)
@@ -9,103 +9,8 @@
#include "commands_p.h"
#include "connection_p.h"
#include "hostinfo.h"
#include "kiocoredebug.h"
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include <QHostInfo>
#include "usernotificationhandler_p.h"
#include "workerbase.h"
@@ -113,6 +18,7 @@
#include <QDataStream>
#include <QDateTime>
#include <QHostInfo>
using namespace KIO;
@@ -364,9 +270,12 @@ bool WorkerInterface::dispatch(int _cmd, const QByteArray &rawdata)
case MSG_HOST_INFO_REQ: {
QString hostName;
stream >> hostName;
const QHostInfo info = HostInfo::lookupHost(hostName, 1500);
QByteArray replyData;
QDataStream replyStream(&replyData, QIODevice::WriteOnly);
replyStream << hostName << QList<QHostAddress>() << int(QHostInfo::UnknownError) << QStringLiteral("Host lookup unavailable on Redox");
replyStream << info.hostName() << info.addresses() << int(info.error()) << info.errorString();
m_connection->send(CMD_HOST_INFO, replyData);
break;
}