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