x11: Make sure that outputs are stored in xinerama order

With the new output query algorithm, position of an output may not align
with its xinerama index. This can be problem on x11 as some protocols,
e.g. startup feedback, use xinerama indices to identify outputs.

Technically, the RandR specification doesn't say that CRTCs are stored
in the xinerama order, it only mentions that the first CRTC corresponds
to the primary output. However, such assumption was made by kwin prior
to output query changes, this change merely restores that behavior.
icc-effect-5.26.4
Vlad Zahorodnii 2021-08-29 16:49:03 +03:00
parent 7016da39c8
commit 8a93a33b96
3 changed files with 29 additions and 0 deletions

View File

@ -23,6 +23,16 @@ QString X11Output::name() const
return m_name;
}
int X11Output::xineramaNumber() const
{
return m_xineramaNumber;
}
void X11Output::setXineramaNumber(int number)
{
m_xineramaNumber = number;
}
QRect X11Output::geometry() const
{
return m_geometry;

View File

@ -32,6 +32,9 @@ public:
QString name() const override;
int xineramaNumber() const;
void setXineramaNumber(int number);
QRect geometry() const override;
void setGeometry(QRect set);
@ -56,6 +59,7 @@ private:
QSize m_physicalSize;
int m_gammaRampSize;
int m_refreshRate;
int m_xineramaNumber = 0;
friend class X11StandalonePlatform;
};

View File

@ -533,6 +533,7 @@ void X11StandalonePlatform::doUpdateOutputs()
output->setGammaRampSize(gamma.isNull() ? 0 : gamma->size);
output->setGeometry(geometry);
output->setRefreshRate(refreshRate * 1000);
output->setXineramaNumber(i);
QSize physicalSize(outputInfo->mm_width, outputInfo->mm_height);
switch (info->rotation) {
@ -578,6 +579,20 @@ void X11StandalonePlatform::doUpdateOutputs()
delete output;
}
// Make sure that the position of an output in m_outputs matches its xinerama index, there
// are X11 protocols that use xinerama indices to identify outputs.
std::sort(m_outputs.begin(), m_outputs.end(), [](const AbstractOutput *a, const AbstractOutput *b) {
const auto xa = qobject_cast<const X11Output *>(a);
if (!xa) {
return false;
}
const auto xb = qobject_cast<const X11Output *>(b);
if (!xb) {
return true;
}
return xa->xineramaNumber() < xb->xineramaNumber();
});
Q_EMIT screensQueried();
}