Plasma-workspace

outputorderwatcher.h
1/*
2 SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#pragma once
8
9#include <QAbstractNativeEventFilter>
10#include <QGuiApplication>
11#include <QObject>
12
13#include "kworkspace_export.h"
14#include <config-outputorder.h>
15
16#if HAVE_X11
17#include <xcb/xcb.h>
18#endif
19
20class QScreen;
21class QTimer;
22
23/**
24 * This class watches for output ordering changes from
25 * the relevant backend
26 */
27class KWORKSPACE_EXPORT OutputOrderWatcher : public QObject
28{
29 Q_OBJECT
30public:
31 /**
32 * Create the correct OutputOrderWatcher
33 */
34 static OutputOrderWatcher *instance(QObject *parent);
35
36 /**
37 * Returns the list of outputs in order
38 *
39 * At the time of change signalling all Screens are
40 * guaranteed to exist in QGuiApplication.
41 *
42 * After screen removal this can temporarily contain
43 * dead entries.
44 */
45 QStringList outputOrder() const;
46
47 /**
48 * @internal
49 * For X11 we know libkscreen takes a server grab whilst changing properties.
50 * This means we know at the time of any runtime screen addition and removal the priorities will
51 * be up-to-date when we poll them.
52 *
53 * For dynamic ordering changes without screen changes we will get the change property multiple times.
54 * A timer is used to batch them.
55 *
56 * A caveat on X11 is the initial startup where plasmashell may query screen information before
57 * kscreen has set properties.
58 * This should resolve itself as a dynamic re-ordering when kscreen does start.
59 *
60 * For wayland we know kwin sends the priority order whenever screen changes are made.
61 * As creating screens requires an extra async call to kwin (to bind to the output)
62 * we always get the new priority ordering before and screen additions.
63 * We should always have correct values on startup.
64 */
65 virtual void refresh();
67 void outputOrderChanged(const QStringList &outputOrder);
68
69protected:
71 /**
72 * Backend failed, use QScreen based implementaion
73 */
74 void useFallback(bool fallback);
75
76 QStringList m_outputOrder;
77 bool m_orderProtocolPresent = false;
78
79private:
80};
81
82#if HAVE_X11
83class X11OutputOrderWatcher : public OutputOrderWatcher, public QAbstractNativeEventFilter
84{
85 Q_OBJECT
86public:
87 X11OutputOrderWatcher(QObject *parent);
88 void refresh() override;
89
90protected:
91 bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
92
93private:
94 void roundtrip() const;
95
96 QNativeInterface::QX11Application *m_x11Interface = nullptr;
97 QTimer *m_delayTimer = nullptr; // This is just to simulate the protocol that will be guaranteed to always arrive after screens additions and removals
98 // Xrandr
99 int m_xrandrExtensionOffset;
100 xcb_atom_t m_kdeScreenAtom = XCB_ATOM_NONE;
101};
102#endif
103
104class WaylandOutputOrderWatcher : public OutputOrderWatcher
105{
107public:
108 WaylandOutputOrderWatcher(QObject *parent);
109 void refresh() override;
110
111private:
112 bool hasAllScreens() const;
113 QStringList m_pendingOutputOrder;
114};
This class watches for output ordering changes from the relevant backend.
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)=0
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Apr 27 2024 22:12:02 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.