diff options
author | Matt Hoosier <matt.hoosier@garmin.com> | 2018-06-18 14:21:48 -0500 |
---|---|---|
committer | Matt Hoosier <matt.hoosier@garmin.com> | 2018-06-25 13:32:46 +0000 |
commit | fbcb9769d3f1748b95e243064fd0b6da8215f3b9 (patch) | |
tree | 111092ba6966e36d4e5c1cdb740b98500e8cba40 | |
parent | 22d7a77315e0475e6f91d2a60365b7694934541f (diff) |
Compositor: add API for using existing socket fd's
This adds functionality to allow system-level control over handing out
file descriptors for sockets. In particular, it allows writing socket-
activated compositors.
[ChangeLog][Compositor] Added API for installing a socket on which bind()
and listen() have already been called into the event dispatch loop. This
facilitates socket-activated compositors.
Change-Id: I620f5ad0a3c3c5c4ecb937004230dcd024df8f69
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.cpp | 56 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.h | 2 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor_p.h | 8 |
3 files changed, 66 insertions, 0 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 8c476cf1c..b0e3cbd24 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -193,6 +193,10 @@ void QWaylandCompositorPrivate::init() emit q->socketNameChanged(socket_name); } +#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10) + connectToExternalSockets(); +#endif + loop = wl_display_get_event_loop(display); int fd = wl_event_loop_get_fd(loop); @@ -274,6 +278,18 @@ void QWaylandCompositorPrivate::addPolishObject(QObject *object) } } +#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10) +void QWaylandCompositorPrivate::connectToExternalSockets() +{ + // Clear out any backlog of user-supplied external socket descriptors + for (int fd : qAsConst(externally_added_socket_fds)) { + if (wl_display_add_socket_fd(display, fd) != 0) + qWarning() << "Failed to integrate user-supplied socket fd into the Wayland event loop"; + } + externally_added_socket_fds.clear(); +} +#endif + void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) { Q_Q(QWaylandCompositor); @@ -552,6 +568,46 @@ QByteArray QWaylandCompositor::socketName() const } /*! + * \qmlmethod QtWaylandCompositor::WaylandCompositor::addSocketFd(fd) + * \since 5.12 + * + * Listen for client connections on a file descriptor referring to a + * server socket already bound and listening. + * + * Does not take ownership of the file descriptor; it must be closed + * explicitly if needed. + * + * \note This method is only available with libwayland 1.10.0 or + * newer. If built against an earlier libwayland runtime, this + * method is a noop. + */ + +/*! + * Listen for client connections on a file descriptor referring to a + * server socket already bound and listening. + * + * Does not take ownership of the file descriptor; it must be closed + * explicitly if needed. + * + * \note This method is only available with libwayland 1.10.0 or + * newer. If built against an earlier libwayland runtime, this + * method is a noop. + * + * \since 5.12 + */ +void QWaylandCompositor::addSocketFd(int fd) +{ +#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10) + Q_D(QWaylandCompositor); + d->externally_added_socket_fds.append(fd); + if (isCreated()) + d->connectToExternalSockets(); +#else + qWarning() << "QWaylandCompositor::addSocketFd() does nothing on libwayland versions prior to 1.10.0"; +#endif +} + +/*! * \internal */ struct wl_display *QWaylandCompositor::display() const diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index 23844d72a..72b8f2d1b 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -93,6 +93,8 @@ public: void setSocketName(const QByteArray &name); QByteArray socketName() const; + Q_INVOKABLE void addSocketFd(int fd); + ::wl_display *display() const; uint32_t nextSerial(); diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h index 0d259ee84..cdf4be6b4 100644 --- a/src/compositor/compositor_api/qwaylandcompositor_p.h +++ b/src/compositor/compositor_api/qwaylandcompositor_p.h @@ -112,6 +112,11 @@ public: inline void addOutput(QWaylandOutput *output); inline void removeOutput(QWaylandOutput *output); + +#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10) + void connectToExternalSockets(); +#endif + protected: void compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) override; void compositor_create_region(wl_compositor::Resource *resource, uint32_t id) override; @@ -128,6 +133,9 @@ protected: void loadServerBufferIntegration(); QByteArray socket_name; +#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10) + QList<int> externally_added_socket_fds; +#endif struct wl_display *display = nullptr; QList<QWaylandSeat *> seats; |