File indexing completed on 2025-02-16 11:23:14
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org> 0006 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #pragma once 0012 0013 #include <config-kwin.h> 0014 #include <kwinglobals.h> 0015 0016 #include <KSharedConfig> 0017 #include <memory> 0018 // Qt 0019 #include <QAbstractNativeEventFilter> 0020 #include <QApplication> 0021 #include <QProcessEnvironment> 0022 0023 class KPluginMetaData; 0024 class QCommandLineParser; 0025 0026 namespace KWin 0027 { 0028 0029 class OutputBackend; 0030 class Session; 0031 class X11EventFilter; 0032 class PluginManager; 0033 class InputMethod; 0034 class ColorManager; 0035 class ScreenLockerWatcher; 0036 class TabletModeManager; 0037 class XwaylandInterface; 0038 class Edge; 0039 class ScreenEdges; 0040 class Outline; 0041 class OutlineVisual; 0042 class Compositor; 0043 class WorkspaceScene; 0044 class Window; 0045 0046 class XcbEventFilter : public QAbstractNativeEventFilter 0047 { 0048 public: 0049 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0050 bool nativeEventFilter(const QByteArray &eventType, void *message, long int *result) override; 0051 #else 0052 bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; 0053 #endif 0054 }; 0055 0056 class X11EventFilterContainer : public QObject 0057 { 0058 Q_OBJECT 0059 0060 public: 0061 explicit X11EventFilterContainer(X11EventFilter *filter); 0062 0063 X11EventFilter *filter() const; 0064 0065 private: 0066 X11EventFilter *m_filter; 0067 }; 0068 0069 class KWIN_EXPORT Application : public QApplication 0070 { 0071 Q_OBJECT 0072 Q_PROPERTY(quint32 x11Time READ x11Time WRITE setX11Time) 0073 Q_PROPERTY(quint32 x11RootWindow READ x11RootWindow CONSTANT) 0074 Q_PROPERTY(void *x11Connection READ x11Connection NOTIFY x11ConnectionChanged) 0075 Q_PROPERTY(KSharedConfigPtr config READ config WRITE setConfig) 0076 Q_PROPERTY(KSharedConfigPtr kxkbConfig READ kxkbConfig WRITE setKxkbConfig) 0077 public: 0078 /** 0079 * @brief This enum provides the various operation modes of KWin depending on the available 0080 * Windowing Systems at startup. For example whether KWin only talks to X11 or also to a Wayland 0081 * Compositor. 0082 * 0083 */ 0084 enum OperationMode { 0085 /** 0086 * @brief KWin uses only X11 for managing windows and compositing 0087 */ 0088 OperationModeX11, 0089 /** 0090 * @brief KWin uses only Wayland 0091 */ 0092 OperationModeWaylandOnly, 0093 /** 0094 * @brief KWin uses Wayland and controls a nested Xwayland server. 0095 */ 0096 OperationModeXwayland 0097 }; 0098 Q_ENUM(OperationMode) 0099 ~Application() override; 0100 0101 void setConfigLock(bool lock); 0102 0103 KSharedConfigPtr config() const 0104 { 0105 return m_config; 0106 } 0107 void setConfig(KSharedConfigPtr config) 0108 { 0109 m_config = std::move(config); 0110 } 0111 0112 KSharedConfigPtr kxkbConfig() const 0113 { 0114 return m_kxkbConfig; 0115 } 0116 void setKxkbConfig(KSharedConfigPtr config) 0117 { 0118 m_kxkbConfig = std::move(config); 0119 } 0120 0121 void start(); 0122 /** 0123 * @brief The operation mode used by KWin. 0124 * 0125 * @return OperationMode 0126 */ 0127 OperationMode operationMode() const; 0128 void setOperationMode(OperationMode mode); 0129 bool shouldUseWaylandForCompositing() const; 0130 0131 void setupTranslator(); 0132 void setupCommandLine(QCommandLineParser *parser); 0133 void processCommandLine(QCommandLineParser *parser); 0134 0135 void registerEventFilter(X11EventFilter *filter); 0136 void unregisterEventFilter(X11EventFilter *filter); 0137 bool dispatchEvent(xcb_generic_event_t *event); 0138 0139 xcb_timestamp_t x11Time() const 0140 { 0141 return m_x11Time; 0142 } 0143 enum class TimestampUpdate { 0144 OnlyIfLarger, 0145 Always 0146 }; 0147 void setX11Time(xcb_timestamp_t timestamp, TimestampUpdate force = TimestampUpdate::OnlyIfLarger) 0148 { 0149 if ((timestamp > m_x11Time || force == TimestampUpdate::Always) && timestamp != 0) { 0150 m_x11Time = timestamp; 0151 } 0152 } 0153 /** 0154 * Queries the current X11 time stamp of the X server. 0155 */ 0156 void updateXTime(); 0157 void updateX11Time(xcb_generic_event_t *event); 0158 0159 static void setCrashCount(int count); 0160 static bool wasCrash(); 0161 void resetCrashesCount(); 0162 0163 /** 0164 * Creates the KAboutData object for the KWin instance and registers it as 0165 * KAboutData::setApplicationData. 0166 */ 0167 static void createAboutData(); 0168 0169 /** 0170 * @returns the X11 root window. 0171 */ 0172 xcb_window_t x11RootWindow() const 0173 { 0174 return m_rootWindow; 0175 } 0176 0177 /** 0178 * @returns the X11 xcb connection 0179 */ 0180 xcb_connection_t *x11Connection() const 0181 { 0182 return m_connection; 0183 } 0184 0185 /** 0186 * Inheriting classes should use this method to set the X11 root window 0187 * before accessing any X11 specific code pathes. 0188 */ 0189 void setX11RootWindow(xcb_window_t root) 0190 { 0191 m_rootWindow = root; 0192 } 0193 /** 0194 * Inheriting classes should use this method to set the xcb connection 0195 * before accessing any X11 specific code pathes. 0196 */ 0197 void setX11Connection(xcb_connection_t *c) 0198 { 0199 m_connection = c; 0200 } 0201 0202 qreal xwaylandScale() const 0203 { 0204 return m_xwaylandScale; 0205 } 0206 0207 void setXwaylandScale(qreal scale); 0208 0209 #if KWIN_BUILD_ACTIVITIES 0210 bool usesKActivities() const 0211 { 0212 return m_useKActivities; 0213 } 0214 void setUseKActivities(bool use) 0215 { 0216 m_useKActivities = use; 0217 } 0218 #endif 0219 0220 QProcessEnvironment processStartupEnvironment() const; 0221 void setProcessStartupEnvironment(const QProcessEnvironment &environment); 0222 0223 OutputBackend *outputBackend() const 0224 { 0225 return m_outputBackend.get(); 0226 } 0227 void setOutputBackend(std::unique_ptr<OutputBackend> &&backend); 0228 0229 Session *session() const 0230 { 0231 return m_session.get(); 0232 } 0233 void setSession(std::unique_ptr<Session> &&session); 0234 void setFollowLocale1(bool follow) 0235 { 0236 m_followLocale1 = follow; 0237 } 0238 bool followLocale1() const 0239 { 0240 return m_followLocale1; 0241 } 0242 0243 bool isTerminating() const 0244 { 0245 return m_terminating; 0246 } 0247 0248 void installNativeX11EventFilter(); 0249 void removeNativeX11EventFilter(); 0250 0251 void createAtoms(); 0252 void destroyAtoms(); 0253 0254 virtual std::unique_ptr<Edge> createScreenEdge(ScreenEdges *parent); 0255 virtual void createPlatformCursor(QObject *parent = nullptr); 0256 virtual std::unique_ptr<OutlineVisual> createOutline(Outline *outline); 0257 virtual void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene); 0258 0259 static void setupMalloc(); 0260 static void setupLocalizedString(); 0261 0262 PluginManager *pluginManager() const; 0263 InputMethod *inputMethod() const; 0264 ColorManager *colorManager() const; 0265 virtual XwaylandInterface *xwayland() const; 0266 #if KWIN_BUILD_SCREENLOCKER 0267 ScreenLockerWatcher *screenLockerWatcher() const; 0268 #endif 0269 0270 /** 0271 * Starts an interactive window selection process. 0272 * 0273 * Once the user selected a window the @p callback is invoked with the selected Window as 0274 * argument. In case the user cancels the interactive window selection or selecting a window is currently 0275 * not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument. 0276 * 0277 * During the interactive window selection the cursor is turned into a crosshair cursor unless 0278 * @p cursorName is provided. The argument @p cursorName is a QByteArray instead of Qt::CursorShape 0279 * to support the "pirate" cursor for kill window which is not wrapped by Qt::CursorShape. 0280 * 0281 * The default implementation forwards to InputRedirection. 0282 * 0283 * @param callback The function to invoke once the interactive window selection ends 0284 * @param cursorName The optional name of the cursor shape to use, default is crosshair 0285 */ 0286 virtual void startInteractiveWindowSelection(std::function<void(KWin::Window *)> callback, const QByteArray &cursorName = QByteArray()); 0287 0288 /** 0289 * Starts an interactive position selection process. 0290 * 0291 * Once the user selected a position on the screen the @p callback is invoked with 0292 * the selected point as argument. In case the user cancels the interactive position selection 0293 * or selecting a position is currently not possible (e.g. screen locked) the @p callback 0294 * is invoked with a point at @c -1 as x and y argument. 0295 * 0296 * During the interactive window selection the cursor is turned into a crosshair cursor. 0297 * 0298 * The default implementation forwards to InputRedirection. 0299 * 0300 * @param callback The function to invoke once the interactive position selection ends 0301 */ 0302 virtual void startInteractivePositionSelection(std::function<void(const QPoint &)> callback); 0303 0304 /** 0305 * Returns a PlatformCursorImage. By default this is created by softwareCursor and 0306 * softwareCursorHotspot. An implementing subclass can use this to provide a better 0307 * suited PlatformCursorImage. 0308 * 0309 * @see softwareCursor 0310 * @see softwareCursorHotspot 0311 * @since 5.9 0312 */ 0313 virtual PlatformCursorImage cursorImage() const; 0314 0315 Q_SIGNALS: 0316 void x11ConnectionChanged(); 0317 void x11ConnectionAboutToBeDestroyed(); 0318 void xwaylandScaleChanged(); 0319 void workspaceCreated(); 0320 void virtualTerminalCreated(); 0321 void started(); 0322 0323 protected: 0324 Application(OperationMode mode, int &argc, char **argv); 0325 virtual void performStartup() = 0; 0326 0327 void notifyKSplash(); 0328 void notifyStarted(); 0329 void createInput(); 0330 void createWorkspace(); 0331 void createOptions(); 0332 void createPlugins(); 0333 void createColorManager(); 0334 void createInputMethod(); 0335 void createTabletModeManager(); 0336 void destroyInput(); 0337 void destroyWorkspace(); 0338 void destroyCompositor(); 0339 void destroyPlugins(); 0340 void destroyColorManager(); 0341 void destroyInputMethod(); 0342 void destroyPlatform(); 0343 0344 void setTerminating() 0345 { 0346 m_terminating = true; 0347 } 0348 0349 protected: 0350 static int crashes; 0351 0352 private: 0353 QList<QPointer<X11EventFilterContainer>> m_eventFilters; 0354 QList<QPointer<X11EventFilterContainer>> m_genericEventFilters; 0355 std::unique_ptr<XcbEventFilter> m_eventFilter; 0356 bool m_followLocale1 = false; 0357 bool m_configLock; 0358 KSharedConfigPtr m_config; 0359 KSharedConfigPtr m_kxkbConfig; 0360 OperationMode m_operationMode; 0361 xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME; 0362 xcb_window_t m_rootWindow = XCB_WINDOW_NONE; 0363 xcb_connection_t *m_connection = nullptr; 0364 #if KWIN_BUILD_ACTIVITIES 0365 bool m_useKActivities = true; 0366 #endif 0367 std::unique_ptr<Session> m_session; 0368 std::unique_ptr<OutputBackend> m_outputBackend; 0369 bool m_terminating = false; 0370 qreal m_xwaylandScale = 1; 0371 QProcessEnvironment m_processEnvironment; 0372 std::unique_ptr<PluginManager> m_pluginManager; 0373 std::unique_ptr<InputMethod> m_inputMethod; 0374 std::unique_ptr<ColorManager> m_colorManager; 0375 std::unique_ptr<TabletModeManager> m_tabletModeManager; 0376 #if KWIN_BUILD_SCREENLOCKER 0377 std::unique_ptr<ScreenLockerWatcher> m_screenLockerWatcher; 0378 #endif 0379 }; 0380 0381 inline static Application *kwinApp() 0382 { 0383 Q_ASSERT(qobject_cast<Application *>(QCoreApplication::instance())); 0384 0385 return static_cast<Application *>(QCoreApplication::instance()); 0386 } 0387 0388 } // namespace