File indexing completed on 2024-12-08 04:20:24
0001 /* 0002 * SPDX-License-Identifier: LGPL-2.0-or-later 0003 * 0004 * SPDX-FileCopyrightText: 2022 Aleix Pol Gonzalez <aleixpol@kde.org> 0005 */ 0006 0007 #include "xdgexporterv2.h" 0008 0009 #include <qpa/qplatformnativeinterface.h> 0010 #include <QDebug> 0011 #include <QGuiApplication> 0012 #include <QWindow> 0013 #include <QWidget> 0014 0015 class WidgetWatcher : public QObject 0016 { 0017 public: 0018 WidgetWatcher(XdgExporterV2 *exporter, XdgExportedV2 *toExport, QWidget *theWidget) 0019 : QObject(theWidget) 0020 , m_toExport(toExport) 0021 , m_widget(theWidget) 0022 , m_exporter(exporter) 0023 { 0024 theWidget->installEventFilter(this); 0025 } 0026 0027 ~WidgetWatcher() { 0028 delete m_toExport; 0029 } 0030 0031 bool eventFilter(QObject * watched, QEvent * event) override { 0032 Q_ASSERT(watched == parent()); 0033 if (event->type() == QEvent::PlatformSurface) { 0034 m_toExport->setWindow(m_widget->windowHandle()); 0035 } 0036 return false; 0037 } 0038 0039 QPointer<XdgExportedV2> m_toExport; 0040 QWidget *const m_widget; 0041 XdgExporterV2 *const m_exporter; 0042 }; 0043 0044 XdgExportedV2::XdgExportedV2(XdgExporterV2* exporter) 0045 : QtWayland::zxdg_exported_v2() 0046 , m_exporter(exporter) 0047 { 0048 } 0049 0050 XdgExportedV2::~XdgExportedV2() 0051 { 0052 destroy(); 0053 } 0054 0055 void XdgExportedV2::setWindow(QWindow* window) { 0056 Q_ASSERT(window); 0057 0058 useWindow(window); 0059 connect(window, &QWindow::visibilityChanged, this, [this, window] (QWindow::Visibility visibility) { 0060 if (visibility != QWindow::Hidden) { 0061 useWindow(window); 0062 } 0063 }); 0064 connect(window, &QWindow::destroyed, this, &QObject::deleteLater); 0065 } 0066 0067 void XdgExportedV2::useWindow(QWindow* window) 0068 { 0069 QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface(); 0070 auto surface = static_cast<wl_surface *>(nativeInterface->nativeResourceForWindow("surface", window)); 0071 if (surface) { 0072 auto tl = m_exporter->export_toplevel(surface); 0073 if (tl) { 0074 init(tl); 0075 } else { 0076 qDebug() << "could not export top level"; 0077 } 0078 } else { 0079 qDebug() << "could not get surface"; 0080 } 0081 } 0082 0083 std::optional<QString> XdgExportedV2::handle() const 0084 { 0085 return m_handle; 0086 } 0087 0088 /////////////////////////////////////////////////////////// 0089 0090 XdgExporterV2::XdgExporterV2() 0091 : QWaylandClientExtensionTemplate(ZXDG_EXPORTER_V2_DESTROY_SINCE_VERSION) 0092 { 0093 initialize(); 0094 0095 if (!isInitialized()) { 0096 qWarning() << "Remember requesting the interface on your desktop file: X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1"; 0097 } 0098 Q_ASSERT(isInitialized()); 0099 } 0100 0101 XdgExporterV2::~XdgExporterV2() 0102 { 0103 destroy(); 0104 } 0105 0106 XdgExportedV2* XdgExporterV2::exportWindow(QWindow* window) 0107 { 0108 if (!window) { 0109 qDebug() << "no window!"; 0110 return nullptr; 0111 } 0112 0113 auto exported = new XdgExportedV2(this); 0114 exported->setWindow(window); 0115 return exported; 0116 } 0117 0118 XdgExportedV2* XdgExporterV2::exportWidget(QWidget* widget) 0119 { 0120 if (widget->windowHandle()) { 0121 return exportWindow(widget->windowHandle()); 0122 } 0123 auto nakedExporter = new XdgExportedV2(this); 0124 new WidgetWatcher(this, nakedExporter, widget); 0125 return nakedExporter; 0126 }