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

OSD positioning changes

This is revision 2 of D9414 that I didn't commit previously.
parent ceb80248
......@@ -52,6 +52,15 @@ Osd::Osd(const KScreen::OutputPtr output, QObject *parent)
m_osdTimer = new QTimer(this);
m_osdTimer->setSingleShot(true);
connect(m_osdTimer, &QTimer::timeout, this, &Osd::hideOsd);
connect(output.data(), &KScreen::Output::isConnectedChanged,
this, &Osd::onOutputAvailabilityChanged);
connect(output.data(), &KScreen::Output::isEnabledChanged,
this, &Osd::onOutputAvailabilityChanged);
connect(output.data(), &KScreen::Output::currentModeIdChanged,
this, &Osd::updatePosition);
connect(output.data(), &KScreen::Output::destroyed,
this, &Osd::hideOsd);
}
Osd::~Osd()
......@@ -104,20 +113,32 @@ void Osd::onOsdActionSelected(int action)
hideOsd();
}
void Osd::onOutputAvailabilityChanged()
{
if (m_output) {
if (!m_output->isConnected() || !m_output->isEnabled() || !m_output->currentMode()) {
hideOsd();
}
} else {
hideOsd();
}
}
void Osd::updatePosition()
{
if (!m_outputGeometry.isValid()) {
return;
const auto geometry = m_output->geometry();
if (!geometry.isValid()) {
hideOsd();
}
auto *rootObject = m_osdObject->rootObject();
const int dialogWidth = rootObject->property("width").toInt();
const int dialogHeight = rootObject->property("height").toInt();
const int relx = m_outputGeometry.x();
const int rely = m_outputGeometry.y();
const int pos_x = relx + (m_outputGeometry.width() - dialogWidth) / 2;
const int pos_y = rely + (m_outputGeometry.height() - dialogHeight) / 2;
const int relx = geometry.x();
const int rely = geometry.y();
const int pos_x = relx + (geometry.width() - dialogWidth) / 2;
const int pos_y = rely + (geometry.height() - dialogHeight) / 2;
rootObject->setProperty("x", pos_x);
rootObject->setProperty("y", pos_y);
......@@ -144,7 +165,7 @@ void Osd::showOsd()
} else {
rootObject->setProperty("visible", true);
}
updatePosition();
QTimer::singleShot(0, this, &Osd::updatePosition);
if (m_timeout > 0) {
m_osdTimer->start(m_timeout);
}
......
......@@ -47,15 +47,16 @@ public:
void showGenericOsd(const QString &icon, const QString &text);
void showOutputIdentifier(const KScreen::OutputPtr output);
void showActionSelector();
void hideOsd();
Q_SIGNALS:
void osdActionSelected(OsdAction::Action action);
private Q_SLOTS:
void onOsdActionSelected(int action);
void onOutputAvailabilityChanged();
private:
void hideOsd();
void showOsd();
void updatePosition();
......
......@@ -154,6 +154,12 @@ OsdAction *OsdManager::showActionSelector()
hideOsd();
OsdActionImpl *action = new OsdActionImpl(this);
connect(action, &OsdActionImpl::selected,
this, [this]() {
for (auto osd : qAsConst(m_osds)) {
osd->hideOsd();
}
});
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished,
this, [this, action](const KScreen::ConfigOperation *op) {
if (op->hasError()) {
......@@ -161,63 +167,49 @@ OsdAction *OsdManager::showActionSelector()
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, 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();
// Show selector on alll enabled screens
const auto outputs = op->config()->outputs();
KScreen::OutputPtr osdOutput;
for (const auto &output : outputs) {
if (!output->isConnected() || !output->isEnabled() || !output->currentMode()) {
continue;
}
}
if (!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) {
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;
}
}
// Prefer laptop screen
if (output->type() == KScreen::Output::Panel) {
osdOutput = output;
break;
}
if (largestIt != end) {
output = *largestIt;
// Fallback to primary
if (output->isPrimary()) {
osdOutput = output;
break;
}
}
if (!output) {
// fallback to the first active output
for (const auto &o : outputs) {
if (o->isConnected() && o->isEnabled()) {
output = o;
// no laptop or primary screen, just take the first usable one
if (!osdOutput) {
for (const auto &output : outputs) {
if (output->isConnected() && output->isEnabled() && output->currentMode()) {
osdOutput = output;
break;
}
}
}
if (!output) {
// no outputs? bail out...
qCDebug(KSCREEN_KDED) << "Found no usable outputs";
if (!osdOutput) {
// huh!?
return;
}
auto osd = new KScreen::Osd(output, this);
KScreen::Osd* osd = nullptr;
if (m_osds.contains(osdOutput->name())) {
osd = m_osds.value(osdOutput->name());
} else {
osd = new KScreen::Osd(osdOutput, this);
m_osds.insert(osdOutput->name(), osd);
}
action->setOsd(osd);
m_osds.insert(output->name(), osd);
osd->showActionSelector();
m_cleanupTimer->start();
}
......
/*
* 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
......
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