Changeset View
Changeset View
Standalone View
Standalone View
src/BackendPlugins/WaylandKWinScreenshotPlugin.cpp
- This file was moved from src/Platforms/PlatformKWinWayland.cpp.
1 | /* This file is part of Spectacle, the KDE screenshot utility | 1 | /* This file is part of Spectacle, the KDE screenshot utility | ||
---|---|---|---|---|---|
2 | * Copyright (C) 2016 Martin Graesslin <mgraesslin@kde.org> | 2 | * Copyright (C) 2019 Leon De Andrade <leondeandrade@hotmail.com> | ||
3 | * | 3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Lesser General Public License as published by | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | 7 | * (at your option) any later version. | ||
8 | * | 8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. | ||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public License | 14 | * You should have received a copy of the GNU Lesser General Public License | ||
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | * Boston, MA 02110-1301, USA. | 17 | * Boston, MA 02110-1301, USA. | ||
18 | * | 18 | * | ||
19 | * SPDX-License-Identifier: LGPL-2.0-or-later | 19 | * SPDX-License-Identifier: LGPL-2.0-or-later | ||
20 | */ | 20 | */ | ||
21 | 21 | | |||
22 | #include "PlatformKWinWayland.h" | 22 | | ||
23 | #include "WaylandKWinScreenshotPlugin.h" | ||||
23 | 24 | | |||
24 | #include <qplatformdefs.h> | 25 | #include <qplatformdefs.h> | ||
25 | #include <QtConcurrent> | 26 | #include <QtConcurrent> | ||
26 | #include <QApplication> | 27 | #include <QApplication> | ||
27 | #include <QImage> | 28 | #include <QImage> | ||
28 | #include <QPixmap> | 29 | #include <QPixmap> | ||
30 | #include <QDBusConnection> | ||||
31 | #include <QDBusConnectionInterface> | ||||
29 | #include <QDBusInterface> | 32 | #include <QDBusInterface> | ||
30 | #include <QDBusUnixFileDescriptor> | 33 | #include <QDBusUnixFileDescriptor> | ||
31 | #include <QDBusPendingCall> | 34 | #include <QDBusPendingCall> | ||
32 | #include <QFutureWatcher> | 35 | #include <QFutureWatcher> | ||
33 | 36 | | |||
34 | /* -- Static Helpers --------------------------------------------------------------------------- */ | 37 | /* -- Static Helpers --------------------------------------------------------------------------- */ | ||
35 | 38 | | |||
36 | static int readData(int theFile, QByteArray &theDataOut) | 39 | static int readData(int theFile, QByteArray &theDataOut) | ||
Show All 29 Lines | 63 | { | |||
66 | close(thePipeFd); | 69 | close(thePipeFd); | ||
67 | 70 | | |||
68 | QDataStream lDataStream(lContent); | 71 | QDataStream lDataStream(lContent); | ||
69 | QImage lImage; | 72 | QImage lImage; | ||
70 | lDataStream >> lImage; | 73 | lDataStream >> lImage; | ||
71 | return lImage; | 74 | return lImage; | ||
72 | } | 75 | } | ||
73 | 76 | | |||
74 | /* -- General Plumbing ------------------------------------------------------------------------- */ | | |||
75 | 77 | | |||
76 | PlatformKWinWayland::PlatformKWinWayland(QObject *parent) : | 78 | /* -- WaylandKWinScreenshotPlugin ------------------------------------------------------------------------- */ | ||
77 | Platform(parent) | 79 | | ||
78 | {} | 80 | WaylandKWinScreenshotPlugin::WaylandKWinScreenshotPlugin(QObject *parent) : ScreenshotInterface {parent} {} | ||
79 | 81 | | |||
80 | QString PlatformKWinWayland::platformName() const | 82 | | ||
83 | QString WaylandKWinScreenshotPlugin::name() const | ||||
81 | { | 84 | { | ||
82 | return QStringLiteral("KWinWayland"); | 85 | return QStringLiteral("Wayland Screenshot Backend"); | ||
83 | } | 86 | } | ||
84 | 87 | | |||
85 | Platform::GrabModes PlatformKWinWayland::supportedGrabModes() const | 88 | Platform WaylandKWinScreenshotPlugin::platform() const { | ||
86 | { | 89 | return Platform::Wayland; | ||
87 | Platform::GrabModes lSupportedModes({ GrabMode::AllScreens, GrabMode::WindowUnderCursor }); | | |||
88 | if (QApplication::screens().count() > 1) { | | |||
89 | lSupportedModes |= Platform::GrabMode::CurrentScreen; | | |||
90 | } | 90 | } | ||
91 | return lSupportedModes; | 91 | | ||
92 | CaptureModes WaylandKWinScreenshotPlugin::supportedCaptureModes() const | ||||
93 | { | ||||
94 | return CaptureModes({ CaptureMode::AllScreens, CaptureMode::CurrentScreen, CaptureMode::WindowUnderCursor, CaptureMode::RectangularRegion }); | ||||
92 | } | 95 | } | ||
93 | 96 | | |||
94 | Platform::ShutterModes PlatformKWinWayland::supportedShutterModes() const | 97 | ShutterModes WaylandKWinScreenshotPlugin::supportedShutterModes() const | ||
95 | { | 98 | { | ||
96 | return { ShutterMode::OnClick }; | 99 | return { ShutterMode::OnClick }; | ||
97 | } | 100 | } | ||
98 | 101 | | |||
99 | void PlatformKWinWayland::doGrab(ShutterMode theShutterMode, GrabMode theGrabMode, bool theIncludePointer, bool theIncludeDecorations) | 102 | bool WaylandKWinScreenshotPlugin::requirementsComplied() const | ||
103 | { | ||||
104 | return true; | ||||
105 | } | ||||
106 | | ||||
107 | void WaylandKWinScreenshotPlugin::doGrab(ShutterMode theShutterMode, CaptureMode theCaptureMode, bool theIncludePointer, bool theIncludeDecorations) | ||||
100 | { | 108 | { | ||
101 | if (theShutterMode != ShutterMode::OnClick) { | 109 | if (theShutterMode != ShutterMode::OnClick) { | ||
102 | emit newScreenshotFailed(); | 110 | emit newScreenshotFailed(); | ||
103 | return; | 111 | return; | ||
104 | } | 112 | } | ||
105 | 113 | | |||
106 | switch(theGrabMode) { | 114 | switch(theCaptureMode) { | ||
107 | case GrabMode::AllScreens: | 115 | case CaptureMode::AllScreens: | ||
108 | return doGrabHelper(QStringLiteral("screenshotFullscreen"), theIncludePointer); | 116 | case CaptureMode::RectangularRegion: | ||
109 | case GrabMode::CurrentScreen: | 117 | doGrabHelper(QStringLiteral("screenshotFullscreen"), theIncludePointer); | ||
110 | return doGrabHelper(QStringLiteral("screenshotScreen"), theIncludePointer); | 118 | break; | ||
111 | case GrabMode::WindowUnderCursor: { | 119 | case CaptureMode::CurrentScreen: | ||
120 | doGrabHelper(QStringLiteral("screenshotScreen"), theIncludePointer); | ||||
121 | break; | ||||
122 | case CaptureMode::WindowUnderCursor: { | ||||
112 | int lOpMask = theIncludeDecorations ? 1 : 0; | 123 | int lOpMask = theIncludeDecorations ? 1 : 0; | ||
113 | if (theIncludePointer) { | 124 | if (theIncludePointer) { | ||
114 | lOpMask |= 1 << 1; | 125 | lOpMask |= 1 << 1; | ||
115 | } | 126 | } | ||
116 | return doGrabHelper(QStringLiteral("interactive"), lOpMask); | 127 | doGrabHelper(QStringLiteral("interactive"), lOpMask); | ||
128 | break; | ||||
117 | } | 129 | } | ||
118 | case GrabMode::InvalidChoice: | 130 | default: | ||
119 | case GrabMode::ActiveWindow: | | |||
120 | case GrabMode::TransientWithParent: | | |||
121 | emit newScreenshotFailed(); | 131 | emit newScreenshotFailed(); | ||
122 | return; | | |||
123 | } | 132 | } | ||
124 | } | 133 | } | ||
125 | 134 | | |||
126 | /* -- Grab Helpers ----------------------------------------------------------------------------- */ | 135 | void WaylandKWinScreenshotPlugin::startReadImage(int theReadPipe) | ||
127 | | ||||
128 | void PlatformKWinWayland::startReadImage(int theReadPipe) | | |||
129 | { | 136 | { | ||
130 | auto lWatcher = new QFutureWatcher<QImage>(this); | 137 | auto lWatcher = new QFutureWatcher<QImage>(this); | ||
131 | QObject::connect(lWatcher, &QFutureWatcher<QImage>::finished, this, | 138 | QObject::connect(lWatcher, &QFutureWatcher<QImage>::finished, this, | ||
132 | [lWatcher, this] () { | 139 | [lWatcher, this] () { | ||
133 | lWatcher->deleteLater(); | 140 | lWatcher->deleteLater(); | ||
134 | const QImage lImage = lWatcher->result(); | 141 | const QImage lImage = lWatcher->result(); | ||
135 | emit newScreenshotTaken(QPixmap::fromImage(lImage)); | 142 | emit newScreenshotTaken(QPixmap::fromImage(lImage)); | ||
136 | } | 143 | } | ||
137 | ); | 144 | ); | ||
138 | lWatcher->setFuture(QtConcurrent::run(readImage, theReadPipe)); | 145 | lWatcher->setFuture(QtConcurrent::run(readImage, theReadPipe)); | ||
139 | } | 146 | } | ||
140 | 147 | | |||
141 | template <typename ArgType> | 148 | template <typename ArgType> | ||
142 | void PlatformKWinWayland::callDBus(const QString &theGrabMethod, ArgType theArgument, int theWriteFile) | 149 | void WaylandKWinScreenshotPlugin::doGrabHelper(const QString &theGrabMethod, ArgType theArgument) | ||
143 | { | | |||
144 | QDBusInterface lInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Screenshot"), QStringLiteral("org.kde.kwin.Screenshot")); | | |||
145 | lInterface.asyncCall(theGrabMethod, QVariant::fromValue(QDBusUnixFileDescriptor(theWriteFile)), theArgument); | | |||
146 | } | | |||
147 | | ||||
148 | template <typename ArgType> | | |||
149 | void PlatformKWinWayland::doGrabHelper(const QString &theGrabMethod, ArgType theArgument) | | |||
150 | { | 150 | { | ||
151 | int lPipeFds[2]; | 151 | int lPipeFds[2]; | ||
152 | if (pipe2(lPipeFds, O_CLOEXEC|O_NONBLOCK) != 0) { | 152 | if (pipe2(lPipeFds, O_CLOEXEC|O_NONBLOCK) != 0) { | ||
153 | emit newScreenshotFailed(); | 153 | emit newScreenshotFailed(); | ||
154 | return; | 154 | return; | ||
155 | } | 155 | } | ||
156 | 156 | | |||
157 | callDBus(theGrabMethod, theArgument, lPipeFds[1]); | 157 | callDBus(theGrabMethod, theArgument, lPipeFds[1]); | ||
158 | startReadImage(lPipeFds[0]); | 158 | startReadImage(lPipeFds[0]); | ||
159 | 159 | | |||
160 | close(lPipeFds[1]); | 160 | close(lPipeFds[1]); | ||
161 | } | 161 | } | ||
162 | | ||||
163 | template <typename ArgType> | ||||
164 | void WaylandKWinScreenshotPlugin::callDBus(const QString &theGrabMethod, ArgType theArgument, int theWriteFile) | ||||
165 | { | ||||
166 | QDBusInterface lInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Screenshot"), QStringLiteral("org.kde.kwin.Screenshot")); | ||||
167 | lInterface.asyncCall(theGrabMethod, QVariant::fromValue(QDBusUnixFileDescriptor(theWriteFile)), theArgument); | ||||
168 | } | ||||
169 | | ||||
170 | #include "moc_WaylandKWinScreenshotPlugin.cpp" | ||||
171 | No newline at end of file |