File indexing completed on 2025-02-02 04:26:13
0001 /* This file is part of Spectacle, the KDE screenshot utility 0002 * SPDX-FileCopyrightText: 2019 Boudhayan Gupta <bgupta@kde.org> 0003 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "PlatformLoader.h" 0008 #include "Config.h" 0009 #include "PlasmaVersion.h" 0010 #include "ScreenShotEffect.h" 0011 0012 #include "ImagePlatformKWin.h" 0013 #include "PlatformNull.h" 0014 #include "VideoPlatformWayland.h" 0015 0016 #ifdef XCB_FOUND 0017 #include "ImagePlatformXcb.h" 0018 #endif 0019 0020 #include <KWindowSystem> 0021 0022 #include <QDebug> 0023 0024 ImagePlatformPtr getForcedImagePlatform() 0025 { 0026 // This environment variable is only for testing purposes. 0027 auto platformName = qgetenv("SPECTACLE_IMAGE_PLATFORM"); 0028 if (platformName.isEmpty()) { 0029 return nullptr; 0030 } 0031 0032 if (platformName == ImagePlatformKWin::staticMetaObject.className()) { 0033 return std::make_unique<ImagePlatformKWin>(); 0034 } else if (platformName == ImagePlatformXcb::staticMetaObject.className()) { 0035 return std::make_unique<ImagePlatformXcb>(); 0036 } else if (platformName == ImagePlatformNull::staticMetaObject.className()) { 0037 return std::make_unique<ImagePlatformNull>(); 0038 } else if (!platformName.isEmpty()) { 0039 qWarning() << "SPECTACLE_IMAGE_PLATFORM:" << platformName << "is invalid"; 0040 } 0041 0042 return nullptr; 0043 } 0044 0045 ImagePlatformPtr loadImagePlatform() 0046 { 0047 if (auto platform = getForcedImagePlatform()) { 0048 return platform; 0049 } 0050 0051 // Check XDG_SESSION_TYPE because Spectacle might be using the XCB platform via XWayland 0052 const bool isReallyX11 = KWindowSystem::isPlatformX11() && qstrcmp(qgetenv("XDG_SESSION_TYPE").constData(), "wayland") != 0; 0053 // Before KWin 5.27.8, there was an infinite loop in KWin on X11 when doing rectangle captures. 0054 // Spectacle uses CaptureScreen DBus calls to KWin for rectangle captures. 0055 if (ScreenShotEffect::isLoaded() && ScreenShotEffect::version() != ScreenShotEffect::NullVersion 0056 && (!isReallyX11 || PlasmaVersion::get() >= PlasmaVersion::check(5, 27, 8))) { 0057 return std::make_unique<ImagePlatformKWin>(); 0058 } 0059 #ifdef XCB_FOUND 0060 else if (isReallyX11) { 0061 return std::make_unique<ImagePlatformXcb>(); 0062 } 0063 #endif 0064 // If nothing else worked, return the null platform 0065 return std::make_unique<ImagePlatformNull>(); 0066 } 0067 0068 VideoPlatformPtr getForcedVideoPlatform() 0069 { 0070 // This environment variable is only for testing purposes. 0071 auto platformName = qgetenv("SPECTACLE_VIDEO_PLATFORM"); 0072 if (platformName.isEmpty()) { 0073 return nullptr; 0074 } 0075 0076 if (platformName == VideoPlatformWayland::staticMetaObject.className()) { 0077 return std::make_unique<VideoPlatformWayland>(); 0078 } else if (platformName == VideoPlatformNull::staticMetaObject.className()) { 0079 return std::make_unique<VideoPlatformNull>(); 0080 } else if (!platformName.isEmpty()) { 0081 qWarning() << "SPECTACLE_VIDEO_PLATFORM:" << platformName << "is invalid"; 0082 } 0083 0084 return nullptr; 0085 } 0086 0087 VideoPlatformPtr loadVideoPlatform() 0088 { 0089 if (auto platform = getForcedVideoPlatform()) { 0090 return platform; 0091 } 0092 if (KWindowSystem::isPlatformWayland()) { 0093 return std::make_unique<VideoPlatformWayland>(); 0094 } 0095 return std::make_unique<VideoPlatformNull>(); 0096 }