1 /*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #ifndef MAIN_H
12 #define MAIN_H
13
14 #include <kwinglobals.h>
15 #include <config-kwin.h>
16
17 #include <KSharedConfig>
18 // Qt
19 #include <QApplication>
20 #include <QAbstractNativeEventFilter>
21 #include <QProcessEnvironment>
22
23 class KPluginMetaData;
24 class QCommandLineParser;
25
26 namespace KWin
27 {
28
29 class Platform;
30 class X11EventFilter;
31
32 class XcbEventFilter : public QAbstractNativeEventFilter
33 {
34 public:
35 bool nativeEventFilter(const QByteArray &eventType, void *message, long int *result) override;
36 };
37
38 class X11EventFilterContainer : public QObject
39 {
40 Q_OBJECT
41
42 public:
43 explicit X11EventFilterContainer(X11EventFilter *filter);
44
45 X11EventFilter *filter() const;
46
47 private:
48 X11EventFilter *m_filter;
49 };
50
51 class KWIN_EXPORT Application : public QApplication
52 {
53 Q_OBJECT
54 Q_PROPERTY(quint32 x11Time READ x11Time WRITE setX11Time)
55 Q_PROPERTY(quint32 x11RootWindow READ x11RootWindow CONSTANT)
56 Q_PROPERTY(void *x11Connection READ x11Connection NOTIFY x11ConnectionChanged)
57 Q_PROPERTY(int x11ScreenNumber READ x11ScreenNumber CONSTANT)
58 Q_PROPERTY(KSharedConfigPtr config READ config WRITE setConfig)
59 Q_PROPERTY(KSharedConfigPtr kxkbConfig READ kxkbConfig WRITE setKxkbConfig)
60 public:
61 /**
62 * @brief This enum provides the various operation modes of KWin depending on the available
63 * Windowing Systems at startup. For example whether KWin only talks to X11 or also to a Wayland
64 * Compositor.
65 *
66 */
67 enum OperationMode {
68 /**
69 * @brief KWin uses only X11 for managing windows and compositing
70 */
71 OperationModeX11,
72 /**
73 * @brief KWin uses only Wayland
74 */
75 OperationModeWaylandOnly,
76 /**
77 * @brief KWin uses Wayland and controls a nested Xwayland server.
78 */
79 OperationModeXwayland
80 };
81 ~Application() override;
82
83 void setConfigLock(bool lock);
84
config()85 KSharedConfigPtr config() const {
86 return m_config;
87 }
setConfig(KSharedConfigPtr config)88 void setConfig(KSharedConfigPtr config) {
89 m_config = std::move(config);
90 }
91
kxkbConfig()92 KSharedConfigPtr kxkbConfig() const {
93 return m_kxkbConfig;
94 }
setKxkbConfig(KSharedConfigPtr config)95 void setKxkbConfig(KSharedConfigPtr config) {
96 m_kxkbConfig = std::move(config);
97 }
98
99 void start();
100 /**
101 * @brief The operation mode used by KWin.
102 *
103 * @return OperationMode
104 */
105 OperationMode operationMode() const;
106 void setOperationMode(OperationMode mode);
107 bool shouldUseWaylandForCompositing() const;
108
109 void setupTranslator();
110 void setupCommandLine(QCommandLineParser *parser);
111 void processCommandLine(QCommandLineParser *parser);
112
113 void registerEventFilter(X11EventFilter *filter);
114 void unregisterEventFilter(X11EventFilter *filter);
115 bool dispatchEvent(xcb_generic_event_t *event);
116
x11Time()117 xcb_timestamp_t x11Time() const {
118 return m_x11Time;
119 }
120 enum class TimestampUpdate {
121 OnlyIfLarger,
122 Always
123 };
124 void setX11Time(xcb_timestamp_t timestamp, TimestampUpdate force = TimestampUpdate::OnlyIfLarger) {
125 if ((timestamp > m_x11Time || force == TimestampUpdate::Always) && timestamp != 0) {
126 m_x11Time = timestamp;
127 }
128 }
129 void updateX11Time(xcb_generic_event_t *event);
130 void createScreens();
131
132 static void setCrashCount(int count);
133 static bool wasCrash();
134 void resetCrashesCount();
135
136 /**
137 * Creates the KAboutData object for the KWin instance and registers it as
138 * KAboutData::setApplicationData.
139 */
140 static void createAboutData();
141
142 /**
143 * @returns the X11 Screen number. If not applicable it's set to @c -1.
144 */
145 static int x11ScreenNumber();
146 /**
147 * Sets the X11 screen number of this KWin instance to @p screenNumber.
148 */
149 static void setX11ScreenNumber(int screenNumber);
150 /**
151 * @returns whether this is a multi head setup on X11.
152 */
153 static bool isX11MultiHead();
154 /**
155 * Sets whether this is a multi head setup on X11.
156 */
157 static void setX11MultiHead(bool multiHead);
158
159 /**
160 * @returns the X11 root window.
161 */
x11RootWindow()162 xcb_window_t x11RootWindow() const {
163 return m_rootWindow;
164 }
165
166 /**
167 * @returns the X11 xcb connection
168 */
x11Connection()169 xcb_connection_t *x11Connection() const {
170 return m_connection;
171 }
172
173 /**
174 * @returns the X11 default screen
175 */
x11DefaultScreen()176 xcb_screen_t *x11DefaultScreen() const {
177 return m_defaultScreen;
178 }
179
180 /**
181 * Returns @c true if we're in the middle of destroying the X11 connection.
182 */
isClosingX11Connection()183 bool isClosingX11Connection() const {
184 return m_isClosingX11Connection;
185 }
186
187 #ifdef KWIN_BUILD_ACTIVITIES
usesKActivities()188 bool usesKActivities() const {
189 return m_useKActivities;
190 }
setUseKActivities(bool use)191 void setUseKActivities(bool use) {
192 m_useKActivities = use;
193 }
194 #endif
195
196 virtual QProcessEnvironment processStartupEnvironment() const;
197
198 void initPlatform(const KPluginMetaData &plugin);
platform()199 Platform *platform() const {
200 return m_platform;
201 }
202
isTerminating()203 bool isTerminating() const {
204 return m_terminating;
205 }
206
207 static void setupMalloc();
208 static void setupLocalizedString();
209
210 static bool usesLibinput();
211 static void setUseLibinput(bool use);
212
213 Q_SIGNALS:
214 void x11ConnectionChanged();
215 void x11ConnectionAboutToBeDestroyed();
216 void workspaceCreated();
217 void screensCreated();
218 void platformCreated();
219 void virtualTerminalCreated();
220 void started();
221
222 protected:
223 Application(OperationMode mode, int &argc, char **argv);
224 virtual void performStartup() = 0;
225
226 void notifyKSplash();
227 void notifyStarted();
228 void createInput();
229 void createWorkspace();
230 void createAtoms();
231 void createOptions();
232 void createPlugins();
233 void createColorManager();
234 void installNativeX11EventFilter();
235 void removeNativeX11EventFilter();
236 void destroyInput();
237 void destroyWorkspace();
238 void destroyCompositor();
239 void destroyPlugins();
240 void destroyColorManager();
241 /**
242 * Inheriting classes should use this method to set the X11 root window
243 * before accessing any X11 specific code pathes.
244 */
setX11RootWindow(xcb_window_t root)245 void setX11RootWindow(xcb_window_t root) {
246 m_rootWindow = root;
247 }
248 /**
249 * Inheriting classes should use this method to set the xcb connection
250 * before accessing any X11 specific code pathes.
251 */
setX11Connection(xcb_connection_t * c)252 void setX11Connection(xcb_connection_t *c) {
253 m_connection = c;
254 }
255 /**
256 * Inheriting classes should use this method to set the default screen
257 * before accessing any X11 specific code pathes.
258 */
setX11DefaultScreen(xcb_screen_t * screen)259 void setX11DefaultScreen(xcb_screen_t *screen) {
260 m_defaultScreen = screen;
261 }
262 void destroyAtoms();
263 void destroyPlatform();
264
setTerminating()265 void setTerminating() {
266 m_terminating = true;
267 }
setClosingX11Connection(bool set)268 void setClosingX11Connection(bool set) {
269 m_isClosingX11Connection = set;
270 }
271
272 protected:
273 static int crashes;
274
275 private:
276 QList<QPointer<X11EventFilterContainer>> m_eventFilters;
277 QList<QPointer<X11EventFilterContainer>> m_genericEventFilters;
278 QScopedPointer<XcbEventFilter> m_eventFilter;
279 bool m_configLock;
280 KSharedConfigPtr m_config;
281 KSharedConfigPtr m_kxkbConfig;
282 OperationMode m_operationMode;
283 xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME;
284 xcb_window_t m_rootWindow = XCB_WINDOW_NONE;
285 xcb_connection_t *m_connection = nullptr;
286 xcb_screen_t *m_defaultScreen = nullptr;
287 #ifdef KWIN_BUILD_ACTIVITIES
288 bool m_useKActivities = true;
289 #endif
290 Platform *m_platform = nullptr;
291 bool m_terminating = false;
292 bool m_isClosingX11Connection = false;
293 };
294
kwinApp()295 inline static Application *kwinApp()
296 {
297 return static_cast<Application*>(QCoreApplication::instance());
298 }
299
300 namespace Xwl
301 {
302 class Xwayland;
303 }
304
305 class KWIN_EXPORT ApplicationWaylandAbstract : public Application
306 {
307 Q_OBJECT
308 public:
309 ~ApplicationWaylandAbstract() override = 0;
310 protected:
311 friend class Xwl::Xwayland;
312
313 ApplicationWaylandAbstract(OperationMode mode, int &argc, char **argv);
setProcessStartupEnvironment(const QProcessEnvironment & environment)314 virtual void setProcessStartupEnvironment(const QProcessEnvironment &environment) {
315 Q_UNUSED(environment);
316 }
startSession()317 virtual void startSession() {}
318 };
319
320
321 } // namespace
322
323 #endif
324