Commit 387fda6f authored by David Redondo's avatar David Redondo 🏎
Browse files

kcm: Use KWin effect to identify outputs

parent 9fbfef94
Pipeline #207331 passed with stage
in 1 minute and 37 seconds
......@@ -3,7 +3,6 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kscreen\")
set(kcm_kscreen_SRCS
config_handler.cpp
kcm.cpp
output_identifier.cpp
output_model.cpp
${CMAKE_SOURCE_DIR}/common/utils.cpp
${CMAKE_SOURCE_DIR}/common/control.cpp
......
......@@ -10,7 +10,6 @@
#include "config_handler.h"
#include "globalscalesettings.h"
#include "kcm_screen_debug.h"
#include "output_identifier.h"
#include "output_model.h"
#include <kscreen/config.h>
......@@ -233,13 +232,11 @@ OutputModel *KCMKScreen::outputModel() const
void KCMKScreen::identifyOutputs()
{
if (!m_configHandler || !m_configHandler->initialConfig() || m_outputIdentifier) {
return;
}
m_outputIdentifier.reset(new OutputIdentifier(m_configHandler->initialConfig(), this));
connect(m_outputIdentifier.get(), &OutputIdentifier::identifiersFinished, this, [this]() {
m_outputIdentifier.reset();
});
const QString name = QStringLiteral("org.kde.KWin");
const QString interface = QStringLiteral("org.kde.KWin.Effect.OutputLocator1");
const QString path = QStringLiteral("/org/kde/KWin/Effect/OutputLocator1");
auto message = QDBusMessage::createMethodCall(name, path, interface, QStringLiteral("show"));
QDBusConnection::sessionBus().send(message);
}
QSize KCMKScreen::normalizeScreen() const
......@@ -483,4 +480,3 @@ void KCMKScreen::setOutputRetention(int retention)
}
#include "kcm.moc"
#include "moc_kcm.cpp"
......@@ -112,7 +112,6 @@ private:
void configReady(KScreen::ConfigOperation *op);
void continueNeedsSaveCheck(bool needs);
std::unique_ptr<OutputIdentifier> m_outputIdentifier;
std::unique_ptr<ConfigHandler> m_configHandler;
OrientationSensor *m_orientationSensor;
bool m_backendReady = false;
......
/*
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "output_identifier.h"
#include "../common/utils.h"
#include <kscreen/edid.h>
#include <kscreen/output.h>
#include <QQuickItem>
#include <QStandardPaths>
#include <QTimer>
#include <KDeclarative/kdeclarative/qmlobject.h>
#include <PlasmaQuick/Dialog>
#define QML_PATH "kpackage/kcms/kcm_kscreen/contents/ui/"
OutputIdentifier::OutputIdentifier(KScreen::ConfigPtr config, QObject *parent)
: QObject(parent)
{
const QString qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(QML_PATH "OutputIdentifier.qml"));
const auto outputs = config->connectedOutputs();
for (const auto &output : outputs) {
if (!output->currentMode()) {
continue;
}
const KScreen::ModePtr mode = output->currentMode();
auto *view = new PlasmaQuick::Dialog();
auto qmlObject = new KDeclarative::QmlObject(view);
qmlObject->setSource(QUrl::fromLocalFile(qmlPath));
qmlObject->completeInitialization();
auto rootObj = qobject_cast<QQuickItem *>(qmlObject->rootObject());
view->setMainItem(rootObj);
view->setFlags(Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
view->setBackgroundHints(PlasmaQuick::Dialog::NoBackground);
view->installEventFilter(this);
if (!rootObj) {
delete view;
continue;
}
QSize logicalSize = config->logicalSizeForOutput(*output.data()).toSize();
if (!(config->supportedFeatures() & KScreen::Config::Feature::PerOutputScaling)) {
logicalSize = logicalSize / view->effectiveDevicePixelRatio();
}
bool shouldShowSerialNumber = false;
if (output->edid()) {
shouldShowSerialNumber = std::any_of(outputs.cbegin(), outputs.cend(), [output](const auto &other) {
return other->id() != output->id() // avoid same output
&& other->edid() && other->edid()->name() == output->edid()->name() && other->edid()->vendor() == output->edid()->vendor();
});
}
rootObj->setProperty("outputName", Utils::outputName(output, shouldShowSerialNumber));
rootObj->setProperty("resolution", output->currentMode()->size());
rootObj->setProperty("scale", output->scale());
view->setProperty("screenSize", QRect(output->pos(), logicalSize));
m_views << view;
}
for (auto *view : qAsConst(m_views)) {
view->show();
}
QTimer::singleShot(2500, this, &OutputIdentifier::identifiersFinished);
}
OutputIdentifier::~OutputIdentifier()
{
qDeleteAll(m_views);
}
bool OutputIdentifier::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::Resize) {
if (m_views.contains(qobject_cast<PlasmaQuick::Dialog *>(object))) {
QResizeEvent *e = static_cast<QResizeEvent *>(event);
const QRect screenSize = object->property("screenSize").toRect();
QRect geometry(QPoint(0, 0), e->size());
geometry.moveCenter(screenSize.center());
static_cast<PlasmaQuick::Dialog *>(object)->setGeometry(geometry);
}
}
return QObject::eventFilter(object, event);
}
/*
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <kscreen/config.h>
#include <QVector>
namespace PlasmaQuick
{
class Dialog;
}
class OutputIdentifier : public QObject
{
Q_OBJECT
public:
explicit OutputIdentifier(KScreen::ConfigPtr config, QObject *parent = nullptr);
~OutputIdentifier() override;
Q_SIGNALS:
void identifiersFinished();
protected:
bool eventFilter(QObject *object, QEvent *event) override;
private:
QVector<PlasmaQuick::Dialog *> m_views;
};
/*
SPDX-FileCopyrightText: 2012 Dan Vratil <dvratil@redhat.com>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
import QtQuick 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Rectangle {
id: root;
property string outputName;
property size resolution;
property double scale;
color: theme.backgroundColor
border {
color: "red"
width: units.smallSpacing * 2
}
width: childrenRect.width + 2 * childrenRect.x
height: childrenRect.height + 2 * childrenRect.y
PlasmaComponents.Label {
id: displayName
x: units.largeSpacing * 2
y: units.largeSpacing
font.pointSize: theme.defaultFont.pointSize * 3
text: root.outputName;
wrapMode: Text.WordWrap;
horizontalAlignment: Text.AlignHCenter;
}
PlasmaComponents.Label {
id: modeLabel;
anchors {
horizontalCenter: displayName.horizontalCenter
top: displayName.bottom
}
text: resolution.width + "x" + resolution.height +
(root.scale !== 1 ? "@" + Math.round(root.scale * 100.0) + "%": "")
horizontalAlignment: Text.AlignHCenter;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment