kwin/src/wayland_server.h

306 lines
9.7 KiB
C
Raw Normal View History

2020-08-02 22:22:19 +00:00
/*
KWin - the KDE window manager
This file is part of the KDE project.
2020-08-02 22:22:19 +00:00
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
2020-08-02 22:22:19 +00:00
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_WAYLAND_SERVER_H
#define KWIN_WAYLAND_SERVER_H
#include <kwinglobals.h>
#include <QObject>
#include <QPointer>
#include <QSet>
class QThread;
Support for syncing the clipboard from X11 to Wayland and vice versa Summary: The clipboard sync is done by a dedicated helper binary launched by KWin. This helper binary is forced to xcb platform to piggy-back on Qt's implementation of the X11 clipboard. In addition it implements the Wayland clipboard - which is much simpler. Reading the Wayland clipboard is based on the implementation in QtWayland. KWin internally knows the DataDeviceInterface belonging to the helper application. Whenever an xwayland client is focussed, this DataDevice is allowed to set the selection and KWin manually updates the current selection in the SeatInterface. By that the sync from X11 to Wayland is implemented. When afterwards a Wayland client is selected, it's sent the current selection which references the X clipboard and a data transfer can be initiated in the normal Wayland way. For the other direction KWin sends the current selection to the helper's DataDevice whenever an xwayland window is focused. The helper application reads the Wayland clipboard and sets it on the X11 clipboard. Thus the Wayland clipboard is synced to X11. The approach used here will also be useful for implementing a clipboard manager (aka klipper). Currently the implementation is not yet fully completed. We need to make sure that the helper application gets restarted in case of a crash. Test Plan: See added test case Reviewers: #plasma_on_wayland, #kwin Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D1973
2016-06-20 09:21:16 +00:00
class QProcess;
class QWindow;
namespace KWaylandServer
{
class AppMenuManagerInterface;
class ClientConnection;
class CompositorInterface;
class Display;
Support for syncing the clipboard from X11 to Wayland and vice versa Summary: The clipboard sync is done by a dedicated helper binary launched by KWin. This helper binary is forced to xcb platform to piggy-back on Qt's implementation of the X11 clipboard. In addition it implements the Wayland clipboard - which is much simpler. Reading the Wayland clipboard is based on the implementation in QtWayland. KWin internally knows the DataDeviceInterface belonging to the helper application. Whenever an xwayland client is focussed, this DataDevice is allowed to set the selection and KWin manually updates the current selection in the SeatInterface. By that the sync from X11 to Wayland is implemented. When afterwards a Wayland client is selected, it's sent the current selection which references the X clipboard and a data transfer can be initiated in the normal Wayland way. For the other direction KWin sends the current selection to the helper's DataDevice whenever an xwayland window is focused. The helper application reads the Wayland clipboard and sets it on the X11 clipboard. Thus the Wayland clipboard is synced to X11. The approach used here will also be useful for implementing a clipboard manager (aka klipper). Currently the implementation is not yet fully completed. We need to make sure that the helper application gets restarted in case of a crash. Test Plan: See added test case Reviewers: #plasma_on_wayland, #kwin Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D1973
2016-06-20 09:21:16 +00:00
class DataDeviceInterface;
class IdleInterface;
2020-07-11 16:40:28 +00:00
class InputMethodV1Interface;
class SeatInterface;
[xwl] Generic X selections translation mechanism with Clipboard support Summary: In this patch an infrastructure is created to represent generic X selections in a Wayland session and use them for data transfers between Xwayland windows and Wayland native clients. The central manager is the DataBridge class, in which Selection objects can be created. This is hard-coded and such a Selection object persists until the end of the session, so no arbitrary selections can be created on the fly. For now the X Clipboard selection is supported, whose corresponding mechanism in the Wayland protocol is just called Selection. A Selection object listens for selection owner changes on the X side and for similar events into the Wayland server interfaces. If a data provider is available a selection source object is created by the Selection object. In case data is requested on the other side, a data transfer is initialized by creating a Transfer object. A Selection keeps track of all transfers and makes sure that they are destroyed when they are finished or in case they idle because of misbehaving clients. The Clipboard class translates the X Clipboard via a proxy window. Selection changes on the Wayland side are listened to through a new signal on the active KWayland seat interface. The previously used X clipboard syncer helper is disabled. The clipboard sync autotest is changed to the new mechanism. BUG: 394765 BUG: 395313 Test Plan: Manually and clipboard sync autotest. Reviewers: #kwin Subscribers: zzag, graesslin, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D15061
2018-08-21 20:06:42 +00:00
class DataDeviceManagerInterface;
class ServerSideDecorationManagerInterface;
class ServerSideDecorationPaletteManagerInterface;
class SurfaceInterface;
class OutputInterface;
class PlasmaShellInterface;
class PlasmaWindowActivationFeedbackInterface;
class PlasmaVirtualDesktopManagementInterface;
class PlasmaWindowManagementInterface;
class PrimaryOutputV1Interface;
class OutputManagementV2Interface;
2020-07-28 11:35:08 +00:00
class XdgForeignV2Interface;
2020-08-20 14:53:10 +00:00
class XdgOutputManagerV1Interface;
class KeyStateInterface;
class LinuxDmaBufV1ClientBufferIntegration;
class LinuxDmaBufV1ClientBuffer;
class TabletManagerV2Interface;
class KeyboardShortcutsInhibitManagerV1Interface;
class XdgDecorationManagerV1Interface;
}
namespace KWin
{
class AbstractClient;
class AbstractOutput;
class Toplevel;
class XdgPopupClient;
class XdgSurfaceClient;
class XdgToplevelClient;
class WaylandOutput;
class WaylandOutputDevice;
class KWIN_EXPORT WaylandServer : public QObject
{
Q_OBJECT
public:
enum class InitializationFlag {
NoOptions = 0x0,
LockScreen = 0x1,
NoLockScreenIntegration = 0x2,
NoGlobalShortcuts = 0x4
};
Q_DECLARE_FLAGS(InitializationFlags, InitializationFlag)
Run clang-tidy with modernize-use-override check Summary: Currently code base of kwin can be viewed as two pieces. One is very ancient, and the other one is more modern, which uses new C++ features. The main problem with the ancient code is that it was written before C++11 era. So, no override or final keywords, lambdas, etc. Quite recently, KDE compiler settings were changed to show a warning if a virtual method has missing override keyword. As you might have already guessed, this fired back at us because of that ancient code. We had about 500 new compiler warnings. A "solution" was proposed to that problem - disable -Wno-suggest-override and the other similar warning for clang. It's hard to call a solution because those warnings are disabled not only for the old code, but also for new. This is not what we want! The main argument for not actually fixing the problem was that git history will be screwed as well because of human factor. While good git history is a very important thing, we should not go crazy about it and block every change that somehow alters git history. git blame allows to specify starting revision for a reason. The other argument (human factor) can be easily solved by using tools such as clang-tidy. clang-tidy is a clang-based linter for C++. It can be used for various things, e.g. fixing coding style(e.g. add missing braces to if statements, readability-braces-around-statements check), or in our case add missing override keywords. Test Plan: Compiles. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, apol, romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D22371
2019-07-22 16:52:26 +00:00
~WaylandServer() override;
bool init(const QString &socketName, InitializationFlags flags = InitializationFlag::NoOptions);
bool init(InitializationFlags flags = InitializationFlag::NoOptions);
bool start();
2020-05-29 06:48:19 +00:00
KWaylandServer::Display *display() const
{
return m_display;
}
2020-05-29 06:48:19 +00:00
KWaylandServer::CompositorInterface *compositor() const
{
return m_compositor;
}
2020-05-29 06:48:19 +00:00
KWaylandServer::SeatInterface *seat() const
{
return m_seat;
}
KWaylandServer::TabletManagerV2Interface *tabletManagerV2() const
{
return m_tabletManagerV2;
}
2020-05-29 06:48:19 +00:00
KWaylandServer::DataDeviceManagerInterface *dataDeviceManager() const
{
[xwl] Generic X selections translation mechanism with Clipboard support Summary: In this patch an infrastructure is created to represent generic X selections in a Wayland session and use them for data transfers between Xwayland windows and Wayland native clients. The central manager is the DataBridge class, in which Selection objects can be created. This is hard-coded and such a Selection object persists until the end of the session, so no arbitrary selections can be created on the fly. For now the X Clipboard selection is supported, whose corresponding mechanism in the Wayland protocol is just called Selection. A Selection object listens for selection owner changes on the X side and for similar events into the Wayland server interfaces. If a data provider is available a selection source object is created by the Selection object. In case data is requested on the other side, a data transfer is initialized by creating a Transfer object. A Selection keeps track of all transfers and makes sure that they are destroyed when they are finished or in case they idle because of misbehaving clients. The Clipboard class translates the X Clipboard via a proxy window. Selection changes on the Wayland side are listened to through a new signal on the active KWayland seat interface. The previously used X clipboard syncer helper is disabled. The clipboard sync autotest is changed to the new mechanism. BUG: 394765 BUG: 395313 Test Plan: Manually and clipboard sync autotest. Reviewers: #kwin Subscribers: zzag, graesslin, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D15061
2018-08-21 20:06:42 +00:00
return m_dataDeviceManager;
}
KWaylandServer::PlasmaWindowActivationFeedbackInterface *plasmaActivationFeedback() const
{
return m_plasmaActivationFeedback;
}
2020-05-29 06:48:19 +00:00
KWaylandServer::PlasmaVirtualDesktopManagementInterface *virtualDesktopManagement() const
{
return m_virtualDesktopManagement;
}
2020-05-29 06:48:19 +00:00
KWaylandServer::PlasmaWindowManagementInterface *windowManagement() const
{
return m_windowManagement;
}
KWaylandServer::ServerSideDecorationManagerInterface *decorationManager() const
{
return m_decorationManager;
}
KWaylandServer::XdgOutputManagerV1Interface *xdgOutputManagerV1() const
{
2020-08-20 14:53:10 +00:00
return m_xdgOutputManagerV1;
}
KWaylandServer::KeyboardShortcutsInhibitManagerV1Interface *keyboardShortcutsInhibitManager() const
{
return m_keyboardShortcutsInhibitManager;
}
bool isKeyboardShortcutsInhibited() const;
KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *linuxDmabuf();
KWaylandServer::InputMethodV1Interface *inputMethod() const
{
2020-07-11 16:40:28 +00:00
return m_inputMethod;
}
KWaylandServer::IdleInterface *idle() const
{
return m_idle;
}
QList<AbstractClient *> clients() const
{
return m_clients;
}
void removeClient(AbstractClient *c);
2020-11-07 02:03:57 +00:00
AbstractClient *findClient(const KWaylandServer::SurfaceInterface *surface) const;
XdgToplevelClient *findXdgToplevelClient(KWaylandServer::SurfaceInterface *surface) const;
XdgSurfaceClient *findXdgSurfaceClient(KWaylandServer::SurfaceInterface *surface) const;
/**
* @returns a transient parent of a surface imported with the foreign protocol, if any
*/
KWaylandServer::SurfaceInterface *findForeignTransientForSurface(KWaylandServer::SurfaceInterface *surface);
/**
* @returns file descriptor for Xwayland to connect to.
*/
int createXWaylandConnection();
void destroyXWaylandConnection();
/**
* @returns file descriptor to the input method server's socket.
*/
int createInputMethodConnection();
void destroyInputMethodConnection();
/**
* @returns true if screen is locked.
*/
bool isScreenLocked() const;
/**
* @returns whether integration with KScreenLocker is available.
*/
bool hasScreenLockerIntegration() const;
/**
* @returns whether any kind of global shortcuts are supported.
*/
bool hasGlobalShortcutSupport() const;
void initPlatform();
void initWorkspace();
KWaylandServer::ClientConnection *xWaylandConnection() const;
KWaylandServer::ClientConnection *inputMethodConnection() const;
KWaylandServer::ClientConnection *screenLockerClientConnection() const
{
return m_screenLockerClientConnection;
}
/**
* Struct containing information for a created Wayland connection through a
* socketpair.
*/
struct SocketPairConnection
{
/**
* ServerSide Connection
*/
KWaylandServer::ClientConnection *connection = nullptr;
/**
* client-side file descriptor for the socket
*/
int fd = -1;
};
/**
* Creates a Wayland connection using a socket pair.
*/
SocketPairConnection createConnection();
void simulateUserActivity();
void updateKeyState(KWin::LEDs leds);
QSet<KWaylandServer::LinuxDmaBufV1ClientBuffer *> linuxDmabufBuffers() const
{
return m_linuxDmabufBuffers;
}
void addLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
{
m_linuxDmabufBuffers << buffer;
}
void removeLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
{
m_linuxDmabufBuffers.remove(buffer);
}
AbstractOutput *findOutput(KWaylandServer::OutputInterface *output) const;
2020-11-17 13:26:01 +00:00
/**
* Returns the first socket name that can be used to connect to this server.
* For a full list, use display()->socketNames()
*/
QString socketName() const;
Q_SIGNALS:
void shellClientAdded(KWin::AbstractClient *);
void shellClientRemoved(KWin::AbstractClient *);
void initialized();
void foreignTransientChanged(KWaylandServer::SurfaceInterface *child);
void lockStateChanged();
private:
int createScreenLockerConnection();
void shellClientShown(Toplevel *t);
void initScreenLocker();
void registerXdgGenericClient(AbstractClient *client);
void registerXdgToplevelClient(XdgToplevelClient *client);
void registerXdgPopupClient(XdgPopupClient *client);
void registerShellClient(AbstractClient *client);
void handleOutputAdded(AbstractOutput *output);
void handleOutputRemoved(AbstractOutput *output);
void handleOutputEnabled(AbstractOutput *output);
void handleOutputDisabled(AbstractOutput *output);
class LockScreenPresentationWatcher : public QObject
{
public:
LockScreenPresentationWatcher(WaylandServer *server);
private:
QSet<AbstractOutput *> m_signaledOutputs;
};
KWaylandServer::Display *m_display = nullptr;
KWaylandServer::CompositorInterface *m_compositor = nullptr;
KWaylandServer::SeatInterface *m_seat = nullptr;
KWaylandServer::TabletManagerV2Interface *m_tabletManagerV2 = nullptr;
KWaylandServer::DataDeviceManagerInterface *m_dataDeviceManager = nullptr;
KWaylandServer::PlasmaShellInterface *m_plasmaShell = nullptr;
KWaylandServer::PlasmaWindowActivationFeedbackInterface *m_plasmaActivationFeedback = nullptr;
KWaylandServer::PlasmaWindowManagementInterface *m_windowManagement = nullptr;
KWaylandServer::PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr;
KWaylandServer::ServerSideDecorationManagerInterface *m_decorationManager = nullptr;
KWaylandServer::OutputManagementV2Interface *m_outputManagement = nullptr;
KWaylandServer::AppMenuManagerInterface *m_appMenuManager = nullptr;
KWaylandServer::ServerSideDecorationPaletteManagerInterface *m_paletteManager = nullptr;
KWaylandServer::IdleInterface *m_idle = nullptr;
2020-08-20 14:53:10 +00:00
KWaylandServer::XdgOutputManagerV1Interface *m_xdgOutputManagerV1 = nullptr;
KWaylandServer::XdgDecorationManagerV1Interface *m_xdgDecorationManagerV1 = nullptr;
KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *m_linuxDmabuf = nullptr;
KWaylandServer::KeyboardShortcutsInhibitManagerV1Interface *m_keyboardShortcutsInhibitManager = nullptr;
QSet<KWaylandServer::LinuxDmaBufV1ClientBuffer *> m_linuxDmabufBuffers;
QPointer<KWaylandServer::ClientConnection> m_xwaylandConnection;
2020-07-11 16:40:28 +00:00
KWaylandServer::InputMethodV1Interface *m_inputMethod = nullptr;
QPointer<KWaylandServer::ClientConnection> m_inputMethodServerConnection;
KWaylandServer::ClientConnection *m_screenLockerClientConnection = nullptr;
2020-07-22 20:27:29 +00:00
KWaylandServer::XdgForeignV2Interface *m_XdgForeign = nullptr;
KWaylandServer::KeyStateInterface *m_keyState = nullptr;
KWaylandServer::PrimaryOutputV1Interface *m_primary = nullptr;
QList<AbstractClient *> m_clients;
InitializationFlags m_initFlags;
QHash<AbstractOutput *, WaylandOutput *> m_waylandOutputs;
QHash<AbstractOutput *, WaylandOutputDevice *> m_waylandOutputDevices;
KWIN_SINGLETON(WaylandServer)
};
inline WaylandServer *waylandServer()
{
return WaylandServer::self();
}
} // namespace KWin
#endif