Implement wp-fractional-scale-v1
This allows clients to provide buffers at native resolutions when fractional scaling is used. Virtual backend is adjusted to support scales as floatsmaster
parent
361828dfbe
commit
c4b134da8d
@ -0,0 +1,103 @@
|
||||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2022 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "kwin_wayland_test.h"
|
||||
|
||||
#include "core/output.h"
|
||||
#include "core/outputbackend.h"
|
||||
#include "wayland/clientconnection.h"
|
||||
#include "wayland/display.h"
|
||||
#include "wayland_server.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <KWayland/Client/compositor.h>
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/output.h>
|
||||
#include <KWayland/Client/server_decoration.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
#include <QDBusConnection>
|
||||
|
||||
// system
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <csignal>
|
||||
|
||||
using namespace KWin;
|
||||
|
||||
static const QString s_socketName = QStringLiteral("wayland_test_kwin_fractionalScale-0");
|
||||
|
||||
class TestFractionalScale : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void testShow();
|
||||
};
|
||||
|
||||
void TestFractionalScale::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<KWin::Window *>();
|
||||
qRegisterMetaType<KWayland::Client::Output *>();
|
||||
|
||||
QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
|
||||
QVERIFY(waylandServer()->init(s_socketName));
|
||||
QMetaObject::invokeMethod(kwinApp()->outputBackend(),
|
||||
"setVirtualOutputs",
|
||||
Qt::DirectConnection,
|
||||
Q_ARG(QVector<QRect>, QVector<QRect>() << QRect(0, 0, 1280, 1024) << QRect(1280, 0, 1280, 1024)),
|
||||
Q_ARG(QVector<qreal>, QVector<qreal>() << 1.25 << 2.0));
|
||||
|
||||
kwinApp()->start();
|
||||
QVERIFY(applicationStartedSpy.wait());
|
||||
const auto outputs = workspace()->outputs();
|
||||
QCOMPARE(outputs.count(), 2);
|
||||
QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1024, 819));
|
||||
QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 640, 512));
|
||||
QCOMPARE(outputs[0]->scale(), 1.25);
|
||||
QCOMPARE(outputs[1]->scale(), 2.0);
|
||||
}
|
||||
|
||||
void TestFractionalScale::init()
|
||||
{
|
||||
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::FractionalScaleManagerV1));
|
||||
|
||||
workspace()->setActiveOutput(QPoint(640, 512));
|
||||
// put mouse in the middle of screen one
|
||||
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
|
||||
}
|
||||
|
||||
void TestFractionalScale::cleanup()
|
||||
{
|
||||
Test::destroyWaylandConnection();
|
||||
}
|
||||
|
||||
void TestFractionalScale::testShow()
|
||||
{
|
||||
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
||||
std::unique_ptr<Test::FractionalScaleV1> fractionalScale(Test::createFractionalScaleV1(surface.get()));
|
||||
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
|
||||
|
||||
// above call commits the surface and blocks for the configure event. We should have received the scale already
|
||||
// We are sent the value in 120ths
|
||||
QCOMPARE(fractionalScale->preferredScale(), 1.25 * 120);
|
||||
|
||||
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
||||
QVERIFY(window);
|
||||
|
||||
QCOMPARE(fractionalScale->preferredScale(), 1.25 * 120);
|
||||
}
|
||||
|
||||
WAYLANDTEST_MAIN(TestFractionalScale)
|
||||
#include "fractional_scaling_test.moc"
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2022 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include "fractionalscale_v1_interface.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "fractionalscale_v1_interface_p.h"
|
||||
#include "surface_interface_p.h"
|
||||
|
||||
static const int s_version = 1;
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class FractionalScaleManagerV1InterfacePrivate : public QtWaylandServer::wp_fractional_scale_manager_v1
|
||||
{
|
||||
protected:
|
||||
void wp_fractional_scale_manager_v1_destroy(Resource *resource) override;
|
||||
void wp_fractional_scale_manager_v1_get_fractional_scale(Resource *resource, uint32_t id, wl_resource *surface) override;
|
||||
};
|
||||
|
||||
void FractionalScaleManagerV1InterfacePrivate::wp_fractional_scale_manager_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void FractionalScaleManagerV1InterfacePrivate::wp_fractional_scale_manager_v1_get_fractional_scale(Resource *resource, uint32_t id, struct ::wl_resource *surface_resource)
|
||||
{
|
||||
SurfaceInterface *surface = SurfaceInterface::get(surface_resource);
|
||||
|
||||
FractionalScaleV1Interface *scaleIface = FractionalScaleV1Interface::get(surface);
|
||||
if (scaleIface) {
|
||||
wl_resource_post_error(resource->handle, error_fractional_scale_exists, "the specified surface already has a fractional scale");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource *surfaceScalerResource = wl_resource_create(resource->client(), &wp_fractional_scale_v1_interface, resource->version(), id);
|
||||
|
||||
new FractionalScaleV1Interface(surface, surfaceScalerResource);
|
||||
}
|
||||
|
||||
FractionalScaleV1Interface::FractionalScaleV1Interface(SurfaceInterface *surface, wl_resource *resource)
|
||||
: QtWaylandServer::wp_fractional_scale_v1(resource)
|
||||
, surface(surface)
|
||||
{
|
||||
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface);
|
||||
surfacePrivate->fractionalScaleExtension = this;
|
||||
setPreferredScale(surfacePrivate->preferredScale);
|
||||
}
|
||||
|
||||
FractionalScaleV1Interface::~FractionalScaleV1Interface()
|
||||
{
|
||||
if (surface) {
|
||||
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface);
|
||||
surfacePrivate->fractionalScaleExtension = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FractionalScaleV1Interface *FractionalScaleV1Interface::get(SurfaceInterface *surface)
|
||||
{
|
||||
return SurfaceInterfacePrivate::get(surface)->fractionalScaleExtension;
|
||||
}
|
||||
|
||||
void FractionalScaleV1Interface::setPreferredScale(qreal scale)
|
||||
{
|
||||
send_preferred_scale(std::round(scale * 120));
|
||||
}
|
||||
|
||||
void FractionalScaleV1Interface::wp_fractional_scale_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void FractionalScaleV1Interface::wp_fractional_scale_v1_destroy_resource(Resource *)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
FractionalScaleManagerV1Interface::FractionalScaleManagerV1Interface(Display *display, QObject *parent)
|
||||
: QObject(parent)
|
||||
, d(new FractionalScaleManagerV1InterfacePrivate)
|
||||
{
|
||||
d->init(*display, s_version);
|
||||
}
|
||||
|
||||
FractionalScaleManagerV1Interface::~FractionalScaleManagerV1Interface()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2022 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kwin_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class Display;
|
||||
class FractionalScaleManagerV1InterfacePrivate;
|
||||
|
||||
class KWIN_EXPORT FractionalScaleManagerV1Interface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FractionalScaleManagerV1Interface(Display *display, QObject *parent = nullptr);
|
||||
~FractionalScaleManagerV1Interface() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<FractionalScaleManagerV1InterfacePrivate> d;
|
||||
};
|
||||
|
||||
} // namespace KWaylandServer
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2022 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qwayland-server-fractional-scale-v1.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class SurfaceInterface;
|
||||
|
||||
class FractionalScaleV1Interface : protected QtWaylandServer::wp_fractional_scale_v1
|
||||
{
|
||||
public:
|
||||
FractionalScaleV1Interface(SurfaceInterface *surface, wl_resource *resource);
|
||||
~FractionalScaleV1Interface() override;
|
||||
|
||||
static FractionalScaleV1Interface *get(SurfaceInterface *surface);
|
||||
|
||||
void setPreferredScale(qreal scale);
|
||||
QPointer<SurfaceInterface> surface;
|
||||
|
||||
protected:
|
||||
void wp_fractional_scale_v1_destroy(Resource *resource) override;
|
||||
void wp_fractional_scale_v1_destroy_resource(Resource *resource) override;
|
||||
};
|
||||
|
||||
} // namespace KWaylandServer
|
Loading…
Reference in New Issue