File indexing completed on 2024-11-10 04:57:05
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 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "integration.h" 0012 #include "backingstore.h" 0013 #include "eglplatformcontext.h" 0014 #include "logging.h" 0015 #include "offscreensurface.h" 0016 #include "screen.h" 0017 #include "window.h" 0018 0019 #include "core/output.h" 0020 #include "core/outputbackend.h" 0021 #include "main.h" 0022 #include "workspace.h" 0023 0024 #include <QCoreApplication> 0025 #include <QTimer> 0026 #include <QtConcurrentRun> 0027 0028 #include <qpa/qplatformaccessibility.h> 0029 #include <qpa/qplatformnativeinterface.h> 0030 #include <qpa/qplatformwindow.h> 0031 #include <qpa/qwindowsysteminterface.h> 0032 0033 #include <QtGui/private/qgenericunixeventdispatcher_p.h> 0034 #include <QtGui/private/qgenericunixfontdatabase_p.h> 0035 #include <QtGui/private/qgenericunixthemes_p.h> 0036 #include <QtGui/private/qspiaccessiblebridge_p.h> 0037 #include <QtGui/private/qunixeventdispatcher_qpa_p.h> 0038 0039 namespace KWin 0040 { 0041 0042 namespace QPA 0043 { 0044 0045 Integration::Integration() 0046 : QObject() 0047 , QPlatformIntegration() 0048 , m_fontDb(new QGenericUnixFontDatabase()) 0049 , m_nativeInterface(new QPlatformNativeInterface()) 0050 , m_services(new QGenericUnixServices()) 0051 { 0052 } 0053 0054 Integration::~Integration() 0055 { 0056 for (QPlatformScreen *platformScreen : std::as_const(m_screens)) { 0057 QWindowSystemInterface::handleScreenRemoved(platformScreen); 0058 } 0059 if (m_dummyScreen) { 0060 QWindowSystemInterface::handleScreenRemoved(m_dummyScreen); 0061 } 0062 } 0063 0064 QHash<Output *, Screen *> Integration::screens() const 0065 { 0066 return m_screens; 0067 } 0068 0069 bool Integration::hasCapability(Capability cap) const 0070 { 0071 switch (cap) { 0072 case ThreadedPixmaps: 0073 return true; 0074 case OpenGL: 0075 return true; 0076 case ThreadedOpenGL: 0077 return false; 0078 case BufferQueueingOpenGL: 0079 return false; 0080 case MultipleWindows: 0081 case NonFullScreenWindows: 0082 return true; 0083 case RasterGLSurface: 0084 return false; 0085 default: 0086 return QPlatformIntegration::hasCapability(cap); 0087 } 0088 } 0089 0090 void Integration::initialize() 0091 { 0092 // This method is called from QGuiApplication's constructor, before kwinApp is built 0093 QTimer::singleShot(0, this, [this] { 0094 // The QPA is initialized before the workspace is created. 0095 if (workspace()) { 0096 handleWorkspaceCreated(); 0097 } else { 0098 connect(kwinApp(), &Application::workspaceCreated, this, &Integration::handleWorkspaceCreated); 0099 } 0100 }); 0101 0102 QPlatformIntegration::initialize(); 0103 0104 m_dummyScreen = new PlaceholderScreen(); 0105 QWindowSystemInterface::handleScreenAdded(m_dummyScreen); 0106 } 0107 0108 QAbstractEventDispatcher *Integration::createEventDispatcher() const 0109 { 0110 return new QUnixEventDispatcherQPA; 0111 } 0112 0113 QPlatformBackingStore *Integration::createPlatformBackingStore(QWindow *window) const 0114 { 0115 return new BackingStore(window); 0116 } 0117 0118 QPlatformWindow *Integration::createPlatformWindow(QWindow *window) const 0119 { 0120 return new Window(window); 0121 } 0122 0123 QPlatformOffscreenSurface *Integration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const 0124 { 0125 return new OffscreenSurface(surface); 0126 } 0127 0128 QPlatformFontDatabase *Integration::fontDatabase() const 0129 { 0130 return m_fontDb.get(); 0131 } 0132 0133 QPlatformTheme *Integration::createPlatformTheme(const QString &name) const 0134 { 0135 return QGenericUnixTheme::createUnixTheme(name); 0136 } 0137 0138 QStringList Integration::themeNames() const 0139 { 0140 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION")) { 0141 return QStringList({QStringLiteral("kde")}); 0142 } 0143 return QStringList({QLatin1String(QGenericUnixTheme::name)}); 0144 } 0145 0146 QPlatformOpenGLContext *Integration::createPlatformOpenGLContext(QOpenGLContext *context) const 0147 { 0148 if (kwinApp()->outputBackend()->sceneEglGlobalShareContext() == EGL_NO_CONTEXT) { 0149 qCWarning(KWIN_QPA) << "Attempting to create a QOpenGLContext before the scene is initialized"; 0150 return nullptr; 0151 } 0152 EglDisplay *const eglDisplay = kwinApp()->outputBackend()->sceneEglDisplayObject(); 0153 if (eglDisplay) { 0154 EGLPlatformContext *platformContext = new EGLPlatformContext(context, eglDisplay); 0155 return platformContext; 0156 } 0157 return nullptr; 0158 } 0159 0160 QPlatformAccessibility *Integration::accessibility() const 0161 { 0162 if (!m_accessibility) { 0163 m_accessibility.reset(new QSpiAccessibleBridge()); 0164 } 0165 return m_accessibility.get(); 0166 } 0167 0168 void Integration::handleWorkspaceCreated() 0169 { 0170 connect(workspace(), &Workspace::outputAdded, 0171 this, &Integration::handleOutputEnabled); 0172 connect(workspace(), &Workspace::outputRemoved, 0173 this, &Integration::handleOutputDisabled); 0174 0175 const QList<Output *> outputs = workspace()->outputs(); 0176 for (Output *output : outputs) { 0177 handleOutputEnabled(output); 0178 } 0179 } 0180 0181 void Integration::handleOutputEnabled(Output *output) 0182 { 0183 Screen *platformScreen = new Screen(output, this); 0184 QWindowSystemInterface::handleScreenAdded(platformScreen); 0185 m_screens.insert(output, platformScreen); 0186 0187 if (m_dummyScreen) { 0188 QWindowSystemInterface::handleScreenRemoved(m_dummyScreen); 0189 m_dummyScreen = nullptr; 0190 } 0191 } 0192 0193 void Integration::handleOutputDisabled(Output *output) 0194 { 0195 Screen *platformScreen = m_screens.take(output); 0196 if (!platformScreen) { 0197 qCWarning(KWIN_QPA) << "Unknown output" << output; 0198 return; 0199 } 0200 0201 if (m_screens.isEmpty()) { 0202 m_dummyScreen = new PlaceholderScreen(); 0203 QWindowSystemInterface::handleScreenAdded(m_dummyScreen); 0204 } 0205 0206 QWindowSystemInterface::handleScreenRemoved(platformScreen); 0207 } 0208 0209 QPlatformNativeInterface *Integration::nativeInterface() const 0210 { 0211 return m_nativeInterface.get(); 0212 } 0213 0214 QPlatformServices *Integration::services() const 0215 { 0216 return m_services.get(); 0217 } 0218 0219 } 0220 } 0221 0222 #include "moc_integration.cpp"