effects/screenshot: Introduce CaptureWorkspace

Most screenshot tools provide some way to capture the entire workspace.
Currently, the way to achieve that is to compute the workspace geometry
yourself and use CaptureArea. It's inconvenient and it's also racy.

This change introduces CaptureWorkspace to provide screenshot tools
slightly nicer API to capture the entire workspace.
This commit is contained in:
Vlad Zahorodnii 2023-03-03 19:53:59 +02:00
parent db55a6f909
commit fdbfd2fd5a
3 changed files with 62 additions and 1 deletions

View file

@ -269,5 +269,45 @@
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" />
<arg name="results" type="a{sv}" direction="out" />
</method>
<!--
CaptureWorkspace:
@options: Optional vardict with screenshot options
@pipe: The pipe file descriptor where the screenshot will be written
Take a screenshot of the workspace, i.e. all screens united. 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.
Supported since version 3.
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="CaptureWorkspace">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" 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>

View file

@ -290,7 +290,7 @@ ScreenShotDBusInterface2::~ScreenShotDBusInterface2()
int ScreenShotDBusInterface2::version() const
{
return 2;
return 3;
}
bool ScreenShotDBusInterface2::checkPermissions() const
@ -514,6 +514,25 @@ QVariantMap ScreenShotDBusInterface2::CaptureInteractive(uint kind,
return QVariantMap();
}
QVariantMap ScreenShotDBusInterface2::CaptureWorkspace(const QVariantMap &options, QDBusUnixFileDescriptor pipe)
{
if (!checkPermissions()) {
return QVariantMap();
}
const int fileDescriptor = dup(pipe.fileDescriptor());
if (fileDescriptor == -1) {
sendErrorReply(s_errorFileDescriptor, s_errorFileDescriptorMessage);
return QVariantMap();
}
takeScreenShot(effects->virtualScreenGeometry(), screenShotFlagsFromOptions(options),
new ScreenShotSinkPipe2(fileDescriptor, message()));
setDelayedReply(true);
return QVariantMap();
}
void ScreenShotDBusInterface2::bind(ScreenShotSinkPipe2 *sink, ScreenShotSource2 *source)
{
connect(source, &ScreenShotSource2::cancelled, sink, [sink, source]() {

View file

@ -53,6 +53,8 @@ public Q_SLOTS:
QDBusUnixFileDescriptor pipe);
QVariantMap CaptureInteractive(uint kind, const QVariantMap &options,
QDBusUnixFileDescriptor pipe);
QVariantMap CaptureWorkspace(const QVariantMap &options,
QDBusUnixFileDescriptor pipe);
private:
void takeScreenShot(EffectScreen *screen, ScreenShotFlags flags, ScreenShotSinkPipe2 *sink);