From 69a13a779d49629be6a9209d82afca40794df1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 25 Feb 2015 14:15:32 +0100 Subject: [PATCH] [kwin_wayland] Start Xwayland through socket file descriptor Creates a socketpair in WaylandServer and creates a ClientConnection for Xwayland. The created file descriptor is passed to Xwayland through the WAYLAND_SOCKET env variable. --- main_wayland.cpp | 22 ++++++++++++++++++---- wayland_server.cpp | 15 +++++++++++++++ wayland_server.h | 7 +++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/main_wayland.cpp b/main_wayland.cpp index 0931ff9ac8..d5babeef04 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -56,7 +56,7 @@ static void sighandler(int) QApplication::exit(); } -static int startXServer(const QByteArray &waylandSocket, int wmFd); +static int startXServer(int waylandSocket, int wmFd); static void readDisplay(int pipe); //************************************ @@ -115,8 +115,15 @@ void ApplicationWayland::continueStartupWithScreens() return; } + const int fd = waylandServer()->createXWaylandConnection(); + if (fd == -1) { + std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl; + exit(1); + return; + } + m_xcbConnectionFd = sx[0]; - const int xDisplayPipe = startXServer(WaylandServer::self()->display()->socketName().toUtf8(), sx[1]); + const int xDisplayPipe = startXServer(fd, sx[1]); QFutureWatcher *watcher = new QFutureWatcher(this); QObject::connect(watcher, &QFutureWatcher::finished, this, &ApplicationWayland::continueStartupWithX, Qt::QueuedConnection); QObject::connect(watcher, &QFutureWatcher::finished, watcher, &QFutureWatcher::deleteLater, Qt::QueuedConnection); @@ -214,7 +221,7 @@ void ApplicationWayland::createX11Connection() * Starts the Xwayland-Server. * The new process is started by forking into it. **/ -static int startXServer(const QByteArray &waylandSocket, int wmFd) +static int startXServer(int waylandSocket, int wmFd) { int pipeFds[2]; if (pipe(pipeFds) != 0) { @@ -237,7 +244,14 @@ static int startXServer(const QByteArray &waylandSocket, int wmFd) return -1; } sprintf(wmfdbuf, "%d", fd); - qputenv("WAYLAND_DISPLAY", waylandSocket.isEmpty() ? QByteArrayLiteral("wayland-0") : waylandSocket); + + int wlfd = dup(waylandSocket); + if (wlfd < 0) { + std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl; + exit(20); + return -1; + } + qputenv("WAYLAND_SOCKET", QByteArray::number(wlfd)); execlp("Xwayland", "Xwayland", "-displayfd", fdbuf, "-rootless", "-wm", wmfdbuf, (char *)0); close(pipeFds[1]); exit(20); diff --git a/wayland_server.cpp b/wayland_server.cpp index 6bb59751f3..37f1257920 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -28,6 +28,10 @@ along with this program. If not, see . #include #include +// system +#include +#include + using namespace KWayland::Server; namespace KWin @@ -87,4 +91,15 @@ void WaylandServer::initOutputs() } } +int WaylandServer::createXWaylandConnection() +{ + int sx[2]; + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) { + qCWarning(KWIN_CORE) << "Could not create socket"; + return -1; + } + m_xwaylandConnection = m_display->createClient(sx[0]); + return sx[1]; +} + } diff --git a/wayland_server.h b/wayland_server.h index 68399d97d0..a4e1b14c54 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -28,6 +28,7 @@ namespace KWayland { namespace Server { +class ClientConnection; class CompositorInterface; class Display; class ShellInterface; @@ -60,11 +61,17 @@ public: return m_shell; } + /** + * @returns file descriptor for Xwayland to connect to. + **/ + int createXWaylandConnection(); + private: KWayland::Server::Display *m_display = nullptr; KWayland::Server::CompositorInterface *m_compositor = nullptr; KWayland::Server::SeatInterface *m_seat = nullptr; KWayland::Server::ShellInterface *m_shell = nullptr; + KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr; KWIN_SINGLETON(WaylandServer) };