KWin
Loading...
Searching...
No Matches
colorpicker.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "colorpicker.h"
10#include "core/rendertarget.h"
11#include "core/renderviewport.h"
13#include "opengl/glutils.h"
15#include <KLocalizedString>
16#include <QDBusConnection>
17#include <QDBusMetaType>
18
20
21QDBusArgument &operator<<(QDBusArgument &argument, const QColor &color)
22{
23 argument.beginStructure();
24 argument << color.rgba();
25 argument.endStructure();
26 return argument;
27}
28
29const QDBusArgument &operator>>(const QDBusArgument &argument, QColor &color)
30{
31 argument.beginStructure();
32 QRgb rgba;
33 argument >> rgba;
34 argument.endStructure();
35 color = QColor::fromRgba(rgba);
36 return argument;
37}
38
39namespace KWin
40{
41
46
48 : m_scheduledPosition(QPoint(-1, -1))
49{
50 qDBusRegisterMetaType<QColor>();
51 QDBusConnection::sessionBus().registerObject(QStringLiteral("/ColorPicker"), this, QDBusConnection::ExportScriptableContents);
52}
53
55
56void ColorPickerEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
57{
58 effects->paintScreen(renderTarget, viewport, mask, region, screen);
59
60 const QRectF geo = viewport.renderRect();
61 if (m_scheduledPosition != QPoint(-1, -1) && exclusiveContains(geo, m_scheduledPosition)) {
62 std::array<float, 4> data;
63 constexpr GLsizei PIXEL_SIZE = 1;
64 const QPoint texturePosition = viewport.mapToRenderTarget(m_scheduledPosition).toPoint();
65
66 glReadPixels(texturePosition.x(), renderTarget.size().height() - texturePosition.y() - PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE, GL_RGBA, GL_FLOAT, data.data());
67 QVector3D sRGB = 255 * renderTarget.colorDescription().mapTo(QVector3D(data[0], data[1], data[2]), ColorDescription::sRGB);
68 QDBusConnection::sessionBus().send(m_replyMessage.createReply(QColor(sRGB.x(), sRGB.y(), sRGB.z())));
69 m_picking = false;
70 m_scheduledPosition = QPoint(-1, -1);
71 }
72}
73
75{
76 if (!calledFromDBus()) {
77 return QColor();
78 }
79 if (m_picking) {
80 sendErrorReply(QDBusError::Failed, "Color picking is already in progress");
81 return QColor();
82 }
83 m_picking = true;
84 m_replyMessage = message();
85 setDelayedReply(true);
86 showInfoMessage();
88 [this](const QPointF &p) {
89 hideInfoMessage();
90 if (p == QPointF(-1, -1)) {
91 // error condition
92 QDBusConnection::sessionBus().send(m_replyMessage.createErrorReply(QStringLiteral("org.kde.kwin.ColorPicker.Error.Cancelled"), "Color picking got cancelled"));
93 m_picking = false;
94 } else {
95 m_scheduledPosition = p;
97 }
98 });
99 return QColor();
100}
101
102void ColorPickerEffect::showInfoMessage()
103{
104 effects->showOnScreenMessage(i18n("Select a position for color picking with left click or enter.\nEscape or right click to cancel."), QStringLiteral("color-picker"));
105}
106
107void ColorPickerEffect::hideInfoMessage()
108{
110}
111
113{
114 return m_picking && ((m_scheduledPosition != QPoint(-1, -1))) && !effects->isScreenLocked();
115}
116
117} // namespace
118
119#include "moc_colorpicker.cpp"
static const ColorDescription sRGB
Definition colorspace.h:132
QVector3D mapTo(QVector3D rgb, const ColorDescription &other) const
Q_SCRIPTABLE QColor pick()
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen) override
~ColorPickerEffect() override
bool isActive() const override
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
void startInteractivePositionSelection(std::function< void(const QPointF &)> callback)
void showOnScreenMessage(const QString &message, const QString &iconName=QString())
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
void hideOnScreenMessage(OnScreenMessageHideFlags flags=OnScreenMessageHideFlags())
Q_SCRIPTABLE void addRepaintFull()
QSize size() const
const ColorDescription & colorDescription() const
QRectF renderRect() const
QRectF mapToRenderTarget(const QRectF &logicalGeometry) const
const QDBusArgument & operator>>(const QDBusArgument &argument, QColor &color)
Q_DECLARE_METATYPE(KWin::SwitchEvent::State)
EffectsHandler * effects