QtWayland是Qt官方基于Wayland开发的一款Toolbox,根据其官网介绍
The QtWayland module consists of two parts:
Wayland platform plugin:
Enables Qt applications to be run as Wayland clients.
QtWaylandCompositor API:
Enables the creation of Wayland compositors using Qt and QtQuick.
可以将QtWayland的功能归纳为两点:
本文基于QtWayland 6.4的源码,对其模块框架及Compositor启动流程进行分析。
// src\compositor\compositor_api\qwaylandcompositor.h
class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandCompositor : public QWaylandObject
{Q_OBJECT// 对应类 QWaylandCompositorPrivate Q_DECLARE_PRIVATE(QWaylandCompositor)// ...
public:QWaylandCompositor(QObject *parent = nullptr);~QWaylandCompositor() override;
}// src\compositor\compositor_api\qwaylandcompositor_p.h
class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandCompositorPrivate : public QObjectPrivate, public QtWaylandServer::wl_compositor, public QtWaylandServer::wl_subcompositor
{
public:QWaylandCompositorPrivate(QWaylandCompositor *compositor);~QWaylandCompositorPrivate() override;
}
// new QWaylandCompositor(),因为它提供默认参数,所以可以不传参数
QWaylandCompositor::QWaylandCompositor(QObject *parent): QWaylandObject(*new QWaylandCompositorPrivate(this), parent)
{
}
// new QWaylandCompositorPrivate
QWaylandCompositorPrivate::QWaylandCompositorPrivate(QWaylandCompositor *compositor)
{// ...// 创建Display(全局Display)if (!display) {display = wl_display_create();ownsDisplay = true;}// ...
}
/** Initializes the QWaylandCompositor.* If you override this function in your subclass, be sure to call the base class implementation.*/
void QWaylandCompositor::create()
{Q_D(QWaylandCompositor);// d 是QWaylandCompositorPrivate// 大部分初始化是在 QWaylandCompositorPrivate::init中实现d->preInit();d->init();
}void QWaylandCompositorPrivate::init()
{// 设置Server端Socket名字// Socket用来跟Client端进行协议通讯if (socket_name.isEmpty()) {const int socketArg = arguments.indexOf(QLatin1String("--wayland-socket-name"));if (socketArg != -1 && socketArg + 1 < arguments.size())socket_name = arguments.at(socketArg + 1).toLocal8Bit();}// 这里初始化了wl_compositor/wl_subcompositor协议// 这里会调用到wl_global_create,将全局对象发布到display上wl_compositor::init(display, 4);wl_subcompositor::init(display, 1);// 初始化shmwl_display_init_shm(display);// 创建Server端Socket// Socket用于跟Client端通信if (!socket_name.isEmpty()) {if (wl_display_add_socket(display, socket_name.constData()))qFatal("Fatal: Failed to open server socket: \"%s\". XDG_RUNTIME_DIR is: \"%s\"\n", socket_name.constData(), getenv("XDG_RUNTIME_DIR"));} else {const char *autoSocketName = wl_display_add_socket_auto(display);if (!autoSocketName)qFatal("Fatal: Failed to open default server socket. XDG_RUNTIME_DIR is: \"%s\"\n", getenv("XDG_RUNTIME_DIR"));socket_name = autoSocketName;emit q->socketNameChanged(socket_name);}// 拿到looploop = wl_display_get_event_loop(display);int fd = wl_event_loop_get_fd(loop);// 通过Qt的QSocketNotifier 监听fd,当有读事件时触发回调processWaylandEventsQSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, q);QObject::connect(sockNot, SIGNAL(activated(QSocketDescriptor)), q, SLOT(processWaylandEvents()));QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;QObject::connect(dispatcher, SIGNAL(aboutToBlock()), q, SLOT(processWaylandEvents()));}