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

Extend the OSD with an actionable OSD to choosee layout for new screens

parent 01e1ab30
......@@ -46,6 +46,7 @@ install(TARGETS kscreen DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kded)
set(QML_FILES
qml/Osd.qml
qml/OsdItem.qml
qml/OsdSelector.qml
qml/OutputIdentifier.qml
)
......
......@@ -85,6 +85,24 @@ void Osd::showOutputIdentifier(const KScreen::OutputPtr output)
showOsd();
}
void Osd::showActionSelector() {
m_outputGeometry = m_output->geometry();
auto *rootObject = m_osdObject->rootObject();
rootObject->setProperty("itemSource", QStringLiteral("OsdSelector.qml"));
rootObject->setProperty("timeout", 0);
rootObject->setProperty("outputOnly", false);
auto osdItem = rootObject->property("osdItem").value<QObject*>();
connect(osdItem, SIGNAL(clicked(QString)),
this, SLOT(onOsdActionSelected(QString)));
m_timeout = 0; // no timeout for this one
showOsd();
}
void Osd::onOsdActionSelected(const QString &action) {
Q_EMIT osdActionSelected(action);
hideOsd();
}
void Osd::updatePosition()
{
if (!m_outputGeometry.isValid()) {
......
......@@ -44,6 +44,13 @@ public:
void showGenericOsd(const QString &icon, const QString &text);
void showOutputIdentifier(const KScreen::OutputPtr output);
void showActionSelector();
Q_SIGNALS:
void osdActionSelected(const QString &action);
private Q_SLOTS:
void onOsdActionSelected(const QString &action);
private:
void hideOsd();
......
......@@ -119,5 +119,76 @@ void OsdManager::showOsd(const QString& icon, const QString& text)
);
}
void OsdManager::showActionSelector()
{
qDeleteAll(m_osds);
m_osds.clear();
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished,
this, [this](const KScreen::ConfigOperation *op) {
if (op->hasError()) {
qCWarning(KSCREEN_KDED) << op->errorString();
return;
}
auto config = op->config();
const auto outputs = config->outputs();
// 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;
}
}
if (!output) {
// no primary or laptop output, use the biggest output
const auto end = outputs.cend();
auto largestIt = end;
for (auto it = outputs.cbegin(); it != end; ++it) {
if (!(*it)->isConnected() || !(*it)->isEnabled() || !(*it)->currentMode()) {
continue;
}
if (largestIt == end) {
largestIt = it;
} else {
const auto itSize = (*it)->currentMode()->size();
const auto largestSize = (*largestIt)->currentMode()->size();
if (itSize.width() * itSize.height() > largestSize.width() * largestSize.height()) {
largestIt = it;
}
}
}
if (largestIt != end) {
output = *largestIt;
}
}
if (!output) {
// fallback to first active output
for (const auto &o : outputs) {
if (o->isConnected() && o->isEnabled()) {
output = o;
break;
}
}
}
if (!output) {
// no outputs? bail out...
qCDebug(KSCREEN_KDED) << "Found no usable outputs";
return;
}
auto osd = new KScreen::Osd(output, this);
connect(osd, &Osd::osdActionSelected, this, &OsdManager::osdActionSelected);
m_osds.insert(output->name(), osd);
osd->showActionSelector();
m_cleanupTimer->start();
}
);
}
}
......@@ -43,6 +43,10 @@ public:
public Q_SLOTS:
void showOutputIdentifiers();
void showOsd(const QString &icon, const QString &text);
void showActionSelector();
Q_SIGNALS:
void osdActionSelected(const QString &action);
private:
OsdManager(QObject *parent = nullptr);
......
......@@ -36,6 +36,7 @@ PlasmaCore.Dialog {
property string modeName
property bool animateOpacity: false
property string itemSource
property QtObject osdItem
Behavior on opacity {
SequentialAnimation {
......@@ -55,6 +56,7 @@ PlasmaCore.Dialog {
onItemChanged: {
if (item != undefined) {
item.rootItem = root;
root.osdItem = item
}
}
......
/*
* Copyright 2017 Daniel Vrátil <dvratil@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.5
import QtQuick.Window 2.2
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
Item {
id: root
property QtObject rootItem
signal clicked(string actionId)
height: Math.min(units.gridUnit * 15, Screen.desktopAvailableHeight / 5)
width: buttonRow.width
PlasmaComponents.ButtonRow {
id: buttonRow
exclusive: false
height: parent.height - label.height - ((units.smallSpacing/2) * 3)
width: (actionRepeater.model.length * height) + ((actionRepeater.model.length - 1) * buttonRow.spacing);
Repeater {
id: actionRepeater
model: [
{
iconSource: "osd-shutd-screen",
label: qsTr("Switch to external screen"),
action: "external-only"
},
{
iconSource: "osd-shutd-laptop",
label: qsTr("Switch to laptop screen"),
action: "internal-only"
},
{
iconSource: "osd-duplicate",
label: qsTr("Duplicate outputs"),
action: "clone"
},
{
iconSource: "osd-sbs-left",
label: qsTr("Extend to left"),
action: "extend-left"
},
{
iconSource: "osd-sbs-sright",
label: qsTr("Extend to right"),
action: "extend-right"
},
{
iconSource: "dialog-cancel",
label: qsTr("Do nothing"),
action: "cancel"
}
]
delegate: PlasmaComponents.Button {
PlasmaCore.IconItem {
source: modelData.iconSource
height: buttonRow.height - ((units.smallSpacing / 2) * 3)
width: height
anchors.centerIn: parent
}
height: parent.height
width: height
onHoveredChanged: rootItem.infoText = (hovered ? modelData.label : "")
onClicked: root.clicked(modelData.action)
}
}
}
// TODO: keep? remove?
PlasmaExtras.Heading {
id: label
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
margins: Math.floor(units.smallSpacing / 2)
}
text: rootItem.infoText
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
maximumLineCount: 2
elide: Text.ElideLeft
minimumPointSize: theme.defaultFont.pointSize
fontSizeMode: Text.HorizontalFit
}
Component.onCompleted: print("OsdSelector loaded...");
}
......@@ -33,6 +33,8 @@ int main(int argc, char **argv)
QStringLiteral("Icon to use for OSD"), QStringLiteral("preferences-desktop-display-randr"));
QCommandLineOption message = QCommandLineOption(QStringList() << QStringLiteral("m") << "message",
QStringLiteral("Icon to use for OSD"), QStringLiteral("OSD Test"));
QCommandLineOption selector = QCommandLineOption({ QStringLiteral("s"), QStringLiteral("selector") },
QStringLiteral("Show new screen action selector"));
KScreen::OsdTest osdtest;
QCommandLineParser parser;
parser.addHelpOption();
......@@ -40,6 +42,7 @@ int main(int argc, char **argv)
parser.addOption(outputid);
parser.addOption(icon);
parser.addOption(message);
parser.addOption(selector);
parser.process(app);
......@@ -48,8 +51,9 @@ int main(int argc, char **argv)
osdtest.setUseDBus(true);
}
if (parser.isSet(outputid)) {
osdtest.showOutputIdentifiers();
} else if (parser.isSet(selector)) {
osdtest.showActionSelector();
} else {
osdtest.showGenericOsd(parser.value(icon), parser.value(message));
}
......
......@@ -75,5 +75,19 @@ 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;
qApp->quit();
});
KScreen::OsdManager::self()->showActionSelector();
} else {
qCWarning(KSCREEN_KDED) << "Implement me.";
QTimer::singleShot(100, qApp, &QCoreApplication::quit);
}
}
} // ns
......@@ -37,6 +37,7 @@ public:
void showGenericOsd(const QString &icon, const QString &message);
void showOutputIdentifiers();
void showActionSelector();
private:
bool m_useDBus = false;
......
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