File indexing completed on 2024-05-12 05:30:35

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #ifndef KWIN_WAYLAND_TEST_H
0010 #define KWIN_WAYLAND_TEST_H
0011 
0012 #include "core/inputdevice.h"
0013 #include "main.h"
0014 #include "window.h"
0015 
0016 // Qt
0017 #include <QSignalSpy>
0018 #include <QTest>
0019 
0020 #include <KWayland/Client/surface.h>
0021 #include <optional>
0022 
0023 #include "qwayland-cursor-shape-v1.h"
0024 #include "qwayland-fake-input.h"
0025 #include "qwayland-fractional-scale-v1.h"
0026 #include "qwayland-idle-inhibit-unstable-v1.h"
0027 #include "qwayland-input-method-unstable-v1.h"
0028 #include "qwayland-kde-output-device-v2.h"
0029 #include "qwayland-kde-output-management-v2.h"
0030 #include "qwayland-kde-screen-edge-v1.h"
0031 #include "qwayland-security-context-v1.h"
0032 #include "qwayland-text-input-unstable-v3.h"
0033 #include "qwayland-wlr-layer-shell-unstable-v1.h"
0034 #include "qwayland-xdg-decoration-unstable-v1.h"
0035 #include "qwayland-xdg-shell.h"
0036 #include "qwayland-zkde-screencast-unstable-v1.h"
0037 
0038 namespace KWayland
0039 {
0040 namespace Client
0041 {
0042 class AppMenuManager;
0043 class ConnectionThread;
0044 class Compositor;
0045 class Output;
0046 class PlasmaShell;
0047 class PlasmaWindowManagement;
0048 class Pointer;
0049 class PointerConstraints;
0050 class Seat;
0051 class ShadowManager;
0052 class ShmPool;
0053 class SubCompositor;
0054 class SubSurface;
0055 class Surface;
0056 class TextInputManager;
0057 }
0058 }
0059 
0060 namespace QtWayland
0061 {
0062 class zwp_input_panel_surface_v1;
0063 class zwp_text_input_v3;
0064 class zwp_text_input_manager_v3;
0065 }
0066 
0067 class ScreencastingV1;
0068 
0069 namespace KWin
0070 {
0071 namespace Xwl
0072 {
0073 class Xwayland;
0074 }
0075 
0076 namespace Test
0077 {
0078 class VirtualInputDevice;
0079 }
0080 
0081 class WaylandTestApplication : public Application
0082 {
0083     Q_OBJECT
0084 public:
0085     WaylandTestApplication(OperationMode mode, int &argc, char **argv);
0086     ~WaylandTestApplication() override;
0087 
0088     void setInputMethodServerToStart(const QString &inputMethodServer)
0089     {
0090         m_inputMethodServerToStart = inputMethodServer;
0091     }
0092 
0093     Test::VirtualInputDevice *virtualPointer() const;
0094     Test::VirtualInputDevice *virtualKeyboard() const;
0095     Test::VirtualInputDevice *virtualTouch() const;
0096     XwaylandInterface *xwayland() const override;
0097 
0098 protected:
0099     void performStartup() override;
0100 
0101 private:
0102     void continueStartupWithScene();
0103     void finalizeStartup();
0104 
0105     void createVirtualInputDevices();
0106     void destroyVirtualInputDevices();
0107 
0108     std::unique_ptr<Xwl::Xwayland> m_xwayland;
0109     QString m_inputMethodServerToStart;
0110 
0111     std::unique_ptr<Test::VirtualInputDevice> m_virtualPointer;
0112     std::unique_ptr<Test::VirtualInputDevice> m_virtualKeyboard;
0113     std::unique_ptr<Test::VirtualInputDevice> m_virtualTouch;
0114 };
0115 
0116 namespace Test
0117 {
0118 
0119 class ScreencastingV1;
0120 class MockInputMethod;
0121 
0122 class TextInputManagerV3 : public QtWayland::zwp_text_input_manager_v3
0123 {
0124 public:
0125     ~TextInputManagerV3() override
0126     {
0127         destroy();
0128     }
0129 };
0130 
0131 class TextInputV3 : public QObject, public QtWayland::zwp_text_input_v3
0132 {
0133     Q_OBJECT
0134 public:
0135     ~TextInputV3() override
0136     {
0137         destroy();
0138     }
0139 
0140 Q_SIGNALS:
0141     void preeditString(const QString &text, int cursor_begin, int cursor_end);
0142 
0143 protected:
0144     void zwp_text_input_v3_preedit_string(const QString &text, int32_t cursor_begin, int32_t cursor_end) override
0145     {
0146         Q_EMIT preeditString(text, cursor_begin, cursor_end);
0147     }
0148 };
0149 
0150 class LayerShellV1 : public QtWayland::zwlr_layer_shell_v1
0151 {
0152 public:
0153     ~LayerShellV1() override;
0154 };
0155 
0156 class LayerSurfaceV1 : public QObject, public QtWayland::zwlr_layer_surface_v1
0157 {
0158     Q_OBJECT
0159 
0160 public:
0161     ~LayerSurfaceV1() override;
0162 
0163 protected:
0164     void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override;
0165     void zwlr_layer_surface_v1_closed() override;
0166 
0167 Q_SIGNALS:
0168     void closeRequested();
0169     void configureRequested(quint32 serial, const QSize &size);
0170 };
0171 
0172 /**
0173  * The XdgShell class represents the @c xdg_wm_base global.
0174  */
0175 class XdgShell : public QtWayland::xdg_wm_base
0176 {
0177 public:
0178     ~XdgShell() override;
0179     void xdg_wm_base_ping(uint32_t serial) override
0180     {
0181         pong(serial);
0182     }
0183 };
0184 
0185 /**
0186  * The XdgSurface class represents an xdg_surface object.
0187  */
0188 class XdgSurface : public QObject, public QtWayland::xdg_surface
0189 {
0190     Q_OBJECT
0191 
0192 public:
0193     explicit XdgSurface(XdgShell *shell, KWayland::Client::Surface *surface, QObject *parent = nullptr);
0194     ~XdgSurface() override;
0195 
0196     KWayland::Client::Surface *surface() const;
0197 
0198 Q_SIGNALS:
0199     void configureRequested(quint32 serial);
0200 
0201 protected:
0202     void xdg_surface_configure(uint32_t serial) override;
0203 
0204 private:
0205     KWayland::Client::Surface *m_surface;
0206 };
0207 
0208 /**
0209  * The XdgToplevel class represents an xdg_toplevel surface. Note that the XdgToplevel surface
0210  * takes the ownership of the underlying XdgSurface object.
0211  */
0212 class XdgToplevel : public QObject, public QtWayland::xdg_toplevel
0213 {
0214     Q_OBJECT
0215 
0216 public:
0217     enum class State {
0218         Maximized = 1 << 0,
0219         Fullscreen = 1 << 1,
0220         Resizing = 1 << 2,
0221         Activated = 1 << 3
0222     };
0223     Q_DECLARE_FLAGS(States, State)
0224 
0225     explicit XdgToplevel(XdgSurface *surface, QObject *parent = nullptr);
0226     ~XdgToplevel() override;
0227 
0228     XdgSurface *xdgSurface() const;
0229 
0230 Q_SIGNALS:
0231     void configureRequested(const QSize &size, KWin::Test::XdgToplevel::States states);
0232     void closeRequested();
0233 
0234 protected:
0235     void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override;
0236     void xdg_toplevel_close() override;
0237 
0238 private:
0239     std::unique_ptr<XdgSurface> m_xdgSurface;
0240 };
0241 
0242 /**
0243  * The XdgPositioner class represents an xdg_positioner object.
0244  */
0245 class XdgPositioner : public QtWayland::xdg_positioner
0246 {
0247 public:
0248     explicit XdgPositioner(XdgShell *shell);
0249     ~XdgPositioner() override;
0250 };
0251 
0252 /**
0253  * The XdgPopup class represents an xdg_popup surface. Note that the XdgPopup surface takes
0254  * the ownership of the underlying XdgSurface object.
0255  */
0256 class XdgPopup : public QObject, public QtWayland::xdg_popup
0257 {
0258     Q_OBJECT
0259 
0260 public:
0261     XdgPopup(XdgSurface *surface, XdgSurface *parentSurface, XdgPositioner *positioner, QObject *parent = nullptr);
0262     ~XdgPopup() override;
0263 
0264     XdgSurface *xdgSurface() const;
0265 
0266 Q_SIGNALS:
0267     void configureRequested(const QRect &rect);
0268     void doneReceived();
0269 
0270 protected:
0271     void xdg_popup_configure(int32_t x, int32_t y, int32_t width, int32_t height) override;
0272     void xdg_popup_popup_done() override;
0273 
0274 private:
0275     std::unique_ptr<XdgSurface> m_xdgSurface;
0276 };
0277 
0278 class XdgDecorationManagerV1 : public QtWayland::zxdg_decoration_manager_v1
0279 {
0280 public:
0281     ~XdgDecorationManagerV1() override;
0282 };
0283 
0284 class XdgToplevelDecorationV1 : public QObject, public QtWayland::zxdg_toplevel_decoration_v1
0285 {
0286     Q_OBJECT
0287 
0288 public:
0289     XdgToplevelDecorationV1(XdgDecorationManagerV1 *manager, XdgToplevel *toplevel, QObject *parent = nullptr);
0290     ~XdgToplevelDecorationV1() override;
0291 
0292 Q_SIGNALS:
0293     void configureRequested(QtWayland::zxdg_toplevel_decoration_v1::mode mode);
0294 
0295 protected:
0296     void zxdg_toplevel_decoration_v1_configure(uint32_t mode) override;
0297 };
0298 
0299 class IdleInhibitManagerV1 : public QtWayland::zwp_idle_inhibit_manager_v1
0300 {
0301 public:
0302     ~IdleInhibitManagerV1() override;
0303 };
0304 
0305 class IdleInhibitorV1 : public QtWayland::zwp_idle_inhibitor_v1
0306 {
0307 public:
0308     IdleInhibitorV1(IdleInhibitManagerV1 *manager, KWayland::Client::Surface *surface);
0309     ~IdleInhibitorV1() override;
0310 };
0311 
0312 class WaylandOutputConfigurationV2 : public QObject, public QtWayland::kde_output_configuration_v2
0313 {
0314     Q_OBJECT
0315 public:
0316     WaylandOutputConfigurationV2(struct ::kde_output_configuration_v2 *object);
0317 
0318 Q_SIGNALS:
0319     void applied();
0320     void failed();
0321 
0322 protected:
0323     void kde_output_configuration_v2_applied() override;
0324     void kde_output_configuration_v2_failed() override;
0325 };
0326 
0327 class WaylandOutputManagementV2 : public QObject, public QtWayland::kde_output_management_v2
0328 {
0329     Q_OBJECT
0330 public:
0331     WaylandOutputManagementV2(struct ::wl_registry *registry, int id, int version);
0332 
0333     WaylandOutputConfigurationV2 *createConfiguration();
0334 };
0335 
0336 class WaylandOutputDeviceV2Mode : public QObject, public QtWayland::kde_output_device_mode_v2
0337 {
0338     Q_OBJECT
0339 
0340 public:
0341     WaylandOutputDeviceV2Mode(struct ::kde_output_device_mode_v2 *object);
0342     ~WaylandOutputDeviceV2Mode() override;
0343 
0344     int refreshRate() const;
0345     QSize size() const;
0346     bool preferred() const;
0347 
0348     bool operator==(const WaylandOutputDeviceV2Mode &other) const;
0349 
0350     static WaylandOutputDeviceV2Mode *get(struct ::kde_output_device_mode_v2 *object);
0351 
0352 Q_SIGNALS:
0353     void removed();
0354 
0355 protected:
0356     void kde_output_device_mode_v2_size(int32_t width, int32_t height) override;
0357     void kde_output_device_mode_v2_refresh(int32_t refresh) override;
0358     void kde_output_device_mode_v2_preferred() override;
0359     void kde_output_device_mode_v2_removed() override;
0360 
0361 private:
0362     int m_refreshRate = 60000;
0363     QSize m_size;
0364     bool m_preferred = false;
0365 };
0366 
0367 class WaylandOutputDeviceV2 : public QObject, public QtWayland::kde_output_device_v2
0368 {
0369     Q_OBJECT
0370 
0371 public:
0372     WaylandOutputDeviceV2(int id);
0373     ~WaylandOutputDeviceV2() override;
0374 
0375     QByteArray edid() const;
0376     bool enabled() const;
0377     int id() const;
0378     QString name() const;
0379     QString model() const;
0380     QString manufacturer() const;
0381     qreal scale() const;
0382     QPoint globalPosition() const;
0383     QSize pixelSize() const;
0384     int refreshRate() const;
0385     uint32_t vrrPolicy() const;
0386     uint32_t overscan() const;
0387     uint32_t capabilities() const;
0388     uint32_t rgbRange() const;
0389 
0390     QString modeId() const;
0391 
0392 Q_SIGNALS:
0393     void enabledChanged();
0394     void done();
0395 
0396 protected:
0397     void kde_output_device_v2_geometry(int32_t x,
0398                                        int32_t y,
0399                                        int32_t physical_width,
0400                                        int32_t physical_height,
0401                                        int32_t subpixel,
0402                                        const QString &make,
0403                                        const QString &model,
0404                                        int32_t transform) override;
0405     void kde_output_device_v2_current_mode(struct ::kde_output_device_mode_v2 *mode) override;
0406     void kde_output_device_v2_mode(struct ::kde_output_device_mode_v2 *mode) override;
0407     void kde_output_device_v2_done() override;
0408     void kde_output_device_v2_scale(wl_fixed_t factor) override;
0409     void kde_output_device_v2_edid(const QString &raw) override;
0410     void kde_output_device_v2_enabled(int32_t enabled) override;
0411     void kde_output_device_v2_uuid(const QString &uuid) override;
0412     void kde_output_device_v2_serial_number(const QString &serialNumber) override;
0413     void kde_output_device_v2_eisa_id(const QString &eisaId) override;
0414     void kde_output_device_v2_capabilities(uint32_t flags) override;
0415     void kde_output_device_v2_overscan(uint32_t overscan) override;
0416     void kde_output_device_v2_vrr_policy(uint32_t vrr_policy) override;
0417     void kde_output_device_v2_rgb_range(uint32_t rgb_range) override;
0418 
0419 private:
0420     QString modeName(const WaylandOutputDeviceV2Mode *m) const;
0421     WaylandOutputDeviceV2Mode *deviceModeFromId(const int modeId) const;
0422 
0423     WaylandOutputDeviceV2Mode *m_mode;
0424     QList<WaylandOutputDeviceV2Mode *> m_modes;
0425 
0426     int m_id;
0427     QPoint m_pos;
0428     QSize m_physicalSize;
0429     int32_t m_subpixel;
0430     QString m_manufacturer;
0431     QString m_model;
0432     int32_t m_transform;
0433     qreal m_factor;
0434     QByteArray m_edid;
0435     int32_t m_enabled;
0436     QString m_uuid;
0437     QString m_serialNumber;
0438     QString m_eisaId;
0439     uint32_t m_flags;
0440     uint32_t m_overscan;
0441     uint32_t m_vrr_policy;
0442     uint32_t m_rgbRange;
0443 };
0444 
0445 class MockInputMethod : public QObject, QtWayland::zwp_input_method_v1
0446 {
0447     Q_OBJECT
0448 public:
0449     enum class Mode {
0450         TopLevel,
0451         Overlay,
0452     };
0453 
0454     MockInputMethod(struct wl_registry *registry, int id, int version);
0455     ~MockInputMethod();
0456 
0457     KWayland::Client::Surface *inputPanelSurface() const
0458     {
0459         return m_inputSurface.get();
0460     }
0461     auto *context() const
0462     {
0463         return m_context;
0464     }
0465 
0466     void setMode(Mode mode);
0467 
0468 Q_SIGNALS:
0469     void activate();
0470 
0471 protected:
0472     void zwp_input_method_v1_activate(struct ::zwp_input_method_context_v1 *context) override;
0473     void zwp_input_method_v1_deactivate(struct ::zwp_input_method_context_v1 *context) override;
0474 
0475 private:
0476     std::unique_ptr<KWayland::Client::Surface> m_inputSurface;
0477     QtWayland::zwp_input_panel_surface_v1 *m_inputMethodSurface = nullptr;
0478     struct ::zwp_input_method_context_v1 *m_context = nullptr;
0479     Mode m_mode = Mode::TopLevel;
0480 };
0481 
0482 class FractionalScaleManagerV1 : public QObject, public QtWayland::wp_fractional_scale_manager_v1
0483 {
0484     Q_OBJECT
0485 public:
0486     ~FractionalScaleManagerV1() override;
0487 };
0488 
0489 class FractionalScaleV1 : public QObject, public QtWayland::wp_fractional_scale_v1
0490 {
0491     Q_OBJECT
0492 public:
0493     ~FractionalScaleV1() override;
0494     int preferredScale();
0495 
0496 protected:
0497     void wp_fractional_scale_v1_preferred_scale(uint32_t scale) override;
0498 
0499 private:
0500     int m_preferredScale = 120;
0501 };
0502 
0503 class ScreenEdgeManagerV1 : public QObject, public QtWayland::kde_screen_edge_manager_v1
0504 {
0505     Q_OBJECT
0506 public:
0507     ~ScreenEdgeManagerV1() override;
0508 };
0509 
0510 class AutoHideScreenEdgeV1 : public QObject, public QtWayland::kde_auto_hide_screen_edge_v1
0511 {
0512     Q_OBJECT
0513 public:
0514     AutoHideScreenEdgeV1(ScreenEdgeManagerV1 *manager, KWayland::Client::Surface *surface, uint32_t border);
0515     ~AutoHideScreenEdgeV1() override;
0516 };
0517 
0518 class CursorShapeManagerV1 : public QObject, public QtWayland::wp_cursor_shape_manager_v1
0519 {
0520     Q_OBJECT
0521 public:
0522     ~CursorShapeManagerV1() override;
0523 };
0524 
0525 class CursorShapeDeviceV1 : public QObject, public QtWayland::wp_cursor_shape_device_v1
0526 {
0527     Q_OBJECT
0528 public:
0529     CursorShapeDeviceV1(CursorShapeManagerV1 *manager, KWayland::Client::Pointer *pointer);
0530     ~CursorShapeDeviceV1() override;
0531 };
0532 
0533 class FakeInput : public QtWayland::org_kde_kwin_fake_input
0534 {
0535 public:
0536     ~FakeInput() override;
0537 };
0538 
0539 class SecurityContextManagerV1 : public QtWayland::wp_security_context_manager_v1
0540 {
0541 public:
0542     ~SecurityContextManagerV1() override;
0543 };
0544 
0545 enum class AdditionalWaylandInterface {
0546     Seat = 1 << 0,
0547     PlasmaShell = 1 << 2,
0548     WindowManagement = 1 << 3,
0549     PointerConstraints = 1 << 4,
0550     IdleInhibitV1 = 1 << 5,
0551     AppMenu = 1 << 6,
0552     ShadowManager = 1 << 7,
0553     XdgDecorationV1 = 1 << 8,
0554     OutputManagementV2 = 1 << 9,
0555     TextInputManagerV2 = 1 << 10,
0556     InputMethodV1 = 1 << 11,
0557     LayerShellV1 = 1 << 12,
0558     TextInputManagerV3 = 1 << 13,
0559     OutputDeviceV2 = 1 << 14,
0560     FractionalScaleManagerV1 = 1 << 15,
0561     ScreencastingV1 = 1 << 16,
0562     ScreenEdgeV1 = 1 << 17,
0563     CursorShapeV1 = 1 << 18,
0564     FakeInput = 1 << 19,
0565     SecurityContextManagerV1 = 1 << 20,
0566 };
0567 Q_DECLARE_FLAGS(AdditionalWaylandInterfaces, AdditionalWaylandInterface)
0568 
0569 class VirtualInputDevice : public InputDevice
0570 {
0571     Q_OBJECT
0572 
0573 public:
0574     explicit VirtualInputDevice(QObject *parent = nullptr);
0575 
0576     void setPointer(bool set);
0577     void setKeyboard(bool set);
0578     void setTouch(bool set);
0579     void setLidSwitch(bool set);
0580     void setName(const QString &name);
0581 
0582     QString sysName() const override;
0583     QString name() const override;
0584 
0585     bool isEnabled() const override;
0586     void setEnabled(bool enabled) override;
0587 
0588     LEDs leds() const override;
0589     void setLeds(LEDs leds) override;
0590 
0591     bool isKeyboard() const override;
0592     bool isAlphaNumericKeyboard() const override;
0593     bool isPointer() const override;
0594     bool isTouchpad() const override;
0595     bool isTouch() const override;
0596     bool isTabletTool() const override;
0597     bool isTabletPad() const override;
0598     bool isTabletModeSwitch() const override;
0599     bool isLidSwitch() const override;
0600 
0601 private:
0602     QString m_name;
0603     bool m_pointer = false;
0604     bool m_keyboard = false;
0605     bool m_touch = false;
0606     bool m_lidSwitch = false;
0607 };
0608 
0609 void keyboardKeyPressed(quint32 key, quint32 time);
0610 void keyboardKeyReleased(quint32 key, quint32 time);
0611 void pointerAxisHorizontal(qreal delta,
0612                            quint32 time,
0613                            qint32 discreteDelta = 0,
0614                            InputRedirection::PointerAxisSource source = InputRedirection::PointerAxisSourceUnknown);
0615 void pointerAxisVertical(qreal delta,
0616                          quint32 time,
0617                          qint32 discreteDelta = 0,
0618                          InputRedirection::PointerAxisSource source = InputRedirection::PointerAxisSourceUnknown);
0619 void pointerButtonPressed(quint32 button, quint32 time);
0620 void pointerButtonReleased(quint32 button, quint32 time);
0621 void pointerMotion(const QPointF &position, quint32 time);
0622 void pointerMotionRelative(const QPointF &delta, quint32 time);
0623 void touchCancel();
0624 void touchDown(qint32 id, const QPointF &pos, quint32 time);
0625 void touchMotion(qint32 id, const QPointF &pos, quint32 time);
0626 void touchUp(qint32 id, quint32 time);
0627 
0628 /**
0629  * Creates a Wayland Connection in a dedicated thread and creates various
0630  * client side objects which can be used to create windows.
0631  * @returns @c true if created successfully, @c false if there was an error
0632  * @see destroyWaylandConnection
0633  */
0634 bool setupWaylandConnection(AdditionalWaylandInterfaces flags = AdditionalWaylandInterfaces());
0635 
0636 /**
0637  * Destroys the Wayland Connection created with @link{setupWaylandConnection}.
0638  * This can be called from cleanup in order to ensure that no Wayland Connection
0639  * leaks into the next test method.
0640  * @see setupWaylandConnection
0641  */
0642 void destroyWaylandConnection();
0643 
0644 KWayland::Client::ConnectionThread *waylandConnection();
0645 KWayland::Client::Compositor *waylandCompositor();
0646 KWayland::Client::SubCompositor *waylandSubCompositor();
0647 KWayland::Client::ShadowManager *waylandShadowManager();
0648 KWayland::Client::ShmPool *waylandShmPool();
0649 KWayland::Client::Seat *waylandSeat();
0650 KWayland::Client::PlasmaShell *waylandPlasmaShell();
0651 KWayland::Client::PlasmaWindowManagement *waylandWindowManagement();
0652 KWayland::Client::PointerConstraints *waylandPointerConstraints();
0653 KWayland::Client::AppMenuManager *waylandAppMenuManager();
0654 WaylandOutputManagementV2 *waylandOutputManagementV2();
0655 KWayland::Client::TextInputManager *waylandTextInputManager();
0656 QList<KWayland::Client::Output *> waylandOutputs();
0657 KWayland::Client::Output *waylandOutput(const QString &name);
0658 ScreencastingV1 *screencasting();
0659 QList<WaylandOutputDeviceV2 *> waylandOutputDevicesV2();
0660 FakeInput *waylandFakeInput();
0661 SecurityContextManagerV1 *waylandSecurityContextManagerV1();
0662 
0663 bool waitForWaylandSurface(Window *window);
0664 
0665 bool waitForWaylandPointer();
0666 bool waitForWaylandTouch();
0667 bool waitForWaylandKeyboard();
0668 
0669 void flushWaylandConnection();
0670 
0671 /**
0672  * Ensures that all client requests are processed by the compositor and all events
0673  * sent by the compositor are seen by the client.
0674  */
0675 bool waylandSync();
0676 
0677 std::unique_ptr<KWayland::Client::Surface> createSurface();
0678 KWayland::Client::SubSurface *createSubSurface(KWayland::Client::Surface *surface,
0679                                                KWayland::Client::Surface *parentSurface, QObject *parent = nullptr);
0680 
0681 LayerSurfaceV1 *createLayerSurfaceV1(KWayland::Client::Surface *surface,
0682                                      const QString &scope,
0683                                      KWayland::Client::Output *output = nullptr,
0684                                      LayerShellV1::layer layer = LayerShellV1::layer_top);
0685 
0686 TextInputManagerV3 *waylandTextInputManagerV3();
0687 
0688 enum class CreationSetup {
0689     CreateOnly,
0690     CreateAndConfigure, /// commit and wait for the configure event, making this surface ready to commit buffers
0691 };
0692 
0693 QtWayland::zwp_input_panel_surface_v1 *createInputPanelSurfaceV1(KWayland::Client::Surface *surface,
0694                                                                  KWayland::Client::Output *output,
0695                                                                  MockInputMethod::Mode mode);
0696 
0697 FractionalScaleV1 *createFractionalScaleV1(KWayland::Client::Surface *surface);
0698 
0699 XdgToplevel *createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent = nullptr);
0700 XdgToplevel *createXdgToplevelSurface(KWayland::Client::Surface *surface,
0701                                       CreationSetup configureMode,
0702                                       QObject *parent = nullptr);
0703 
0704 XdgPositioner *createXdgPositioner();
0705 
0706 XdgPopup *createXdgPopupSurface(KWayland::Client::Surface *surface, XdgSurface *parentSurface,
0707                                 XdgPositioner *positioner,
0708                                 CreationSetup configureMode = CreationSetup::CreateAndConfigure,
0709                                 QObject *parent = nullptr);
0710 
0711 XdgToplevelDecorationV1 *createXdgToplevelDecorationV1(XdgToplevel *toplevel, QObject *parent = nullptr);
0712 IdleInhibitorV1 *createIdleInhibitorV1(KWayland::Client::Surface *surface);
0713 AutoHideScreenEdgeV1 *createAutoHideScreenEdgeV1(KWayland::Client::Surface *surface, uint32_t border);
0714 CursorShapeDeviceV1 *createCursorShapeDeviceV1(KWayland::Client::Pointer *pointer);
0715 
0716 /**
0717  * Creates a shared memory buffer of @p size in @p color and attaches it to the @p surface.
0718  * The @p surface gets damaged and committed, thus it's rendered.
0719  */
0720 void render(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format = QImage::Format_ARGB32_Premultiplied);
0721 
0722 /**
0723  * Creates a shared memory buffer using the supplied image @p img and attaches it to the @p surface
0724  */
0725 void render(KWayland::Client::Surface *surface, const QImage &img);
0726 
0727 /**
0728  * Waits till a new Window is shown and returns the created Window.
0729  * If no Window gets shown during @p timeout @c null is returned.
0730  */
0731 Window *waitForWaylandWindowShown(int timeout = 5000);
0732 
0733 /**
0734  * Combination of @link{render} and @link{waitForWaylandWindowShown}.
0735  */
0736 Window *renderAndWaitForShown(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format = QImage::Format_ARGB32, int timeout = 5000);
0737 
0738 Window *renderAndWaitForShown(KWayland::Client::Surface *surface, const QImage &img, int timeout = 5000);
0739 
0740 /**
0741  * Waits for the @p window to be destroyed.
0742  */
0743 bool waitForWindowClosed(Window *window);
0744 
0745 /**
0746  * Locks the screen and waits till the screen is locked.
0747  * @returns @c true if the screen could be locked, @c false otherwise
0748  */
0749 bool lockScreen();
0750 
0751 /**
0752  * Unlocks the screen and waits till the screen is unlocked.
0753  * @returns @c true if the screen could be unlocked, @c false otherwise
0754  */
0755 bool unlockScreen();
0756 
0757 /**
0758  * Returns @c true if the system has at least one render node; otherwise returns @c false.
0759  *
0760  * This can be used to test whether the system is capable of allocating and sharing prime buffers, etc.
0761  */
0762 bool renderNodeAvailable();
0763 
0764 /**
0765  * Creates an X11 connection
0766  * Internally a nested event loop is spawned whilst we connect to avoid a deadlock
0767  * with X on demand
0768  */
0769 
0770 struct XcbConnectionDeleter
0771 {
0772     void operator()(xcb_connection_t *pointer);
0773 };
0774 
0775 typedef std::unique_ptr<xcb_connection_t, XcbConnectionDeleter> XcbConnectionPtr;
0776 XcbConnectionPtr createX11Connection();
0777 
0778 MockInputMethod *inputMethod();
0779 KWayland::Client::Surface *inputPanelSurface();
0780 
0781 class ScreencastingStreamV1 : public QObject, public QtWayland::zkde_screencast_stream_unstable_v1
0782 {
0783     Q_OBJECT
0784     friend class ScreencastingV1;
0785 
0786 public:
0787     ScreencastingStreamV1(QObject *parent)
0788         : QObject(parent)
0789     {
0790     }
0791 
0792     ~ScreencastingStreamV1() override
0793     {
0794         if (isInitialized()) {
0795             close();
0796         }
0797     }
0798 
0799     quint32 nodeId() const
0800     {
0801         Q_ASSERT(m_nodeId.has_value());
0802         return *m_nodeId;
0803     }
0804 
0805     void zkde_screencast_stream_unstable_v1_created(uint32_t node) override
0806     {
0807         m_nodeId = node;
0808         Q_EMIT created(node);
0809     }
0810 
0811     void zkde_screencast_stream_unstable_v1_closed() override
0812     {
0813         Q_EMIT closed();
0814     }
0815 
0816     void zkde_screencast_stream_unstable_v1_failed(const QString &error) override
0817     {
0818         Q_EMIT failed(error);
0819     }
0820 
0821 Q_SIGNALS:
0822     void created(quint32 nodeid);
0823     void failed(const QString &error);
0824     void closed();
0825 
0826 private:
0827     std::optional<uint> m_nodeId;
0828 };
0829 
0830 class ScreencastingV1 : public QObject, public QtWayland::zkde_screencast_unstable_v1
0831 {
0832     Q_OBJECT
0833 public:
0834     explicit ScreencastingV1(QObject *parent = nullptr)
0835         : QObject(parent)
0836     {
0837     }
0838 
0839     ScreencastingStreamV1 *createOutputStream(wl_output *output, pointer mode)
0840     {
0841         auto stream = new ScreencastingStreamV1(this);
0842         stream->init(stream_output(output, mode));
0843         return stream;
0844     }
0845 
0846     ScreencastingStreamV1 *createWindowStream(const QString &uuid, pointer mode)
0847     {
0848         auto stream = new ScreencastingStreamV1(this);
0849         stream->init(stream_window(uuid, mode));
0850         return stream;
0851     }
0852 };
0853 
0854 struct OutputInfo
0855 {
0856     QRect geometry;
0857     double scale = 1;
0858     bool internal = false;
0859 };
0860 void setOutputConfig(const QList<QRect> &geometries);
0861 void setOutputConfig(const QList<OutputInfo> &infos);
0862 }
0863 
0864 }
0865 
0866 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::Test::AdditionalWaylandInterfaces)
0867 Q_DECLARE_METATYPE(KWin::Test::XdgToplevel::States)
0868 Q_DECLARE_METATYPE(QtWayland::zxdg_toplevel_decoration_v1::mode)
0869 
0870 #define WAYLANDTEST_MAIN(TestObject)                                                                                                      \
0871     int main(int argc, char *argv[])                                                                                                      \
0872     {                                                                                                                                     \
0873         setenv("QT_QPA_PLATFORM", "wayland-org.kde.kwin.qpa", true);                                                                      \
0874         setenv("QT_QPA_PLATFORM_PLUGIN_PATH", QFileInfo(QString::fromLocal8Bit(argv[0])).absolutePath().toLocal8Bit().constData(), true); \
0875         setenv("KWIN_FORCE_OWN_QPA", "1", true);                                                                                          \
0876         qunsetenv("KDE_FULL_SESSION");                                                                                                    \
0877         qunsetenv("KDE_SESSION_VERSION");                                                                                                 \
0878         qunsetenv("XDG_SESSION_DESKTOP");                                                                                                 \
0879         qunsetenv("XDG_CURRENT_DESKTOP");                                                                                                 \
0880         KWin::WaylandTestApplication app(KWin::Application::OperationModeXwayland, argc, argv);                                           \
0881         app.setAttribute(Qt::AA_Use96Dpi, true);                                                                                          \
0882         TestObject tc;                                                                                                                    \
0883         return QTest::qExec(&tc, argc, argv);                                                                                             \
0884     }
0885 
0886 #endif