kwin/src/effects/screenshot/screenshot.cpp

495 lines
16 KiB
C++
Raw Normal View History

2020-08-02 22:22:19 +00:00
/*
KWin - the KDE window manager
This file is part of the KDE project.
2020-08-02 22:22:19 +00:00
SPDX-FileCopyrightText: 2010 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2010 Nokia Corporation and /or its subsidiary(-ies)
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
2020-08-02 22:22:19 +00:00
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "screenshot.h"
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
#include "screenshotdbusinterface1.h"
#include <kwinglplatform.h>
#include <kwinglutils.h>
#include <kwinxrenderutils.h>
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
#include <QPainter>
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
#include <xcb/xcb_image.h>
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
namespace KWin
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
struct ScreenShotWindowData
{
QFutureInterface<QImage> promise;
ScreenShotFlags flags;
EffectWindow *window = nullptr;
};
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
struct ScreenShotAreaData
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QFutureInterface<QImage> promise;
ScreenShotFlags flags;
QRect area;
QImage result;
QList<EffectScreen *> screens;
};
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
struct ScreenShotScreenData
2011-01-30 14:34:42 +00:00
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QFutureInterface<QImage> promise;
ScreenShotFlags flags;
EffectScreen *screen = nullptr;
};
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
static void convertFromGLImage(QImage &img, int w, int h)
2011-01-30 14:34:42 +00:00
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
// from QtOpenGL/qgl.cpp
// SPDX-FileCopyrightText: 2010 Nokia Corporation and /or its subsidiary(-ies)
// see https://github.com/qt/qtbase/blob/dev/src/opengl/qgl.cpp
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
// OpenGL gives RGBA; Qt wants ARGB
uint *p = reinterpret_cast<uint *>(img.bits());
uint *end = p + w * h;
while (p < end) {
uint a = *p << 24;
*p = (*p >> 8) | a;
p++;
}
} else {
// OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
for (int y = 0; y < h; y++) {
uint *q = reinterpret_cast<uint *>(img.scanLine(y));
for (int x = 0; x < w; ++x) {
const uint pixel = *q;
*q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff)
| (pixel & 0xff00ff00);
q++;
}
}
}
img = img.mirrored();
2011-01-30 14:34:42 +00:00
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
static void xImageCleanup(void *data)
2011-01-30 14:34:42 +00:00
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
xcb_image_destroy(static_cast<xcb_image_t *>(data));
2011-01-30 14:34:42 +00:00
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
static QImage xPictureToImage(xcb_render_picture_t srcPic, const QRect &geometry)
{
xcb_connection_t *c = effects->xcbConnection();
xcb_pixmap_t xpix = xcb_generate_id(c);
xcb_create_pixmap(c, 32, xpix, effects->x11RootWindow(), geometry.width(), geometry.height());
XRenderPicture pic(xpix, 32);
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, srcPic, XCB_RENDER_PICTURE_NONE, pic,
geometry.x(), geometry.y(), 0, 0, 0, 0, geometry.width(), geometry.height());
xcb_flush(c);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
xcb_image_t *xImage = xcb_image_get(c, xpix, 0, 0, geometry.width(), geometry.height(),
~0, XCB_IMAGE_FORMAT_Z_PIXMAP);
QImage img(xImage->data, xImage->width, xImage->height, xImage->stride,
QImage::Format_ARGB32_Premultiplied, xImageCleanup, xImage);
// TODO: byte order might need swapping
xcb_free_pixmap(c, xpix);
return img.copy();
}
#endif
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
bool ScreenShotEffect::supported()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
return effects->compositingType() == XRenderCompositing ||
(effects->isOpenGLCompositing() && GLRenderTarget::supported());
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
ScreenShotEffect::ScreenShotEffect()
: m_dbusInterface1(new ScreenShotDBusInterface1(this))
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
connect(effects, &EffectsHandler::screenAdded, this, &ScreenShotEffect::handleScreenAdded);
connect(effects, &EffectsHandler::screenRemoved, this, &ScreenShotEffect::handleScreenRemoved);
connect(effects, &EffectsHandler::windowClosed, this, &ScreenShotEffect::handleWindowClosed);
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
ScreenShotEffect::~ScreenShotEffect()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
cancelWindowScreenShots();
cancelAreaScreenShots();
cancelScreenScreenShots();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QFuture<QImage> ScreenShotEffect::scheduleScreenShot(EffectScreen *screen, ScreenShotFlags flags)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
for (ScreenShotScreenData &data : m_screenScreenShots) {
if (data.screen == screen && data.flags == flags) {
return data.promise.future();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
ScreenShotScreenData data;
data.screen = screen;
data.flags = flags;
m_screenScreenShots.append(data);
effects->addRepaint(screen->geometry());
data.promise.reportStarted();
return data.promise.future();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QFuture<QImage> ScreenShotEffect::scheduleScreenShot(const QRect &area, ScreenShotFlags flags)
2011-01-30 14:34:42 +00:00
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
for (ScreenShotAreaData &data : m_areaScreenShots) {
if (data.area == area && data.flags == flags) {
return data.promise.future();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
ScreenShotAreaData data;
data.area = area;
data.flags = flags;
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
const QList<EffectScreen *> screens = effects->screens();
for (EffectScreen *screen : screens) {
if (screen->geometry().intersects(area)) {
data.screens.append(screen);
2011-01-30 14:34:42 +00:00
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
qreal devicePixelRatio = 1.0;
if (flags & ScreenShotNativeResolution) {
for (const EffectScreen *screen : qAsConst(data.screens)) {
if (screen->devicePixelRatio() > devicePixelRatio) {
devicePixelRatio = screen->devicePixelRatio();
}
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
data.result = QImage(area.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
data.result.fill(Qt::transparent);
data.result.setDevicePixelRatio(devicePixelRatio);
m_areaScreenShots.append(data);
effects->addRepaint(area);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
data.promise.reportStarted();
return data.promise.future();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QFuture<QImage> ScreenShotEffect::scheduleScreenShot(EffectWindow *window, ScreenShotFlags flags)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
for (ScreenShotWindowData &data : m_windowScreenShots) {
if (data.window == window && data.flags == flags) {
return data.promise.future();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
ScreenShotWindowData data;
data.window = window;
data.flags = flags;
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
m_windowScreenShots.append(data);
window->addRepaintFull();
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
data.promise.reportStarted();
return data.promise.future();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::cancelWindowScreenShots()
2011-01-30 14:34:42 +00:00
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
while (!m_windowScreenShots.isEmpty()) {
ScreenShotWindowData screenshot = m_windowScreenShots.takeLast();
screenshot.promise.reportCanceled();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::cancelAreaScreenShots()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
while (!m_areaScreenShots.isEmpty()) {
ScreenShotAreaData screenshot = m_areaScreenShots.takeLast();
screenshot.promise.reportCanceled();
}
2011-01-30 14:34:42 +00:00
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::cancelScreenScreenShots()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
while (!m_screenScreenShots.isEmpty()) {
ScreenShotScreenData screenshot = m_screenScreenShots.takeLast();
screenshot.promise.reportCanceled();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &data)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
m_paintedScreen = data.screen();
effects->paintScreen(mask, region, data);
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::takeScreenShot(ScreenShotWindowData *screenshot)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
EffectWindow *window = screenshot->window;
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
WindowPaintData d(window);
double left = 0;
double top = 0;
double right = window->width();
double bottom = window->height();
if (window->hasDecoration() && (screenshot->flags & ScreenShotIncludeDecoration)) {
for (const WindowQuad &quad : qAsConst(d.quads)) {
// we need this loop to include the decoration padding
left = qMin(left, quad.left());
top = qMin(top, quad.top());
right = qMax(right, quad.right());
bottom = qMax(bottom, quad.bottom());
}
} else if (window->hasDecoration()) {
WindowQuadList newQuads;
left = window->width();
top = window->height();
right = 0;
bottom = 0;
for (const WindowQuad &quad : qAsConst(d.quads)) {
if (quad.type() == WindowQuadContents) {
newQuads << quad;
left = qMin(left, quad.left());
top = qMin(top, quad.top());
right = qMax(right, quad.right());
bottom = qMax(bottom, quad.bottom());
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
}
d.quads = newQuads;
}
const int width = right - left;
const int height = bottom - top;
bool validTarget = true;
QScopedPointer<GLTexture> offscreenTexture;
QScopedPointer<GLRenderTarget> target;
if (effects->isOpenGLCompositing()) {
offscreenTexture.reset(new GLTexture(GL_RGBA8, width, height));
offscreenTexture->setFilter(GL_LINEAR);
offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE);
target.reset(new GLRenderTarget(*offscreenTexture));
validTarget = target->valid();
}
if (validTarget) {
d.setXTranslation(-window->x() - left);
d.setYTranslation(-window->y() - top);
// render window into offscreen texture
int mask = PAINT_WINDOW_TRANSFORMED | PAINT_WINDOW_TRANSLUCENT;
QImage img;
if (effects->isOpenGLCompositing()) {
GLRenderTarget::pushRenderTarget(target.data());
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QMatrix4x4 projection;
projection.ortho(QRect(0, 0, offscreenTexture->width(), offscreenTexture->height()));
d.setProjectionMatrix(projection);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
effects->drawWindow(window, mask, infiniteRegion(), d);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
// copy content from framebuffer into image
img = QImage(QSize(width, height), QImage::Format_ARGB32);
glReadnPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, img.sizeInBytes(), (GLvoid*)img.bits());
GLRenderTarget::popRenderTarget();
convertFromGLImage(img, width, height);
}
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (effects->compositingType() == XRenderCompositing) {
setXRenderOffscreen(true);
effects->drawWindow(window, mask, QRegion(0, 0, width, height), d);
if (xRenderOffscreenTarget()) {
img = xPictureToImage(xRenderOffscreenTarget(), QRect(0, 0, width, height));
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
setXRenderOffscreen(false);
}
#endif
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
if (screenshot->flags & ScreenShotIncludeCursor) {
grabPointerImage(img, window->x() + left, window->y() + top);
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
screenshot->promise.reportResult(img);
screenshot->promise.reportFinished();
} else {
screenshot->promise.reportCanceled();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
bool ScreenShotEffect::takeScreenShot(ScreenShotAreaData *screenshot)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
if (!m_paintedScreen) {
// On X11, all screens are painted simultaneously and there is no native HiDPI support.
QImage snapshot = blitScreenshot(screenshot->area);
if (screenshot->flags & ScreenShotIncludeCursor) {
grabPointerImage(snapshot, screenshot->area.x(), screenshot->area.y());
}
screenshot->promise.reportResult(snapshot);
screenshot->promise.reportFinished();
} else {
if (!screenshot->screens.contains(m_paintedScreen)) {
return false;
}
screenshot->screens.removeOne(m_paintedScreen);
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
const QRect sourceRect = screenshot->area & m_paintedScreen->geometry();
qreal sourceDevicePixelRatio = 1.0;
if (screenshot->flags & ScreenShotNativeResolution) {
sourceDevicePixelRatio = m_paintedScreen->devicePixelRatio();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
const QImage snapshot = blitScreenshot(sourceRect, sourceDevicePixelRatio);
const QRect nativeArea(screenshot->area.topLeft(),
screenshot->area.size() * screenshot->result.devicePixelRatio());
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QPainter painter(&screenshot->result);
painter.setWindow(nativeArea);
painter.drawImage(sourceRect, snapshot);
painter.end();
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
if (screenshot->screens.isEmpty()) {
if (screenshot->flags & ScreenShotIncludeCursor) {
grabPointerImage(screenshot->result, screenshot->area.x(), screenshot->area.y());
}
screenshot->promise.reportResult(screenshot->result);
screenshot->promise.reportFinished();
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
return screenshot->promise.isFinished();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
bool ScreenShotEffect::takeScreenShot(ScreenShotScreenData *screenshot)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
if (!m_paintedScreen || screenshot->screen == m_paintedScreen) {
qreal devicePixelRatio = 1.0;
if (screenshot->flags & ScreenShotNativeResolution) {
devicePixelRatio = screenshot->screen->devicePixelRatio();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
QImage snapshot = blitScreenshot(screenshot->screen->geometry(), devicePixelRatio);
if (screenshot->flags & ScreenShotIncludeCursor) {
const int xOffset = screenshot->screen->geometry().width();
const int yOffset = screenshot->screen->geometry().height();
grabPointerImage(snapshot, xOffset, yOffset);
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
screenshot->promise.reportResult(snapshot);
screenshot->promise.reportFinished();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
return screenshot->promise.isFinished();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::postPaintScreen()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
effects->postPaintScreen();
while (!m_windowScreenShots.isEmpty()) {
ScreenShotWindowData screenshot = m_windowScreenShots.takeLast();
takeScreenShot(&screenshot);
}
for (int i = m_areaScreenShots.count() - 1; i >= 0; --i) {
if (takeScreenShot(&m_areaScreenShots[i])) {
m_areaScreenShots.removeAt(i);
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
for (int i = m_screenScreenShots.count() - 1; i >= 0; --i) {
if (takeScreenShot(&m_screenScreenShots[i])) {
m_screenScreenShots.removeAt(i);
}
}
}
QImage ScreenShotEffect::blitScreenshot(const QRect &geometry, const qreal scale)
{
QImage img;
if (effects->isOpenGLCompositing())
{
const QSize nativeSize = geometry.size() * scale;
if (GLRenderTarget::blitSupported() && !GLPlatform::instance()->isGLES()) {
img = QImage(nativeSize.width(), nativeSize.height(), QImage::Format_ARGB32);
GLTexture tex(GL_RGBA8, nativeSize.width(), nativeSize.height());
GLRenderTarget target(tex);
target.blitFromFramebuffer(geometry);
// copy content from framebuffer into image
tex.bind();
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, static_cast<GLvoid*>(img.bits()));
tex.unbind();
} else {
img = QImage(nativeSize.width(), nativeSize.height(), QImage::Format_ARGB32);
glReadPixels(0, 0, nativeSize.width(), nativeSize.height(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)img.bits());
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
convertFromGLImage(img, nativeSize.width(), nativeSize.height());
}
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (effects->compositingType() == XRenderCompositing) {
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
img = xPictureToImage(effects->xrenderBufferPicture(), geometry);
}
#endif
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
img.setDevicePixelRatio(scale);
return img;
}
2011-01-30 14:34:42 +00:00
void ScreenShotEffect::grabPointerImage(QImage& snapshot, int offsetx, int offsety)
{
const auto cursor = effects->cursorImage();
if (cursor.image().isNull())
2011-01-30 14:34:42 +00:00
return;
QPainter painter(&snapshot);
painter.drawImage(effects->cursorPos() - cursor.hotSpot() - QPoint(offsetx, offsety), cursor.image());
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
bool ScreenShotEffect::isActive() const
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
return (!m_windowScreenShots.isEmpty() || !m_areaScreenShots.isEmpty() || !m_screenScreenShots.isEmpty())
&& !effects->isScreenLocked();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
int ScreenShotEffect::requestedEffectChainPosition() const
{
return 50;
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::handleScreenAdded()
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
cancelAreaScreenShots();
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::handleScreenRemoved(EffectScreen *screen)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
cancelAreaScreenShots();
for (int i = m_screenScreenShots.count() - 1; i >= 0; --i) {
if (m_screenScreenShots[i].screen == screen) {
m_screenScreenShots[i].promise.reportCanceled();
m_screenScreenShots.removeAt(i);
}
}
}
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
void ScreenShotEffect::handleWindowClosed(EffectWindow *window)
{
effects/screenshot: Prepare for versioned dbus interface On Wayland, when the compositor sends a screenshot to the requesting app, it encodes the screenshot as a PNG image and sends the encoded data over the pipe. The requesting app (Spectacle) then needs to decode the data. The issue is that encoding PNG images is not cheap. This is the main reason why Spectacle is shown with a huge delay after you press the PrtScr key. In order to fix the latency issue, we need to transfer raw image data. Unfortunately, the current dbus api of the screenshot is too cluttered and the best option at the moment is to start with a clean slate. This change prepares the screenshot effect for versioned dbus interface. Most of existing dbus logic was moved out in a separate class. In order to schedule screen shots, the screenshot effect got some new API. QFuture<QImage> scheduleScreenShot(window, flags) QFuture<QImage> scheduleScreenShot(area, flags) QFuture<QImage> scheduleScreenShot(screen, flags) If a dbus interface needs to take a screenshot, it needs to call one of the overloaded scheduleScreenShot() functions. Every overload returns a QFuture object that can be used for querying the result. This change also introduces "sink" and "source" objects in the dbus api implementation to simplify handling of QFuture objects. Note that the QFutureInterface is undocumented, so if you use it, you do it on your own risk. However, since Qt 5.15 is frozen for non-commercial use and some other Plasma projects already use QFutureInterface, this is not a big concern. For what it's worth, in Qt 6, there's the QPromise class, which is equivalent to the QFutureInterface class. CCBUG: 433776 CCBUG: 430869
2021-03-01 11:58:57 +00:00
for (int i = m_windowScreenShots.count() - 1; i >= 0; --i) {
if (m_windowScreenShots[i].window == window) {
m_windowScreenShots[i].promise.reportCanceled();
m_windowScreenShots.removeAt(i);
}
}
}
} // namespace