Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit b237aebd authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧

Support QXL hotplug_mode_update

Summary:
QXL is a driver used mainly in VMs.
This driver, it creates a new preferred mode upon resize instead of just
offering the one and resizing it. This makes Plasma not resize when it should
as described on the bug report below.
This patch allows kscreen to know if the driver considers we should be
following the preferred mode.

https://bugzilla.redhat.com/show_bug.cgi?id=1290586

Test Plan: Tested extensively on one of these vms and outside.

Reviewers: #plasma, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: davidedmundson, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D15789
parent c4d361db
......@@ -277,6 +277,18 @@ QByteArray XRandR::outputEdid(xcb_randr_output_t outputId)
return edid;
}
bool XRandR::hasProperty(xcb_randr_output_t output, const QByteArray& name)
{
xcb_generic_error_t *error = nullptr;
auto atom = XCB::InternAtom(false, name.length(), name.constData())->atom;
auto cookie = xcb_randr_get_output_property(XCB::connection(), output, atom, XCB_ATOM_ANY, 0, 1, false, false);
auto prop_reply = xcb_randr_get_output_property_reply (XCB::connection(), cookie, &error);
const bool ret = prop_reply->num_items == 1;
free(prop_reply);
return ret;
}
xcb_randr_get_screen_resources_reply_t* XRandR::screenResources()
{
if (XRandR::s_has_1_3) {
......
......@@ -57,6 +57,8 @@ class XRandR : public KScreen::AbstractBackend
static xcb_screen_t* screen();
static xcb_window_t rootWindow();
static bool hasProperty(xcb_randr_output_t outputId, const QByteArray &name);
private Q_SLOTS:
void outputChanged(xcb_randr_output_t output,
xcb_randr_crtc_t crtc,
......
......@@ -155,6 +155,7 @@ void XRandROutput::update(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, xcb_rand
updateModes(outputInfo);
}
m_hotplugModeUpdate = XRandR::hasProperty(m_id, "hotplug_mode_update");
}
// A monitor has been enabled or disabled
......@@ -208,6 +209,7 @@ void XRandROutput::init()
if (m_crtc) {
m_crtc->connectOutput(m_id);
}
m_hotplugModeUpdate = XRandR::hasProperty(m_id, "hotplug_mode_update");
updateModes(outputInfo);
}
......@@ -304,6 +306,10 @@ KScreen::OutputPtr XRandROutput::toKScreenOutput() const
kscreenOutput->setName(m_name);
kscreenOutput->setIcon(m_icon);
//See https://bugzilla.redhat.com/show_bug.cgi?id=1290586
//QXL will be creating a new mode we need to jump to every time the display is resized
kscreenOutput->setFollowPreferredMode(m_hotplugModeUpdate);
kscreenOutput->setConnected(isConnected());
if (isConnected()) {
KScreen::ModeList kscreenModes;
......
......@@ -90,6 +90,7 @@ private:
mutable QByteArray m_edid;
unsigned int m_widthMm;
unsigned int m_heightMm;
bool m_hotplugModeUpdate = false;
XRandRCrtc *m_crtc;
};
......
......@@ -86,6 +86,7 @@ QJsonObject ConfigSerializer::serializeOutput(const OutputPtr &output)
obj[QLatin1String("currentModeId")] = output->currentModeId();
obj[QLatin1String("preferredModes")] = serializeList(output->preferredModes());
obj[QLatin1String("connected")] = output->isConnected();
obj[QLatin1String("followPreferredMode")] = output->followPreferredMode();
obj[QLatin1String("enabled")] = output->isEnabled();
obj[QLatin1String("primary")] = output->isPrimary();
obj[QLatin1String("clones")] = serializeList(output->clones());
......@@ -242,6 +243,8 @@ OutputPtr ConfigSerializer::deserializeOutput(const QDBusArgument &arg)
output->setPreferredModes(deserializeList<QString>(value.value<QDBusArgument>()));
} else if (key == QLatin1String("connected")) {
output->setConnected(value.toBool());
} else if (key == QLatin1String("followPreferredMode")) {
output->setFollowPreferredMode(value.toBool());
} else if (key == QLatin1String("enabled")) {
output->setEnabled(value.toBool());
} else if (key == QLatin1String("primary")) {
......
......@@ -60,7 +60,8 @@ class Q_DECL_HIDDEN Output::Private
scale(other.scale),
connected(other.connected),
enabled(other.enabled),
primary(other.primary)
primary(other.primary),
followPreferredMode(other.followPreferredMode)
{
Q_FOREACH (const ModePtr &otherMode, other.modeList) {
modeList.insert(otherMode->id(), otherMode->clone());
......@@ -90,6 +91,7 @@ class Q_DECL_HIDDEN Output::Private
bool connected;
bool enabled;
bool primary;
bool followPreferredMode = false;
mutable QPointer<Edid> edid;
};
......@@ -479,6 +481,19 @@ void Output::setSizeMm(const QSize &size)
d->sizeMm = size;
}
bool KScreen::Output::followPreferredMode() const
{
return d->followPreferredMode;
}
void KScreen::Output::setFollowPreferredMode(bool follow)
{
if (follow != d->followPreferredMode) {
d->followPreferredMode = follow;
Q_EMIT followPreferredModeChanged(follow);
}
}
QRect Output::geometry() const
{
if (!currentMode()) {
......@@ -588,6 +603,7 @@ QDebug operator<<(QDebug dbg, const KScreen::OutputPtr &output)
<< "pos:" << output->pos() << "res:" << output->size()
<< "modeId:" << output->currentModeId()
<< "scale:" << output->scale()
<< "followPreferredMode:" << output->followPreferredMode()
<< ")";
} else {
dbg << "KScreen::Output(NULL)";
......
......@@ -59,6 +59,7 @@ class KSCREEN_EXPORT Output : public QObject
Q_PROPERTY(KScreen::Edid* edid READ edid CONSTANT)
Q_PROPERTY(QSize sizeMm READ sizeMm CONSTANT)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
Q_PROPERTY(bool followPreferredMode READ followPreferredMode WRITE setFollowPreferredMode NOTIFY followPreferredModeChanged)
enum Type {
......@@ -211,6 +212,21 @@ class KSCREEN_EXPORT Output : public QObject
*/
void setScale(qreal factor);
/**
* @returns whether the mode should be changed to the new preferred mode
* once it changes
*
* @since 5.15
*/
bool followPreferredMode() const;
/**
* Set whether the preferred mode should be followed through @arg follow
*
* @since 5.15
*/
void setFollowPreferredMode(bool follow);
void apply(const OutputPtr &other);
Q_SIGNALS:
void outputChanged();
......@@ -223,6 +239,7 @@ class KSCREEN_EXPORT Output : public QObject
void isPrimaryChanged();
void clonesChanged();
void scaleChanged();
void followPreferredModeChanged(bool followPreferredMode);
/** The mode list changed.
*
......
Markdown is supported
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