aboutsummaryrefslogtreecommitdiffstats
path: root/community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch')
-rw-r--r--community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch449
1 files changed, 0 insertions, 449 deletions
diff --git a/community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch b/community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch
deleted file mode 100644
index 9b8654a4db1..00000000000
--- a/community/plasma-phone-components/0001-Port-to-the-new-org.kde.KWin.ScreenShots2-interface.patch
+++ /dev/null
@@ -1,449 +0,0 @@
-From 989d6fdc1dbf399d3daafa3c53327288a9cc7d01 Mon Sep 17 00:00:00 2001
-From: Aleix Pol <aleixpol@kde.org>
-Date: Fri, 23 Jul 2021 03:30:16 +0200
-Subject: [PATCH] Port to the new org.kde.KWin.ScreenShots2 interface
-
-Fixes https://invent.kde.org/plasma/plasma-phone-components/-/issues/85
----
- containments/panel/CMakeLists.txt | 2 +-
- .../panel/dbus/org.kde.KWin.ScreenShot2.xml | 184 ++++++++++++++++++
- containments/panel/phonepanel.cpp | 152 ++++++++-------
- containments/panel/phonepanel.h | 5 +-
- 4 files changed, 274 insertions(+), 69 deletions(-)
- create mode 100644 containments/panel/dbus/org.kde.KWin.ScreenShot2.xml
-
-diff --git a/containments/panel/CMakeLists.txt b/containments/panel/CMakeLists.txt
-index 8758686..b482ac4 100644
---- a/containments/panel/CMakeLists.txt
-+++ b/containments/panel/CMakeLists.txt
-@@ -1,4 +1,4 @@
--qt5_add_dbus_interfaces(DBUS_SRCS dbus/org.kde.KWin.Screenshot.xml
-+qt5_add_dbus_interfaces(DBUS_SRCS dbus/org.kde.KWin.ScreenShot2.xml
- dbus/org.kde.KScreen.xml)
-
- set(phonepanel_SRCS
-diff --git a/containments/panel/dbus/org.kde.KWin.ScreenShot2.xml b/containments/panel/dbus/org.kde.KWin.ScreenShot2.xml
-new file mode 100644
-index 0000000..34c03b2
---- /dev/null
-+++ b/containments/panel/dbus/org.kde.KWin.ScreenShot2.xml
-@@ -0,0 +1,184 @@
-+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
-+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-+<!--
-+ SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
-+
-+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
-+-->
-+<node name="/org/kde/KWin/ScreenShot2">
-+ <!--
-+ org.kde.KWin.ScreenShot2:
-+ @short_description: Screen shot interface
-+
-+ This interface provides a way to request a screenshot of a rectangular area,
-+ a screen, or a window.
-+ -->
-+ <interface name="org.kde.KWin.ScreenShot2">
-+ <!--
-+ CaptureWindow:
-+ @handle: The unique handle that identified the window
-+ @options: Optional vardict with screenshot options
-+ @pipe: The pipe file descriptor where the screenshot will be written
-+
-+ Take a screenshot of the specified window. The application that
-+ requests the screenshot must have the org.kde.KWin.ScreenShot2
-+ interface listed in the X-KDE-DBUS-Restricted-Interfaces desktop
-+ file entry.
-+
-+ Available @options include:
-+
-+ * "include-cursor" (b): Whether the cursor should be included.
-+ Defaults to false
-+ * "include-decoration" (b): Whether the decoration should be included.
-+ Defaults to false
-+ * "native-resolution" (b): Whether the screenshot should be in
-+ native size. Defaults to false
-+
-+ The following results get returned via the @results vardict:
-+
-+ * "type" (s): The type of the image written to the pipe. Currently,
-+ the only supported type is "raw"
-+ * "width" (u): The width of the image. Available only if the image
-+ type is "raw"
-+ * "height" (u): The height of the image. Available only if the image
-+ type is "raw"
-+ * "stride" (u): The number of bytes per row. Available only if the
-+ image type is "raw"
-+ * "format" (u): The image format, as defined in QImage::Format.
-+ Available only if the image type is "raw"
-+ -->
-+ <method name="CaptureWindow">
-+ <arg name="handle" type="s" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap" />
-+ <arg name="options" type="a{sv}" direction="in" />
-+ <arg name="pipe" type="h" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" />
-+ <arg name="results" type="a{sv}" direction="out" />
-+ </method>
-+
-+ <!--
-+ CaptureArea:
-+ @x: The x coordinate of the upper left corner of the area
-+ @y: The y coordinate of the upper left corner of the area
-+ @width: The width of the screenshot area
-+ @height: The height of the screenshot area
-+ @options: Optional vardict with screenshot options
-+ @pipe: The pipe file descriptor where the screenshot will be written
-+
-+ Take a screenshot of the specified rectangular area. The application
-+ that requests the screenshot must have the org.kde.KWin.ScreenShot2
-+ interface listed in the X-KDE-DBUS-Restricted-Interfaces desktop file
-+ entry.
-+
-+ Available @options include:
-+
-+ * "include-cursor" (b): Whether the cursor should be included.
-+ Defaults to false
-+ * "native-resolution" (b): Whether the screenshot should be in
-+ native size. Defaults to false
-+
-+ The following results get returned via the @results vardict:
-+
-+ * "type" (s): The type of the image written to the pipe. Currently,
-+ the only supported type is "raw"
-+ * "width" (u): The width of the image. Available only if the image
-+ type is "raw"
-+ * "height" (u): The height of the image. Available only if the image
-+ type is "raw"
-+ * "stride" (u): The number of bytes per row. Available only if the
-+ image type is "raw"
-+ * "format" (u): The image format, as defined in QImage::Format.
-+ Available only if the image type is "raw"
-+ -->
-+ <method name="CaptureArea">
-+ <arg name="x" type="i" direction="in" />
-+ <arg name="y" type="i" direction="in" />
-+ <arg name="width" type="u" direction="in" />
-+ <arg name="height" type="u" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QVariantMap" />
-+ <arg name="options" type="a{sv}" direction="in" />
-+ <arg name="pipe" type="h" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" />
-+ <arg name="results" type="a{sv}" direction="out" />
-+ </method>
-+
-+ <!--
-+ CaptureScreen:
-+ @name: The name of the screen assigned by the compositor
-+ @options: Optional vardict with screenshot options
-+ @pipe: The pipe file descriptor where the screenshot will be written
-+
-+ Take a screenshot of the specified monitor. The application that
-+ requests the screenshot must have the org.kde.KWin.ScreenShot2
-+ interface listed in the X-KDE-DBUS-Restricted-Interfaces desktop file
-+ entry.
-+
-+ Available @options include:
-+
-+ * "include-cursor" (b): Whether the cursor should be included.
-+ Defaults to false
-+ * "native-resolution" (b): Whether the screenshot should be in
-+ native size. Defaults to false
-+
-+ The following results get returned via the @results vardict:
-+
-+ * "type" (s): The type of the image written to the pipe. Currently,
-+ the only supported type is "raw"
-+ * "width" (u): The width of the image. Available only if the image
-+ type is "raw"
-+ * "height" (u): The height of the image. Available only if the image
-+ type is "raw"
-+ * "stride" (u): The number of bytes per row. Available only if the
-+ image type is "raw"
-+ * "format" (u): The image format, as defined in QImage::Format.
-+ Available only if the image type is "raw"
-+ -->
-+ <method name="CaptureScreen">
-+ <arg name="name" type="s" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap" />
-+ <arg name="options" type="a{sv}" direction="in" />
-+ <arg name="pipe" type="h" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" />
-+ <arg name="results" type="a{sv}" direction="out" />
-+ </method>
-+
-+ <!--
-+ CaptureInteractive:
-+ @kind: 0 - window, 1 - screen
-+ @options: Optional vardict with screenshot options
-+ @pipe: The pipe file descriptor where the screenshot will be written
-+
-+ Take a screenshot of a screen or a window as selected by the user.
-+
-+ Available @options include:
-+
-+ * "include-cursor" (b): Whether the cursor should be included.
-+ Defaults to false
-+ * "include-decoration" (b): Whether the decoration should be included.
-+ Defaults to false
-+ * "native-resolution" (b): Whether the screenshot should be in
-+ native size. Defaults to false
-+
-+ The following results get returned via the @results vardict:
-+
-+ * "type" (s): The type of the image written to the pipe. Currently,
-+ the only supported type is "raw"
-+ * "width" (u): The width of the image. Available only if the image
-+ type is "raw"
-+ * "height" (u): The height of the image. Available only if the image
-+ type is "raw"
-+ * "stride" (u): The number of bytes per row. Available only if the
-+ image type is "raw"
-+ * "format" (u): The image format, as defined in QImage::Format.
-+ Available only if the image type is "raw"
-+ -->
-+ <method name="CaptureInteractive">
-+ <arg name="kind" type="u" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap" />
-+ <arg name="options" type="a{sv}" direction="in" />
-+ <arg name="pipe" type="h" direction="in" />
-+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" />
-+ <arg name="results" type="a{sv}" direction="out" />
-+ </method>
-+ </interface>
-+</node>
-diff --git a/containments/panel/phonepanel.cpp b/containments/panel/phonepanel.cpp
-index 06aab12..35a72a8 100644
---- a/containments/panel/phonepanel.cpp
-+++ b/containments/panel/phonepanel.cpp
-@@ -19,6 +19,7 @@
- #include <QDateTime>
- #include <QDebug>
- #include <QFile>
-+#include <QGuiApplication>
- #include <QProcess>
- #include <QScreen>
- #include <QStandardPaths>
-@@ -30,44 +31,45 @@ constexpr int SCREENSHOT_DELAY = 200;
-
- /* -- Static Helpers --------------------------------------------------------------------------- */
-
--static int readData(int theFile, QByteArray &theDataOut)
-+static QImage allocateImage(const QVariantMap &metadata)
- {
-- // implementation based on QtWayland file qwaylanddataoffer.cpp
-- char lBuffer[4096];
-- int lRetryCount = 0;
-- ssize_t lBytesRead = 0;
--
-- do {
-- // give user 30 sec to click a window, afterwards considered as error
-- while (true) {
-- lBytesRead = QT_READ(theFile, lBuffer, sizeof lBuffer);
-- if (lBytesRead == -1 && (errno == EAGAIN) && ++lRetryCount < 30000) {
-- usleep(1000);
-- } else {
-- break;
-- }
-- }
-+ bool ok;
-
-- if (lBytesRead > 0) {
-- theDataOut.append(lBuffer, lBytesRead);
-- }
-- } while (lBytesRead > 0);
-- return lBytesRead;
-+ const uint width = metadata.value(QStringLiteral("width")).toUInt(&ok);
-+ if (!ok) {
-+ return QImage();
-+ }
-+
-+ const uint height = metadata.value(QStringLiteral("height")).toUInt(&ok);
-+ if (!ok) {
-+ return QImage();
-+ }
-+
-+ const uint format = metadata.value(QStringLiteral("format")).toUInt(&ok);
-+ if (!ok) {
-+ return QImage();
-+ }
-+
-+ return QImage(width, height, QImage::Format(format));
- }
-
--static QImage readImage(int thePipeFd)
-+static QImage readImage(int fileDescriptor, const QVariantMap &metadata)
- {
-- QByteArray lContent;
-- if (readData(thePipeFd, lContent) != 0) {
-- close(thePipeFd);
-+ QFile file;
-+ if (!file.open(fileDescriptor, QFileDevice::ReadOnly, QFileDevice::AutoCloseHandle)) {
-+ close(fileDescriptor);
- return QImage();
- }
-- close(thePipeFd);
-
-- QDataStream lDataStream(lContent);
-- QImage lImage;
-- lDataStream >> lImage;
-- return lImage;
-+ QImage result = allocateImage(metadata);
-+ if (result.isNull()) {
-+ return QImage();
-+ }
-+
-+ QDataStream stream(&file);
-+ stream.readRawData(reinterpret_cast<char *>(result.bits()), result.sizeInBytes());
-+
-+ return result;
- }
-
- PhonePanel::PhonePanel(QObject *parent, const QVariantList &args)
-@@ -75,7 +77,10 @@ PhonePanel::PhonePanel(QObject *parent, const QVariantList &args)
- {
- // setHasConfigurationInterface(true);
- m_kscreenInterface = new org::kde::KScreen(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/kscreen"), QDBusConnection::sessionBus(), this);
-- m_screenshotInterface = new org::kde::kwin::Screenshot(QStringLiteral("org.kde.KWin"), QStringLiteral("/Screenshot"), QDBusConnection::sessionBus(), this);
-+ m_screenshotInterface = new OrgKdeKWinScreenShot2Interface(QStringLiteral("org.kde.KWin.ScreenShot2"),
-+ QStringLiteral("/org/kde/KWin/ScreenShot2"),
-+ QDBusConnection::sessionBus(),
-+ this);
-
- m_localeConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig);
- m_localeConfigWatcher = KConfigWatcher::create(m_localeConfig);
-@@ -142,55 +147,70 @@ void PhonePanel::setAutoRotate(bool value)
- }
- }
-
--void PhonePanel::takeScreenshot()
-+void PhonePanel::handleMetaDataReceived(const QVariantMap &metadata, int fd)
- {
-- QString filePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
-- if (filePath.isEmpty()) {
-- qWarning() << "Couldn't find a writable location for the screenshot!";
-- return;
-- }
-- QDir picturesDir(filePath);
-- if (!picturesDir.mkpath(QStringLiteral("Screenshots"))) {
-- qWarning() << "Couldn't create folder at" << picturesDir.path() + QStringLiteral("/Screenshots") << "to take screenshot.";
-+ const QString type = metadata.value(QStringLiteral("type")).toString();
-+ if (type != QLatin1String("raw")) {
-+ qWarning() << "Unsupported metadata type:" << type;
- return;
- }
-- filePath += QStringLiteral("/Screenshots/Screenshot_%1.png").arg(QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmss")));
-
-+ auto watcher = new QFutureWatcher<QImage>(this);
-+ connect(watcher, &QFutureWatcher<QImage>::finished, this, [watcher]() {
-+ watcher->deleteLater();
-+
-+ QString filePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
-+ if (filePath.isEmpty()) {
-+ qWarning() << "Couldn't find a writable location for the screenshot!";
-+ return;
-+ }
-+ QDir picturesDir(filePath);
-+ if (!picturesDir.mkpath(QStringLiteral("Screenshots"))) {
-+ qWarning() << "Couldn't create folder at" << picturesDir.path() + QStringLiteral("/Screenshots") << "to take screenshot.";
-+ return;
-+ }
-+ filePath += QStringLiteral("/Screenshots/Screenshot_%1.png").arg(QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmss")));
-+ const auto m_result = watcher->result();
-+ if (m_result.isNull() || !m_result.save(filePath)) {
-+ qWarning() << "Screenshot failed";
-+ } else {
-+ KNotification *notif = new KNotification("captured");
-+ notif->setComponentName(QStringLiteral("plasma_phone_components"));
-+ notif->setTitle(i18n("New Screenshot"));
-+ notif->setUrls({filePath});
-+ notif->setText(i18n("New screenshot saved to %1", filePath));
-+ notif->sendEvent();
-+ }
-+ });
-+ watcher->setFuture(QtConcurrent::run(readImage, fd, metadata));
-+}
-+
-+void PhonePanel::takeScreenshot()
-+{
- // wait ~200 ms to wait for rest of animations
- QTimer::singleShot(SCREENSHOT_DELAY, [=]() {
- int lPipeFds[2];
-- if (pipe2(lPipeFds, O_CLOEXEC | O_NONBLOCK) != 0) {
-+ if (pipe2(lPipeFds, O_CLOEXEC) != 0) {
- qWarning() << "Could not take screenshot";
- return;
- }
-- // Take fullscreen screenshot, and no pointer
-- QDBusPendingCall pcall = m_screenshotInterface->screenshotFullscreen(QDBusUnixFileDescriptor(lPipeFds[1]), false, true);
-- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
-- QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [](QDBusPendingCallWatcher *watcher) {
-- if (watcher->isError()) {
-- const auto error = watcher->error();
-- qWarning() << "Error calling KWin DBus interface:" << error.name() << error.message();
-- }
-+
-+ // We don't have access to the ScreenPool so we'll just take the first screen
-+ auto pendingCall = m_screenshotInterface->CaptureScreen(qGuiApp->screens().constFirst()->name(), {}, QDBusUnixFileDescriptor(lPipeFds[1]));
-+ close(lPipeFds[1]);
-+ auto pipeFileDescriptor = lPipeFds[0];
-+
-+ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
-+ connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, watcher, pipeFileDescriptor]() {
- watcher->deleteLater();
-- });
-- const auto lWatcher = new QFutureWatcher<QImage>(this);
-- QObject::connect(lWatcher, &QFutureWatcher<QImage>::finished, this, [lWatcher, filePath]() {
-- lWatcher->deleteLater();
-- const QImage lImage = lWatcher->result();
-- qDebug() << lImage;
-- if (!lImage.save(filePath, "PNG")) {
-- qWarning() << "Failed to save screenshot to" << filePath;
-+ const QDBusPendingReply<QVariantMap> reply = *watcher;
-+
-+ if (reply.isError()) {
-+ qWarning() << "Screenshot request failed:" << reply.error().message();
- } else {
-- KNotification *notif = new KNotification("captured");
-- notif->setComponentName(QStringLiteral("plasma_phone_components"));
-- notif->setTitle(i18n("New Screenshot"));
-- notif->setUrls({filePath});
-- notif->setText(i18n("New screenshot saved to %1", filePath));
-- notif->sendEvent();
-+ handleMetaDataReceived(reply, pipeFileDescriptor);
- }
- });
-- lWatcher->setFuture(QtConcurrent::run(readImage, lPipeFds[0]));
-- close(lPipeFds[1]);
- });
- }
-
-diff --git a/containments/panel/phonepanel.h b/containments/panel/phonepanel.h
-index 59b9351..6e7e04a 100644
---- a/containments/panel/phonepanel.h
-+++ b/containments/panel/phonepanel.h
-@@ -13,7 +13,7 @@
- #include <KSharedConfig>
-
- #include "kscreeninterface.h"
--#include "screenshotinterface.h"
-+#include "screenshot2interface.h"
-
- class PhonePanel : public Plasma::Containment
- {
-@@ -44,13 +44,14 @@ signals:
- void isSystem24HourFormatChanged();
-
- private:
-+ void handleMetaDataReceived(const QVariantMap &metadata, int fd);
- bool m_running = false;
-
- KConfigWatcher::Ptr m_localeConfigWatcher;
- KSharedConfig::Ptr m_localeConfig;
-
- org::kde::KScreen *m_kscreenInterface;
-- org::kde::kwin::Screenshot *m_screenshotInterface;
-+ OrgKdeKWinScreenShot2Interface *m_screenshotInterface;
- };
-
- #endif