File indexing completed on 2024-04-28 05:36:53
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Red Hat Inc 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 * 0006 * SPDX-FileCopyrightText: 2018 Jan Grulich <jgrulich@redhat.com> 0007 * SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> 0008 */ 0009 0010 #include "screenshot.h" 0011 #include "request.h" 0012 #include "screenshot_debug.h" 0013 #include "screenshotdialog.h" 0014 #include "utils.h" 0015 0016 #include <QDBusArgument> 0017 #include <QDBusReply> 0018 #include <QDateTime> 0019 #include <QPointer> 0020 #include <QStandardPaths> 0021 #include <QWindow> 0022 #include <QtDBus> 0023 0024 // Keep in sync with qflatpakcolordialog from Qt flatpak platform theme 0025 Q_DECLARE_METATYPE(ScreenshotPortal::ColorRGB) 0026 0027 QDBusArgument &operator<<(QDBusArgument &arg, const ScreenshotPortal::ColorRGB &color) 0028 { 0029 arg.beginStructure(); 0030 arg << color.red << color.green << color.blue; 0031 arg.endStructure(); 0032 return arg; 0033 } 0034 0035 const QDBusArgument &operator>>(const QDBusArgument &arg, ScreenshotPortal::ColorRGB &color) 0036 { 0037 double red, green, blue; 0038 arg.beginStructure(); 0039 arg >> red >> green >> blue; 0040 color.red = red; 0041 color.green = green; 0042 color.blue = blue; 0043 arg.endStructure(); 0044 0045 return arg; 0046 } 0047 0048 QDBusArgument &operator<<(QDBusArgument &argument, const QColor &color) 0049 { 0050 argument.beginStructure(); 0051 argument << color.rgba(); 0052 argument.endStructure(); 0053 return argument; 0054 } 0055 0056 const QDBusArgument &operator>>(const QDBusArgument &argument, QColor &color) 0057 { 0058 argument.beginStructure(); 0059 QRgb rgba; 0060 argument >> rgba; 0061 argument.endStructure(); 0062 color = QColor::fromRgba(rgba); 0063 return argument; 0064 } 0065 0066 ScreenshotPortal::ScreenshotPortal(QObject *parent) 0067 : QDBusAbstractAdaptor(parent) 0068 { 0069 qDBusRegisterMetaType<QColor>(); 0070 qDBusRegisterMetaType<ColorRGB>(); 0071 } 0072 0073 ScreenshotPortal::~ScreenshotPortal() 0074 { 0075 } 0076 0077 uint ScreenshotPortal::Screenshot(const QDBusObjectPath &handle, 0078 const QString &app_id, 0079 const QString &parent_window, 0080 const QVariantMap &options, 0081 QVariantMap &results) 0082 { 0083 qCDebug(XdgDesktopPortalKdeScreenshot) << "Screenshot called with parameters:"; 0084 qCDebug(XdgDesktopPortalKdeScreenshot) << " handle: " << handle.path(); 0085 qCDebug(XdgDesktopPortalKdeScreenshot) << " app_id: " << app_id; 0086 qCDebug(XdgDesktopPortalKdeScreenshot) << " parent_window: " << parent_window; 0087 qCDebug(XdgDesktopPortalKdeScreenshot) << " options: " << options; 0088 0089 QPointer<ScreenshotDialog> screenshotDialog = new ScreenshotDialog; 0090 Utils::setParentWindow(screenshotDialog->windowHandle(), parent_window); 0091 Request::makeClosableDialogRequest(handle, screenshotDialog.data()); 0092 0093 const bool modal = options.value(QStringLiteral("modal"), false).toBool(); 0094 screenshotDialog->windowHandle()->setModality(modal ? Qt::WindowModal : Qt::NonModal); 0095 0096 const bool interactive = options.value(QStringLiteral("interactive"), false).toBool(); 0097 if (!interactive) { 0098 screenshotDialog->takeScreenshotNonInteractive(); 0099 } else { 0100 screenshotDialog->exec(); 0101 } 0102 0103 const QImage screenshot = screenshotDialog->image(); 0104 0105 if (screenshotDialog) { 0106 screenshotDialog->deleteLater(); 0107 } 0108 0109 if (screenshot.isNull()) { 0110 return 1; 0111 } 0112 0113 const QString filename = 0114 QStringLiteral("%1/Screenshot_%2.png") // 0115 .arg(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmss"))); 0116 0117 if (!screenshot.save(filename, "PNG")) { 0118 return 1; 0119 } 0120 0121 results.insert(QStringLiteral("uri"), QUrl::fromLocalFile(filename).toString(QUrl::FullyEncoded)); 0122 0123 return 0; 0124 } 0125 0126 uint ScreenshotPortal::PickColor(const QDBusObjectPath &handle, 0127 const QString &app_id, 0128 const QString &parent_window, 0129 const QVariantMap &options, 0130 QVariantMap &results) 0131 { 0132 qCDebug(XdgDesktopPortalKdeScreenshot) << "PickColor called with parameters:"; 0133 qCDebug(XdgDesktopPortalKdeScreenshot) << " handle: " << handle.path(); 0134 qCDebug(XdgDesktopPortalKdeScreenshot) << " app_id: " << app_id; 0135 qCDebug(XdgDesktopPortalKdeScreenshot) << " parent_window: " << parent_window; 0136 qCDebug(XdgDesktopPortalKdeScreenshot) << " options: " << options; 0137 0138 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), 0139 QStringLiteral("/ColorPicker"), 0140 QStringLiteral("org.kde.kwin.ColorPicker"), 0141 QStringLiteral("pick")); 0142 QDBusReply<QColor> reply = QDBusConnection::sessionBus().call(msg); 0143 if (reply.isValid() && !reply.error().isValid()) { 0144 QColor selectedColor = reply.value(); 0145 ColorRGB color; 0146 color.red = selectedColor.redF(); 0147 color.green = selectedColor.greenF(); 0148 color.blue = selectedColor.blueF(); 0149 0150 results.insert(QStringLiteral("color"), QVariant::fromValue<ScreenshotPortal::ColorRGB>(color)); 0151 return 0; 0152 } 0153 0154 return 1; 0155 }