Commit 7a74d3af authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

Integrate the OSD action selector with the KDED daemon

parent b64339f4
......@@ -181,10 +181,49 @@ void KScreenDaemon::applyKnownConfig()
doApplyConfig(config);
}
void KScreenDaemon::applyOsdAction(KScreen::OsdAction *self, KScreen::OsdAction::Action action)
{
self->deleteLater();
switch (action) {
case KScreen::OsdAction::NoAction:
qCDebug(KSCREEN_KDED) << "OSD: no action";
return;
case KScreen::OsdAction::SwitchToInternal:
qCDebug(KSCREEN_KDED) << "OSD: swutch to internal";
doApplyConfig(Generator::self()->displaySwitch(Generator::TurnOffExternal));
return;
case KScreen::OsdAction::SwitchToExternal:
qCDebug(KSCREEN_KDED) << "OSD: switch to external";
doApplyConfig(Generator::self()->displaySwitch(Generator::TurnOffEmbedded));
return;
case KScreen::OsdAction::ExtendLeft:
qCDebug(KSCREEN_KDED) << "OSD: extend left";
doApplyConfig(Generator::self()->displaySwitch(Generator::ExtendToLeft));
return;
case KScreen::OsdAction::ExtendRight:
qCDebug(KSCREEN_KDED) << "OSD: extend right";
doApplyConfig(Generator::self()->displaySwitch(Generator::ExtendToRight));
return;
case KScreen::OsdAction::Clone:
qCDebug(KSCREEN_KDED) << "OSD: clone";
doApplyConfig(Generator::self()->displaySwitch(Generator::Clone));
return;
}
Q_UNREACHABLE();
}
void KScreenDaemon::applyIdealConfig()
{
qCDebug(KSCREEN_KDED) << "Applying ideal config";
doApplyConfig(Generator::self()->idealConfig(m_monitoredConfig));
if (m_monitoredConfig->connectedOutputs().count() < 2) {
doApplyConfig(Generator::self()->idealConfig(m_monitoredConfig));
} else {
qCDebug(KSCREEN_KDED) << "Getting ideal config from user...";
auto action = KScreen::OsdManager::self()->showActionSelector();
connect(action, &KScreen::OsdAction::selected,
this, &KScreenDaemon::applyOsdAction);
}
}
void logConfig(const KScreen::ConfigPtr &config) {
......
......@@ -26,6 +26,7 @@
#include <kscreen/config.h>
#include "generator.h"
#include "osdmanager.h"
class QTimer;
......@@ -61,6 +62,7 @@ class Q_DECL_EXPORT KScreenDaemon : public KDEDModule
void setMonitorForChanges(bool enabled);
void outputConnectedChanged();
void showOutputIdentifier();
void applyOsdAction(KScreen::OsdAction *self, KScreen::OsdAction::Action action);
Q_SIGNALS:
void outputConnected(const QString &outputName);
......
......@@ -92,14 +92,15 @@ void Osd::showActionSelector() {
rootObject->setProperty("timeout", 0);
rootObject->setProperty("outputOnly", false);
auto osdItem = rootObject->property("osdItem").value<QObject*>();
connect(osdItem, SIGNAL(clicked(QString)),
this, SLOT(onOsdActionSelected(QString)));
connect(osdItem, SIGNAL(clicked(int)),
this, SLOT(onOsdActionSelected(int)));
m_timeout = 0; // no timeout for this one
showOsd();
}
void Osd::onOsdActionSelected(const QString &action) {
Q_EMIT osdActionSelected(action);
void Osd::onOsdActionSelected(int action)
{
Q_EMIT osdActionSelected(static_cast<OsdAction::Action>(action));
hideOsd();
}
......
......@@ -26,6 +26,8 @@
#include <KScreen/Output>
#include "osdmanager.h"
namespace KDeclarative {
class QmlObject;
}
......@@ -47,10 +49,10 @@ public:
void showActionSelector();
Q_SIGNALS:
void osdActionSelected(const QString &action);
void osdActionSelected(OsdAction::Action action);
private Q_SLOTS:
void onOsdActionSelected(const QString &action);
void onOsdActionSelected(int action);
private:
void hideOsd();
......
......@@ -26,14 +26,39 @@
#include <QDBusConnection>
#include <QQmlEngine>
namespace KScreen {
OsdManager* OsdManager::s_instance = nullptr;
OsdAction::OsdAction(QObject *parent)
: QObject(parent)
{
}
class OsdActionImpl : public OsdAction
{
Q_OBJECT
public:
OsdActionImpl(QObject *parent = nullptr)
: OsdAction(parent)
{}
void setOsd(Osd *osd) {
connect(osd, &Osd::osdActionSelected,
this, [this](Action action) {
Q_EMIT selected(this, action);
});
}
};
OsdManager::OsdManager(QObject *parent)
: QObject(parent)
, m_cleanupTimer(new QTimer(this))
{
qmlRegisterUncreatableType<OsdAction>("org.kde.KScreen", 1, 0, "OsdAction", "You cannot create OsdAction");
// free up memory when the osd hasn't been used for more than 1 minute
m_cleanupTimer->setInterval(60000);
m_cleanupTimer->setSingleShot(true);
......@@ -119,12 +144,14 @@ void OsdManager::showOsd(const QString& icon, const QString& text)
);
}
void OsdManager::showActionSelector()
OsdAction *OsdManager::showActionSelector()
{
qDeleteAll(m_osds);
m_osds.clear();
OsdActionImpl *action = new OsdActionImpl(this);
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished,
this, [this](const KScreen::ConfigOperation *op) {
this, [this, action](const KScreen::ConfigOperation *op) {
if (op->hasError()) {
qCWarning(KSCREEN_KDED) << op->errorString();
return;
......@@ -135,17 +162,20 @@ void OsdManager::showActionSelector()
// If we have a primary output, show the selector on that screen
auto output = config->primaryOutput();
if (!output) {
// no primary output, use the laptop output
auto it = std::find_if(outputs.cbegin(), outputs.cend(),
[](const OutputPtr &output) {
return output->type() == Output::Panel;
});
if (it != outputs.cend() && (*it)->isConnected() && (*it)->isEnabled()) {
output = *it;
// no primary output, maybe we have only one output enabled?
int enabledCount = 0;
for (const auto &out : outputs) {
if (out->isConnected() && out->isEnabled()) {
enabledCount++;
output = out;
}
}
if (enabledCount > 1) {
output.clear();
}
}
if (!output) {
// no primary or laptop output, use the biggest output
// multiple outputs, none primary, show on the biggest one
const auto end = outputs.cend();
auto largestIt = end;
for (auto it = outputs.cbegin(); it != end; ++it) {
......@@ -167,7 +197,7 @@ void OsdManager::showActionSelector()
}
}
if (!output) {
// fallback to first active output
// fallback to the first active output
for (const auto &o : outputs) {
if (o->isConnected() && o->isEnabled()) {
output = o;
......@@ -182,13 +212,17 @@ void OsdManager::showActionSelector()
}
auto osd = new KScreen::Osd(output, this);
connect(osd, &Osd::osdActionSelected, this, &OsdManager::osdActionSelected);
action->setOsd(osd);
m_osds.insert(output->name(), osd);
osd->showActionSelector();
m_cleanupTimer->start();
}
);
return action;
}
}
#include "osdmanager.moc"
......@@ -32,6 +32,28 @@ class ConfigOperation;
class Osd;
class Output;
class OsdAction : public QObject
{
Q_OBJECT
public:
enum Action {
NoAction,
SwitchToExternal,
SwitchToInternal,
Clone,
ExtendLeft,
ExtendRight
};
Q_ENUM(Action)
Q_SIGNALS:
void selected(OsdAction *self, Action action);
protected:
explicit OsdAction(QObject *parent = nullptr);
};
class OsdManager : public QObject {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.kscreen.osdService")
......@@ -43,10 +65,7 @@ public:
public Q_SLOTS:
void showOutputIdentifiers();
void showOsd(const QString &icon, const QString &text);
void showActionSelector();
Q_SIGNALS:
void osdActionSelected(const QString &action);
OsdAction *showActionSelector();
private:
OsdManager(QObject *parent = nullptr);
......
......@@ -22,11 +22,13 @@ import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.KScreen 1.0
Item {
id: root
property QtObject rootItem
signal clicked(string actionId)
signal clicked(int actionId)
height: Math.min(units.gridUnit * 15, Screen.desktopAvailableHeight / 5)
width: buttonRow.width
......@@ -45,32 +47,32 @@ Item {
{
iconSource: "osd-shutd-screen",
label: qsTr("Switch to external screen"),
action: "external-only"
action: OsdAction.SwitchToExternal
},
{
iconSource: "osd-shutd-laptop",
label: qsTr("Switch to laptop screen"),
action: "internal-only"
action: OsdAction.SwitchToInternal
},
{
iconSource: "osd-duplicate",
label: qsTr("Duplicate outputs"),
action: "clone"
action: OsdAction.Clonse
},
{
iconSource: "osd-sbs-left",
label: qsTr("Extend to left"),
action: "extend-left"
action: OsdAction.ExtendLeft
},
{
iconSource: "osd-sbs-sright",
label: qsTr("Extend to right"),
action: "extend-right"
action: OsdAction.ExtendRight
},
{
iconSource: "dialog-cancel",
label: qsTr("Do nothing"),
action: "cancel"
action: OsdAction.NoAction
}
]
delegate: PlasmaComponents.Button {
......
......@@ -78,12 +78,13 @@ void OsdTest::showGenericOsd(const QString& icon, const QString& message)
void OsdTest::showActionSelector()
{
if (!m_useDBus) {
connect(KScreen::OsdManager::self(), &KScreen::OsdManager::osdActionSelected,
[](const QString &action) {
qCDebug(KSCREEN_KDED) << "Action selected:" << action;
auto action = KScreen::OsdManager::self()->showActionSelector();
connect(action, &KScreen::OsdAction::selected,
[](KScreen::OsdAction *self, KScreen::OsdAction::Action action) {
self->deleteLater();
qCDebug(KSCREEN_KDED) << "Selected action:" << action;
qApp->quit();
});
KScreen::OsdManager::self()->showActionSelector();
} else {
qCWarning(KSCREEN_KDED) << "Implement me.";
QTimer::singleShot(100, qApp, &QCoreApplication::quit);
......
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