OutputManagement fractional scaling
Summary: In order to have fractional scaling in kwin, we need to communicate it with kscreen, which means changing the data type in our config protocols. This introduces a new method on outputdevice and outputconfiguration to set/request scale as a float. wl_output is and should remain unchanged as an int No urgent rush for reviewing/merging this as it's useless without other changes. Test Plan: Attached unit tests Reviewers: #kwin, romangg Subscribers: romangg, zzag, kde-frameworks-devel Tags: #frameworks Differential Revision: https://phabricator.kde.org/D13601
This commit is contained in:
parent
2a3b34ae6a
commit
961bcbde08
9 changed files with 152 additions and 15 deletions
|
@ -44,6 +44,7 @@ private Q_SLOTS:
|
|||
|
||||
void testRegistry();
|
||||
void testModeChanges();
|
||||
void testScaleChange_legacy();
|
||||
void testScaleChange();
|
||||
|
||||
void testSubPixel_data();
|
||||
|
@ -310,7 +311,7 @@ void TestWaylandOutputDevice::testModeChanges()
|
|||
QCOMPARE(output.pixelSize(), QSize(1280, 1024));
|
||||
}
|
||||
|
||||
void TestWaylandOutputDevice::testScaleChange()
|
||||
void TestWaylandOutputDevice::testScaleChange_legacy()
|
||||
{
|
||||
KWayland::Client::Registry registry;
|
||||
QSignalSpy interfacesAnnouncedSpy(®istry, &KWayland::Client::Registry::interfacesAnnounced);
|
||||
|
@ -336,12 +337,51 @@ void TestWaylandOutputDevice::testScaleChange()
|
|||
m_serverOutputDevice->setScale(2);
|
||||
QVERIFY(outputChanged.wait());
|
||||
QCOMPARE(output.scale(), 2);
|
||||
QCOMPARE(output.scaleF(), 2.0); //check we're forward compatiable
|
||||
|
||||
|
||||
// change once more
|
||||
outputChanged.clear();
|
||||
m_serverOutputDevice->setScale(4);
|
||||
QVERIFY(outputChanged.wait());
|
||||
QCOMPARE(output.scale(), 4);
|
||||
QCOMPARE(output.scaleF(), 4.0);
|
||||
}
|
||||
|
||||
void TestWaylandOutputDevice::testScaleChange()
|
||||
{
|
||||
KWayland::Client::Registry registry;
|
||||
QSignalSpy interfacesAnnouncedSpy(®istry, &KWayland::Client::Registry::interfacesAnnounced);
|
||||
QVERIFY(interfacesAnnouncedSpy.isValid());
|
||||
QSignalSpy announced(®istry, &KWayland::Client::Registry::outputDeviceAnnounced);
|
||||
registry.setEventQueue(m_queue);
|
||||
registry.create(m_connection->display());
|
||||
QVERIFY(registry.isValid());
|
||||
registry.setup();
|
||||
wl_display_flush(m_connection->display());
|
||||
QVERIFY(interfacesAnnouncedSpy.wait());
|
||||
|
||||
KWayland::Client::OutputDevice output;
|
||||
QSignalSpy outputChanged(&output, &KWayland::Client::OutputDevice::done);
|
||||
QVERIFY(outputChanged.isValid());
|
||||
output.setup(registry.bindOutputDevice(announced.first().first().value<quint32>(), announced.first().last().value<quint32>()));
|
||||
wl_display_flush(m_connection->display());
|
||||
QVERIFY(outputChanged.wait());
|
||||
QCOMPARE(output.scaleF(), 1.0);
|
||||
|
||||
// change the scale
|
||||
outputChanged.clear();
|
||||
m_serverOutputDevice->setScaleF(2.2);
|
||||
QVERIFY(outputChanged.wait());
|
||||
QCOMPARE(output.scale(), 2); //check backwards compatibility works
|
||||
QCOMPARE(wl_fixed_from_double(output.scaleF()), wl_fixed_from_double(2.2));
|
||||
|
||||
// change once more
|
||||
outputChanged.clear();
|
||||
m_serverOutputDevice->setScaleF(4.9);
|
||||
QVERIFY(outputChanged.wait());
|
||||
QCOMPARE(output.scale(), 5);
|
||||
QCOMPARE(wl_fixed_from_double(output.scaleF()), wl_fixed_from_double(4.9));
|
||||
}
|
||||
|
||||
void TestWaylandOutputDevice::testSubPixel_data()
|
||||
|
|
|
@ -60,6 +60,7 @@ private Q_SLOTS:
|
|||
void testFailed();
|
||||
|
||||
void testExampleConfig();
|
||||
void testScale();
|
||||
|
||||
void testRemoval();
|
||||
|
||||
|
@ -229,7 +230,7 @@ void TestWaylandOutputManagement::applyPendingChanges()
|
|||
outputdevice->setGlobalPosition(c->position());
|
||||
}
|
||||
if (c->scaleChanged()) {
|
||||
outputdevice->setScale(c->scale());
|
||||
outputdevice->setScaleF(c->scaleF());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -472,5 +473,34 @@ void TestWaylandOutputManagement::testExampleConfig()
|
|||
QVERIFY(configAppliedSpy.wait(200));
|
||||
}
|
||||
|
||||
void TestWaylandOutputManagement::testScale()
|
||||
{
|
||||
createConfig();
|
||||
|
||||
auto config = m_outputConfiguration;
|
||||
KWayland::Client::OutputDevice *output = m_clientOutputs.first();
|
||||
|
||||
config->setScaleF(output, 2.3);
|
||||
config->apply();
|
||||
|
||||
QSignalSpy configAppliedSpy(config, &OutputConfiguration::applied);
|
||||
m_outputConfigurationInterface->setApplied();
|
||||
QVERIFY(configAppliedSpy.isValid());
|
||||
QVERIFY(configAppliedSpy.wait(200));
|
||||
|
||||
QCOMPARE(output->scale(), 2); //test backwards compatibility
|
||||
QCOMPARE(wl_fixed_from_double(output->scaleF()), wl_fixed_from_double(2.3));
|
||||
|
||||
config->setScale(output, 3);
|
||||
config->apply();
|
||||
|
||||
m_outputConfigurationInterface->setApplied();
|
||||
QVERIFY(configAppliedSpy.isValid());
|
||||
QVERIFY(configAppliedSpy.wait(200));
|
||||
|
||||
QCOMPARE(output->scale(), 3);
|
||||
QCOMPARE(output->scaleF(), 3.0); //test fowards compatibility
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestWaylandOutputManagement)
|
||||
#include "test_wayland_outputmanagement.moc"
|
||||
|
|
|
@ -102,10 +102,16 @@ QPoint OutputChangeSet::position() const
|
|||
bool OutputChangeSet::scaleChanged() const
|
||||
{
|
||||
Q_D();
|
||||
return d->scale != d->o->scale();
|
||||
return !qFuzzyCompare(d->scale, d->o->scaleF());
|
||||
}
|
||||
|
||||
int OutputChangeSet::scale() const
|
||||
{
|
||||
Q_D();
|
||||
return qRound(d->scale);
|
||||
}
|
||||
|
||||
qreal OutputChangeSet::scaleF() const
|
||||
{
|
||||
Q_D();
|
||||
return d->scale;
|
||||
|
|
|
@ -78,8 +78,14 @@ public:
|
|||
OutputDeviceInterface::Transform transform() const;
|
||||
/** The new value for globalPosition. */
|
||||
QPoint position() const;
|
||||
/** The new value for scale. */
|
||||
/** The new value for scale.
|
||||
@deprecated see scaleF
|
||||
*/
|
||||
int scale() const;
|
||||
/** The new value for scale.
|
||||
* @since 5.XX
|
||||
*/
|
||||
qreal scaleF() const;
|
||||
|
||||
private:
|
||||
friend class OutputConfigurationInterface;
|
||||
|
|
|
@ -40,9 +40,9 @@ namespace KWayland
|
|||
int modeId;
|
||||
OutputDeviceInterface::Transform transform;
|
||||
QPoint position;
|
||||
int scale;
|
||||
qreal scale;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
OutputManagementInterface *outputManagement;
|
||||
QHash<OutputDeviceInterface*, OutputChangeSet*> changes;
|
||||
|
||||
static const quint32 s_version = 1;
|
||||
static const quint32 s_version = 2;
|
||||
|
||||
private:
|
||||
static void enableCallback(wl_client *client, wl_resource *resource,
|
||||
|
@ -69,6 +69,8 @@ private:
|
|||
static void scaleCallback(wl_client *client, wl_resource *resource,
|
||||
wl_resource * outputdevice, int32_t scale);
|
||||
static void applyCallback(wl_client *client, wl_resource *resource);
|
||||
static void scaleFCallback(wl_client *client, wl_resource *resource,
|
||||
wl_resource * outputdevice, wl_fixed_t scale);
|
||||
|
||||
OutputConfigurationInterface *q_func() {
|
||||
return reinterpret_cast<OutputConfigurationInterface *>(q);
|
||||
|
@ -83,7 +85,8 @@ const struct org_kde_kwin_outputconfiguration_interface OutputConfigurationInter
|
|||
transformCallback,
|
||||
positionCallback,
|
||||
scaleCallback,
|
||||
applyCallback
|
||||
applyCallback,
|
||||
scaleFCallback
|
||||
};
|
||||
|
||||
OutputConfigurationInterface::OutputConfigurationInterface(OutputManagementInterface* parent, wl_resource* parentResource): Resource(new Private(this, parent, parentResource))
|
||||
|
@ -185,6 +188,22 @@ void OutputConfigurationInterface::Private::scaleCallback(wl_client *client, wl_
|
|||
s->pendingChanges(o)->d_func()->scale = scale;
|
||||
}
|
||||
|
||||
void OutputConfigurationInterface::Private::scaleFCallback(wl_client *client, wl_resource *resource, wl_resource * outputdevice, wl_fixed_t scale_fixed)
|
||||
{
|
||||
Q_UNUSED(client);
|
||||
const qreal scale = wl_fixed_to_double(scale_fixed);
|
||||
|
||||
if (scale <= 0) {
|
||||
qCWarning(KWAYLAND_SERVER) << "Requested to scale output device to" << scale << ", but I can't do that.";
|
||||
return;
|
||||
}
|
||||
OutputDeviceInterface *o = OutputDeviceInterface::get(outputdevice);
|
||||
auto s = cast<Private>(resource);
|
||||
Q_ASSERT(s);
|
||||
|
||||
s->pendingChanges(o)->d_func()->scale = scale;
|
||||
}
|
||||
|
||||
void OutputConfigurationInterface::Private::applyCallback(wl_client *client, wl_resource *resource)
|
||||
{
|
||||
Q_UNUSED(client);
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
QPoint globalPosition;
|
||||
QString manufacturer = QStringLiteral("org.kde.kwin");
|
||||
QString model = QStringLiteral("none");
|
||||
int scale = 1;
|
||||
qreal scale = 1.0;
|
||||
SubPixel subPixel = SubPixel::Unknown;
|
||||
Transform transform = Transform::Normal;
|
||||
QList<Mode> modes;
|
||||
|
@ -80,7 +80,7 @@ private:
|
|||
static QVector<Private*> s_privates;
|
||||
};
|
||||
|
||||
const quint32 OutputDeviceInterface::Private::s_version = 1;
|
||||
const quint32 OutputDeviceInterface::Private::s_version = 2;
|
||||
|
||||
QVector<OutputDeviceInterface::Private*> OutputDeviceInterface::Private::s_privates;
|
||||
|
||||
|
@ -138,7 +138,7 @@ OutputDeviceInterface::OutputDeviceInterface(Display *display, QObject *parent)
|
|||
connect(this, &OutputDeviceInterface::globalPositionChanged, this, [this, d] { d->updateGeometry(); });
|
||||
connect(this, &OutputDeviceInterface::modelChanged, this, [this, d] { d->updateGeometry(); });
|
||||
connect(this, &OutputDeviceInterface::manufacturerChanged, this, [this, d] { d->updateGeometry(); });
|
||||
connect(this, &OutputDeviceInterface::scaleChanged, this, [this, d] { d->updateScale(); });
|
||||
connect(this, &OutputDeviceInterface::scaleFChanged, this, [this, d] { d->updateScale(); });
|
||||
}
|
||||
|
||||
OutputDeviceInterface::~OutputDeviceInterface() = default;
|
||||
|
@ -402,7 +402,11 @@ void OutputDeviceInterface::Private::sendGeometry(wl_resource *resource)
|
|||
|
||||
void OutputDeviceInterface::Private::sendScale(const ResourceData &data)
|
||||
{
|
||||
org_kde_kwin_outputdevice_send_scale(data.resource, scale);
|
||||
if (wl_resource_get_version(data.resource) < ORG_KDE_KWIN_OUTPUTDEVICE_SCALEF_SINCE_VERSION) {
|
||||
org_kde_kwin_outputdevice_send_scale(data.resource, qRound(scale));
|
||||
} else {
|
||||
org_kde_kwin_outputdevice_send_scalef(data.resource, wl_fixed_from_double(scale));
|
||||
}
|
||||
}
|
||||
|
||||
void OutputDeviceInterface::Private::sendDone(const ResourceData &data)
|
||||
|
@ -441,12 +445,33 @@ SETTER(setPhysicalSize, const QSize&, physicalSize)
|
|||
SETTER(setGlobalPosition, const QPoint&, globalPosition)
|
||||
SETTER(setManufacturer, const QString&, manufacturer)
|
||||
SETTER(setModel, const QString&, model)
|
||||
SETTER(setScale, int, scale)
|
||||
SETTER(setSubPixel, SubPixel, subPixel)
|
||||
SETTER(setTransform, Transform, transform)
|
||||
|
||||
#undef SETTER
|
||||
|
||||
void OutputDeviceInterface::setScale(int scale)
|
||||
{
|
||||
Q_D();
|
||||
if (d->scale == scale) {
|
||||
return;
|
||||
}
|
||||
d->scale = scale;
|
||||
emit scaleChanged(d->scale);
|
||||
emit scaleFChanged(d->scale);
|
||||
}
|
||||
|
||||
void OutputDeviceInterface::setScaleF(qreal scale)
|
||||
{
|
||||
Q_D();
|
||||
if (qFuzzyCompare(d->scale, scale)) {
|
||||
return;
|
||||
}
|
||||
d->scale = scale;
|
||||
emit scaleChanged(qRound(d->scale));
|
||||
emit scaleFChanged(d->scale);
|
||||
}
|
||||
|
||||
QSize OutputDeviceInterface::physicalSize() const
|
||||
{
|
||||
Q_D();
|
||||
|
@ -472,11 +497,18 @@ QString OutputDeviceInterface::model() const
|
|||
}
|
||||
|
||||
int OutputDeviceInterface::scale() const
|
||||
{
|
||||
Q_D();
|
||||
return qRound(d->scale);
|
||||
}
|
||||
|
||||
qreal OutputDeviceInterface::scaleF() const
|
||||
{
|
||||
Q_D();
|
||||
return d->scale;
|
||||
}
|
||||
|
||||
|
||||
OutputDeviceInterface::SubPixel OutputDeviceInterface::subPixel() const
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -53,7 +53,7 @@ class KWAYLANDSERVER_EXPORT OutputDeviceInterface : public Global
|
|||
Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
|
||||
Q_PROPERTY(QSize pixelSize READ pixelSize NOTIFY pixelSizeChanged)
|
||||
Q_PROPERTY(int refreshRate READ refreshRate NOTIFY refreshRateChanged)
|
||||
Q_PROPERTY(int scale READ scale WRITE setScale NOTIFY scaleChanged)
|
||||
Q_PROPERTY(qreal scale READ scaleF WRITE setScaleF NOTIFY scaleFChanged)
|
||||
Q_PROPERTY(QByteArray edid READ edid WRITE setEdid NOTIFY edidChanged)
|
||||
Q_PROPERTY(OutputDeviceInterface::Enablement enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(QByteArray uuid READ uuid WRITE setUuid NOTIFY uuidChanged)
|
||||
|
@ -100,6 +100,7 @@ public:
|
|||
QSize pixelSize() const;
|
||||
int refreshRate() const;
|
||||
int scale() const;
|
||||
qreal scaleF() const;
|
||||
SubPixel subPixel() const;
|
||||
Transform transform() const;
|
||||
QList<Mode> modes() const;
|
||||
|
@ -114,6 +115,7 @@ public:
|
|||
void setManufacturer(const QString &manufacturer);
|
||||
void setModel(const QString &model);
|
||||
void setScale(int scale);
|
||||
void setScaleF(qreal scale);
|
||||
void setSubPixel(SubPixel subPixel);
|
||||
void setTransform(Transform transform);
|
||||
void addMode(Mode &mode);
|
||||
|
@ -133,7 +135,9 @@ Q_SIGNALS:
|
|||
void modelChanged(const QString&);
|
||||
void pixelSizeChanged(const QSize&);
|
||||
void refreshRateChanged(int);
|
||||
//@deprecated see scaleChanged(real)
|
||||
void scaleChanged(int);
|
||||
void scaleFChanged(qreal);
|
||||
void subPixelChanged(SubPixel);
|
||||
void transformChanged(Transform);
|
||||
void modesChanged();
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
QHash<wl_resource*, OutputConfigurationInterface*> configurationInterfaces;
|
||||
};
|
||||
|
||||
const quint32 OutputManagementInterface::Private::s_version = 1;
|
||||
const quint32 OutputManagementInterface::Private::s_version = 2;
|
||||
|
||||
const struct org_kde_kwin_outputmanagement_interface OutputManagementInterface::Private::s_interface = {
|
||||
createConfigurationCallback
|
||||
|
|
Loading…
Reference in a new issue