1 /* 2 KWin - the KDE window manager 3 This file is part of the KDE project. 4 5 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com> 6 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 7 8 SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 #ifndef KWIN_XWL_XWAYLAND 11 #define KWIN_XWL_XWAYLAND 12 13 #include "xwayland_interface.h" 14 15 #include <QProcess> 16 #include <QSocketNotifier> 17 #include <QTemporaryFile> 18 19 class KSelectionOwner; 20 21 namespace KWin 22 { 23 class ApplicationWaylandAbstract; 24 class XwaylandSocket; 25 26 namespace Xwl 27 { 28 29 class Xwayland : public XwaylandInterface 30 { 31 Q_OBJECT 32 33 public: 34 Xwayland(ApplicationWaylandAbstract *app, QObject *parent = nullptr); 35 ~Xwayland() override; 36 37 /** 38 * Returns the associated Xwayland process or @c null if the Xwayland server is inactive. 39 */ 40 QProcess *process() const override; 41 42 /** 43 * Set file descriptors that xwayland should use for listening 44 * This is to be used in conjuction with kwin_wayland_wrapper which creates a socket externally 45 * That external process is responsible for setting up the DISPLAY env with a valid value. 46 * Ownership of the file descriptor is not transferrred. 47 */ 48 void setListenFDs(const QVector<int> &listenFds); 49 50 /** 51 * Sets the display name used by XWayland (i.e ':0') 52 * This is to be used in conjuction with kwin_wayland_wrapper to provide the name of the socket 53 * created externally 54 */ 55 void setDisplayName(const QString &displayName); 56 57 /** 58 * Sets the xauthority file to be used by XWayland 59 * This is to be used in conjuction with kwin_wayland_wrapper 60 */ 61 void setXauthority(const QString &xauthority); 62 63 public Q_SLOTS: 64 /** 65 * Starts the Xwayland server. 66 * 67 * This method will spawn an Xwayland process and will establish a new XCB connection to it. 68 * If an error has occurred during the startup, the errorOccurred() signal is going to 69 * be emitted. If the Xwayland server has started successfully, the started() signal will be 70 * emitted. 71 * 72 * @see started(), stop() 73 */ 74 void start(); 75 /** 76 * Stops the Xwayland server. 77 * 78 * This method will destroy the existing XCB connection as well all connected X11 clients. 79 * 80 * A SIGTERM signal will be sent to the Xwayland process. If Xwayland doesn't shut down 81 * within a reasonable amount of time (5 seconds), a SIGKILL signal will be sent and thus 82 * the process will be killed for good. 83 * 84 * If the Xwayland process crashes, the server will be stopped automatically. 85 * 86 * @see start() 87 */ 88 void stop(); 89 90 Q_SIGNALS: 91 /** 92 * This signal is emitted when the Xwayland server has been started successfully and it is 93 * ready to accept and manage X11 clients. 94 */ 95 void started(); 96 /** 97 * This signal is emitted when an error occurs with the Xwayland server. 98 */ 99 void errorOccurred(); 100 101 private Q_SLOTS: 102 void dispatchEvents(); 103 void resetCrashCount(); 104 105 void handleXwaylandFinished(int exitCode, QProcess::ExitStatus exitStatus); 106 void handleXwaylandCrashed(); 107 void handleXwaylandError(QProcess::ProcessError error); 108 void handleXwaylandReady(); 109 110 void handleSelectionLostOwnership(); 111 void handleSelectionFailedToClaimOwnership(); 112 void handleSelectionClaimedOwnership(); 113 114 private: 115 void installSocketNotifier(); 116 void uninstallSocketNotifier(); 117 void maybeDestroyReadyNotifier(); 118 119 bool startInternal(); 120 void stopInternal(); 121 void restartInternal(); 122 123 bool createX11Connection(); 124 void destroyX11Connection(); 125 126 DragEventReply dragMoveFilter(Toplevel *target, const QPoint &pos) override; 127 KWaylandServer::AbstractDropHandler *xwlDropHandler() override; 128 129 int m_xcbConnectionFd = -1; 130 QProcess *m_xwaylandProcess = nullptr; 131 QSocketNotifier *m_socketNotifier = nullptr; 132 QSocketNotifier *m_readyNotifier = nullptr; 133 QTimer *m_resetCrashCountTimer = nullptr; 134 ApplicationWaylandAbstract *m_app; 135 QScopedPointer<KSelectionOwner> m_selectionOwner; 136 // this is only used when kwin is run without kwin_wayland_wrapper 137 QScopedPointer<XwaylandSocket> m_socket; 138 139 QVector<int> m_listenFds; 140 QString m_displayName; 141 QString m_xAuthority; 142 143 int m_crashCount = 0; 144 145 Q_DISABLE_COPY(Xwayland) 146 }; 147 148 } // namespace Xwl 149 } // namespace KWin 150 151 #endif 152