summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Gräßlin <[email protected]>2016-11-24 08:05:27 +0100
committerMartin Gräßlin <[email protected]>2016-11-25 09:31:21 +0100
commit1bca39d22941e1e40799ff8bf0d8654a3b935db5 (patch)
treea433131cb48e040ef42637ca6b2f84cffb8f8a09
parentbd319ece70bea676580e72874855ce5007c77813 (diff)
[applets] Support KWin/Wayland in ColorPicker
Summary: KWin provides a DBus interface for interactive color picking. This allows to have a color picker on Wayland. To use this the GrabWidget is refactored and an abstract Grabber class is split out. The current functionality using an (X11) window is moved into an X11Grabber class and a new class KWinWaylandGrabber is added which performs the interaction through DBus. Reviewers: #plasma, broulik Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D3481
-rw-r--r--applets/colorpicker/CMakeLists.txt2
-rw-r--r--applets/colorpicker/plugin/grabwidget.cpp124
-rw-r--r--applets/colorpicker/plugin/grabwidget.h56
3 files changed, 159 insertions, 23 deletions
diff --git a/applets/colorpicker/CMakeLists.txt b/applets/colorpicker/CMakeLists.txt
index 80b9d61..67dc749 100644
--- a/applets/colorpicker/CMakeLists.txt
+++ b/applets/colorpicker/CMakeLists.txt
@@ -10,5 +10,5 @@ set(colorpickerplugin_SRCS
install(FILES plugin/qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/colorpicker)
add_library(colorpickerplugin SHARED ${colorpickerplugin_SRCS})
-target_link_libraries(colorpickerplugin Qt5::Gui Qt5::Qml Qt5::Widgets)
+target_link_libraries(colorpickerplugin Qt5::DBus Qt5::Gui Qt5::Qml Qt5::Widgets KF5::WindowSystem)
install(TARGETS colorpickerplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/colorpicker)
diff --git a/applets/colorpicker/plugin/grabwidget.cpp b/applets/colorpicker/plugin/grabwidget.cpp
index 719a1ef..e53fdec 100644
--- a/applets/colorpicker/plugin/grabwidget.cpp
+++ b/applets/colorpicker/plugin/grabwidget.cpp
@@ -21,6 +21,12 @@
#include "grabwidget.h"
#include <QDebug>
+#include <QDBusConnection>
+#include <QDBusMessage>
+#include <QDBusMetaType>
+#include <QDBusPendingCall>
+#include <QDBusPendingCallWatcher>
+#include <QDBusPendingReply>
#include <QApplication>
#include <QClipboard>
#include <QEvent>
@@ -28,24 +34,57 @@
#include <QScreen>
#include <QWidget>
-GrabWidget::GrabWidget(QObject *parent)
+#include <KWindowSystem>
+
+Q_DECLARE_METATYPE(QColor)
+
+QDBusArgument &operator<< (QDBusArgument &argument, const QColor &color)
+{
+ argument.beginStructure();
+ argument << color.rgba();
+ argument.endStructure();
+ return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, QColor &color)
+{
+ argument.beginStructure();
+ QRgb rgba;
+ argument >> rgba;
+ argument.endStructure();
+ color = QColor::fromRgba(rgba);
+ return argument;
+}
+
+Grabber::Grabber(QObject *parent)
: QObject(parent)
- , m_grabWidget(new QWidget(nullptr, Qt::BypassWindowManagerHint))
{
- m_grabWidget->move(-5000, -5000);
}
-GrabWidget::~GrabWidget()
+Grabber::~Grabber() = default;
+
+void Grabber::setColor(const QColor &color)
{
- delete m_grabWidget;
+ if (m_color == color) {
+ return;
+ }
+ m_color = color;
+ emit colorChanged();
}
-QColor GrabWidget::currentColor() const
+X11Grabber::X11Grabber(QObject *parent)
+ : Grabber(parent)
+ , m_grabWidget(new QWidget(nullptr, Qt::BypassWindowManagerHint))
{
- return m_currentColor;
+ m_grabWidget->move(-5000, -5000);
}
-void GrabWidget::pick()
+X11Grabber::~X11Grabber()
+{
+ delete m_grabWidget;
+}
+
+void X11Grabber::pick()
{
// TODO pretend the mouse went somewhere else to prevent the tooltip from spawning
@@ -54,12 +93,7 @@ void GrabWidget::pick()
m_grabWidget->grabMouse(Qt::CrossCursor);
}
-void GrabWidget::copyToClipboard(const QString &text)
-{
- QApplication::clipboard()->setText(text);
-}
-
-bool GrabWidget::eventFilter(QObject *watched, QEvent *event)
+bool X11Grabber::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_grabWidget && event->type() == QEvent::MouseButtonRelease) {
m_grabWidget->removeEventFilter(this);
@@ -75,9 +109,67 @@ bool GrabWidget::eventFilter(QObject *watched, QEvent *event)
const QPixmap pixmap = qApp->primaryScreen()->grabWindow(0);
const QPoint localPos = pos * qApp->devicePixelRatio();
- m_currentColor = QColor(pixmap.toImage().pixel(localPos));
- emit currentColorChanged();
+ setColor(QColor(pixmap.toImage().pixel(localPos)));
}
return QObject::eventFilter(watched, event);
}
+
+KWinWaylandGrabber::KWinWaylandGrabber(QObject *parent)
+ : Grabber(parent)
+{
+ qDBusRegisterMetaType<QColor>();
+}
+
+KWinWaylandGrabber::~KWinWaylandGrabber() = default;
+
+void KWinWaylandGrabber::pick()
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
+ QStringLiteral("/ColorPicker"),
+ QStringLiteral("org.kde.kwin.ColorPicker"),
+ QStringLiteral("pick"));
+ auto call = QDBusConnection::sessionBus().asyncCall(msg);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ connect(watcher, &QDBusPendingCallWatcher::finished, this,
+ [this] (QDBusPendingCallWatcher *watcher) {
+ watcher->deleteLater();
+ QDBusPendingReply<QColor> reply = *watcher;
+ if (!reply.isError()) {
+ setColor(reply.value());
+ }
+ }
+ );
+}
+
+GrabWidget::GrabWidget(QObject *parent)
+ : QObject(parent)
+{
+ if (KWindowSystem::isPlatformX11()) {
+ m_grabber = new X11Grabber(this);
+ } else if (KWindowSystem::isPlatformWayland()) {
+ m_grabber = new KWinWaylandGrabber(this);
+ }
+ if (m_grabber) {
+ connect(m_grabber, &Grabber::colorChanged, this, &GrabWidget::currentColorChanged);
+ }
+}
+
+GrabWidget::~GrabWidget() = default;
+
+QColor GrabWidget::currentColor() const
+{
+ return m_grabber ? m_grabber->color() : QColor();
+}
+
+void GrabWidget::pick()
+{
+ if (m_grabber) {
+ m_grabber->pick();
+ }
+}
+
+void GrabWidget::copyToClipboard(const QString &text)
+{
+ QApplication::clipboard()->setText(text);
+}
diff --git a/applets/colorpicker/plugin/grabwidget.h b/applets/colorpicker/plugin/grabwidget.h
index d8e46e6..3fedb23 100644
--- a/applets/colorpicker/plugin/grabwidget.h
+++ b/applets/colorpicker/plugin/grabwidget.h
@@ -26,6 +26,55 @@
class QWidget;
+class Grabber : public QObject
+{
+ Q_OBJECT
+public:
+ virtual ~Grabber();
+
+ virtual void pick() = 0;
+
+ QColor color() const {
+ return m_color;
+ }
+
+Q_SIGNALS:
+ void colorChanged();
+
+protected:
+ void setColor(const QColor &color);
+ explicit Grabber(QObject *parent = nullptr);
+
+private:
+ QColor m_color;
+};
+
+class X11Grabber : public Grabber
+{
+ Q_OBJECT
+public:
+ explicit X11Grabber(QObject *parent = nullptr);
+ virtual ~X11Grabber();
+
+ void pick() override;
+
+protected:
+ virtual bool eventFilter(QObject *watched, QEvent *event) override;
+
+private:
+ QWidget *m_grabWidget;
+};
+
+class KWinWaylandGrabber : public Grabber
+{
+ Q_OBJECT
+public:
+ explicit KWinWaylandGrabber(QObject *parent = nullptr);
+ virtual ~KWinWaylandGrabber();
+
+ void pick() override;
+};
+
class GrabWidget : public QObject
{
Q_OBJECT
@@ -44,13 +93,8 @@ public:
signals:
void currentColorChanged();
-protected:
- virtual bool eventFilter(QObject *watched, QEvent *event) override;
-
private:
- QWidget *m_grabWidget;
-
- QColor m_currentColor;
+ Grabber *m_grabber = nullptr;
};