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 floats
This commit is contained in:
parent
361828dfbe
commit
c4b134da8d
19 changed files with 380 additions and 18 deletions
|
@ -196,7 +196,7 @@ set_package_properties(Wayland PROPERTIES
|
|||
PURPOSE "Required for building KWin with Wayland support"
|
||||
)
|
||||
|
||||
find_package(WaylandProtocols 1.30)
|
||||
find_package(WaylandProtocols 1.31)
|
||||
set_package_properties(WaylandProtocols PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Collection of Wayland protocols that add functionality not available in the Wayland core protocol"
|
||||
|
|
|
@ -34,6 +34,10 @@ if (QT_MAJOR_VERSION EQUAL "5")
|
|||
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-management-v2.xml
|
||||
BASENAME kde-output-management-v2
|
||||
)
|
||||
ecm_add_qtwayland_client_protocol(KWinIntegrationTestFramework
|
||||
PROTOCOL ${WaylandProtocols_DATADIR}/staging/fractional-scale/fractional-scale-v1.xml
|
||||
BASENAME fractional-scale-v1
|
||||
)
|
||||
else()
|
||||
qt6_generate_wayland_protocol_client_sources(KWinIntegrationTestFramework
|
||||
NO_INCLUDE_CORE_ONLY
|
||||
|
@ -47,6 +51,7 @@ else()
|
|||
${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
|
||||
${WaylandProtocols_DATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
||||
${WaylandProtocols_DATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml
|
||||
${WaylandProtocols_DATADIR}/staging/fractional-scale/fractional-scale-v1.xml
|
||||
${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-device-v2.xml
|
||||
${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-management-v2.xml
|
||||
)
|
||||
|
@ -142,6 +147,7 @@ integrationTest(WAYLAND_ONLY NAME testScreens SRCS screens_test.cpp)
|
|||
integrationTest(WAYLAND_ONLY NAME testScreenEdges SRCS screenedges_test.cpp)
|
||||
integrationTest(WAYLAND_ONLY NAME testOutputChanges SRCS outputchanges_test.cpp)
|
||||
integrationTest(WAYLAND_ONLY NAME testTiles SRCS tiles_test.cpp)
|
||||
integrationTest(WAYLAND_ONLY NAME testFractionalScaling SRCS fractional_scaling_test.cpp)
|
||||
|
||||
qt_add_dbus_interfaces(DBUS_SRCS ${CMAKE_BINARY_DIR}/src/org.kde.kwin.VirtualKeyboard.xml)
|
||||
integrationTest(WAYLAND_ONLY NAME testVirtualKeyboardDBus SRCS test_virtualkeyboard_dbus.cpp ${DBUS_SRCS})
|
||||
|
|
|
@ -515,16 +515,10 @@ void ActivationTest::stackScreensHorizontally()
|
|||
QRect(1280, 0, 1280, 1024),
|
||||
};
|
||||
|
||||
const QVector<int> screenScales{
|
||||
1,
|
||||
1,
|
||||
};
|
||||
|
||||
QMetaObject::invokeMethod(kwinApp()->outputBackend(),
|
||||
"setVirtualOutputs",
|
||||
Qt::DirectConnection,
|
||||
Q_ARG(QVector<QRect>, screenGeometries),
|
||||
Q_ARG(QVector<int>, screenScales));
|
||||
Q_ARG(QVector<QRect>, screenGeometries));
|
||||
}
|
||||
|
||||
void ActivationTest::stackScreensVertically()
|
||||
|
@ -537,16 +531,10 @@ void ActivationTest::stackScreensVertically()
|
|||
QRect(0, 1024, 1280, 1024),
|
||||
};
|
||||
|
||||
const QVector<int> screenScales{
|
||||
1,
|
||||
1,
|
||||
};
|
||||
|
||||
QMetaObject::invokeMethod(kwinApp()->outputBackend(),
|
||||
"setVirtualOutputs",
|
||||
Qt::DirectConnection,
|
||||
Q_ARG(QVector<QRect>, screenGeometries),
|
||||
Q_ARG(QVector<int>, screenScales));
|
||||
Q_ARG(QVector<QRect>, screenGeometries));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
103
autotests/integration/fractional_scaling_test.cpp
Normal file
103
autotests/integration/fractional_scaling_test.cpp
Normal file
|
@ -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"
|
|
@ -638,7 +638,7 @@ void InternalWindowTest::testScale()
|
|||
{
|
||||
QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection,
|
||||
Q_ARG(QVector<QRect>, QVector<QRect>({QRect(0, 0, 1280, 1024), QRect(1280 / 2, 0, 1280, 1024)})),
|
||||
Q_ARG(QVector<int>, QVector<int>({2, 2})));
|
||||
Q_ARG(QVector<qreal>, QVector<qreal>({2, 2})));
|
||||
|
||||
QSignalSpy windowAddedSpy(workspace(), &Workspace::internalWindowAdded);
|
||||
HelperWindow win;
|
||||
|
|
|
@ -196,4 +196,24 @@ XwaylandInterface *WaylandTestApplication::xwayland() const
|
|||
{
|
||||
return m_xwayland.get();
|
||||
}
|
||||
|
||||
Test::FractionalScaleManagerV1::~FractionalScaleManagerV1()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
Test::FractionalScaleV1::~FractionalScaleV1()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
int Test::FractionalScaleV1::preferredScale()
|
||||
{
|
||||
return m_preferredScale;
|
||||
}
|
||||
|
||||
void Test::FractionalScaleV1::wp_fractional_scale_v1_preferred_scale(uint32_t scale)
|
||||
{
|
||||
m_preferredScale = scale;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
#include "qwayland-fractional-scale-v1.h"
|
||||
#include "qwayland-idle-inhibit-unstable-v1.h"
|
||||
#include "qwayland-input-method-unstable-v1.h"
|
||||
#include "qwayland-kde-output-device-v2.h"
|
||||
|
@ -460,6 +461,27 @@ private:
|
|||
struct ::zwp_input_method_context_v1 *m_context = nullptr;
|
||||
};
|
||||
|
||||
class FractionalScaleManagerV1 : public QObject, public QtWayland::wp_fractional_scale_manager_v1
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~FractionalScaleManagerV1() override;
|
||||
};
|
||||
|
||||
class FractionalScaleV1 : public QObject, public QtWayland::wp_fractional_scale_v1
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~FractionalScaleV1() override;
|
||||
int preferredScale();
|
||||
|
||||
protected:
|
||||
void wp_fractional_scale_v1_preferred_scale(uint32_t scale) override;
|
||||
|
||||
private:
|
||||
int m_preferredScale = 120;
|
||||
};
|
||||
|
||||
enum class AdditionalWaylandInterface {
|
||||
Seat = 1 << 0,
|
||||
Decoration = 1 << 1,
|
||||
|
@ -476,6 +498,7 @@ enum class AdditionalWaylandInterface {
|
|||
LayerShellV1 = 1 << 12,
|
||||
TextInputManagerV3 = 1 << 13,
|
||||
OutputDeviceV2 = 1 << 14,
|
||||
FractionalScaleManagerV1 = 1 << 15,
|
||||
};
|
||||
Q_DECLARE_FLAGS(AdditionalWaylandInterfaces, AdditionalWaylandInterface)
|
||||
|
||||
|
@ -595,6 +618,8 @@ enum class CreationSetup {
|
|||
QtWayland::zwp_input_panel_surface_v1 *createInputPanelSurfaceV1(KWayland::Client::Surface *surface,
|
||||
KWayland::Client::Output *output);
|
||||
|
||||
FractionalScaleV1 *createFractionalScaleV1(KWayland::Client::Surface *surface);
|
||||
|
||||
XdgToplevel *createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent = nullptr);
|
||||
XdgToplevel *createXdgToplevelSurface(KWayland::Client::Surface *surface,
|
||||
CreationSetup configureMode,
|
||||
|
|
|
@ -251,6 +251,7 @@ static struct
|
|||
QtWayland::zwp_input_method_context_v1 *inputMethodContextV1 = nullptr;
|
||||
LayerShellV1 *layerShellV1 = nullptr;
|
||||
TextInputManagerV3 *textInputManagerV3 = nullptr;
|
||||
FractionalScaleManagerV1 *fractionalScaleManagerV1 = nullptr;
|
||||
} s_waylandConnection;
|
||||
|
||||
MockInputMethod *inputMethod()
|
||||
|
@ -415,6 +416,13 @@ bool setupWaylandConnection(AdditionalWaylandInterfaces flags)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (flags & AdditionalWaylandInterface::FractionalScaleManagerV1) {
|
||||
if (interface == wp_fractional_scale_manager_v1_interface.name) {
|
||||
s_waylandConnection.fractionalScaleManagerV1 = new FractionalScaleManagerV1();
|
||||
s_waylandConnection.fractionalScaleManagerV1->init(*registry, name, version);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
QSignalSpy allAnnounced(registry, &KWayland::Client::Registry::interfacesAnnounced);
|
||||
|
@ -539,6 +547,8 @@ void destroyWaylandConnection()
|
|||
s_waylandConnection.layerShellV1 = nullptr;
|
||||
delete s_waylandConnection.outputManagementV2;
|
||||
s_waylandConnection.outputManagementV2 = nullptr;
|
||||
delete s_waylandConnection.fractionalScaleManagerV1;
|
||||
s_waylandConnection.fractionalScaleManagerV1 = nullptr;
|
||||
|
||||
delete s_waylandConnection.queue; // Must be destroyed last
|
||||
s_waylandConnection.queue = nullptr;
|
||||
|
@ -796,6 +806,18 @@ QtWayland::zwp_input_panel_surface_v1 *createInputPanelSurfaceV1(KWayland::Clien
|
|||
return s;
|
||||
}
|
||||
|
||||
FractionalScaleV1 *createFractionalScaleV1(KWayland::Client::Surface *surface)
|
||||
{
|
||||
if (!s_waylandConnection.fractionalScaleManagerV1) {
|
||||
qWarning() << "Unable to create fractional scale surface. The global is not bound";
|
||||
return nullptr;
|
||||
}
|
||||
auto scale = new FractionalScaleV1();
|
||||
scale->init(s_waylandConnection.fractionalScaleManagerV1->get_fractional_scale(*surface));
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
static void waitForConfigured(XdgSurface *shellSurface)
|
||||
{
|
||||
QSignalSpy surfaceConfigureRequestedSpy(shellSurface, &XdgSurface::configureRequested);
|
||||
|
|
|
@ -83,7 +83,7 @@ Output *VirtualBackend::addOutput(const QSize &size, qreal scale)
|
|||
return output;
|
||||
}
|
||||
|
||||
void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector<int> scales)
|
||||
void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector<qreal> scales)
|
||||
{
|
||||
Q_ASSERT(scales.size() == 0 || scales.size() == geometries.size());
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
std::unique_ptr<OpenGLBackend> createOpenGLBackend() override;
|
||||
|
||||
Output *addOutput(const QSize &size, qreal scale);
|
||||
Q_INVOKABLE void setVirtualOutputs(const QVector<QRect> &geometries, QVector<int> scales = QVector<int>());
|
||||
|
||||
Q_INVOKABLE void setVirtualOutputs(const QVector<QRect> &geometries, QVector<qreal> scales = QVector<qreal>());
|
||||
|
||||
Outputs outputs() const override;
|
||||
|
||||
|
|
|
@ -201,6 +201,11 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
|||
BASENAME xwayland-shell-v1
|
||||
)
|
||||
|
||||
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
||||
PROTOCOL ${WaylandProtocols_DATADIR}/staging/fractional-scale/fractional-scale-v1.xml
|
||||
BASENAME fractional-scale-v1
|
||||
)
|
||||
|
||||
target_sources(kwin PRIVATE
|
||||
abstract_data_source.cpp
|
||||
abstract_drop_handler.cpp
|
||||
|
@ -225,6 +230,7 @@ target_sources(kwin PRIVATE
|
|||
drmclientbuffer.cpp
|
||||
drmlease_v1_interface.cpp
|
||||
fakeinput_interface.cpp
|
||||
fractionalscale_v1_interface.cpp
|
||||
filtered_display.cpp
|
||||
idle_interface.cpp
|
||||
idleinhibit_v1_interface.cpp
|
||||
|
|
92
src/wayland/fractionalscale_v1_interface.cpp
Normal file
92
src/wayland/fractionalscale_v1_interface.cpp
Normal file
|
@ -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
|
31
src/wayland/fractionalscale_v1_interface.h
Normal file
31
src/wayland/fractionalscale_v1_interface.h
Normal file
|
@ -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
|
33
src/wayland/fractionalscale_v1_interface_p.h
Normal file
33
src/wayland/fractionalscale_v1_interface_p.h
Normal file
|
@ -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
|
|
@ -10,6 +10,7 @@
|
|||
#include "compositor_interface.h"
|
||||
#include "contenttype_v1_interface.h"
|
||||
#include "display.h"
|
||||
#include "fractionalscale_v1_interface_p.h"
|
||||
#include "idleinhibit_v1_interface_p.h"
|
||||
#include "linuxdmabufv1clientbuffer.h"
|
||||
#include "pointerconstraints_v1_interface_p.h"
|
||||
|
@ -72,6 +73,8 @@ void SurfaceInterfacePrivate::addChild(SubSurfaceInterface *child)
|
|||
cached.above.append(child);
|
||||
current.above.append(child);
|
||||
child->surface()->setOutputs(outputs);
|
||||
child->surface()->setPreferredScale(preferredScale);
|
||||
|
||||
Q_EMIT q->childSubSurfaceAdded(child);
|
||||
Q_EMIT q->childSubSurfacesChanged();
|
||||
}
|
||||
|
@ -1106,4 +1109,22 @@ PresentationHint SurfaceInterface::presentationHint() const
|
|||
return d->current.presentationHint;
|
||||
}
|
||||
|
||||
void SurfaceInterface::setPreferredScale(qreal scale)
|
||||
{
|
||||
if (scale == d->preferredScale) {
|
||||
return;
|
||||
}
|
||||
d->preferredScale = scale;
|
||||
|
||||
if (d->fractionalScaleExtension) {
|
||||
d->fractionalScaleExtension->setPreferredScale(scale);
|
||||
}
|
||||
for (auto child : qAsConst(d->current.below)) {
|
||||
child->surface()->setPreferredScale(scale);
|
||||
}
|
||||
for (auto child : qAsConst(d->current.above)) {
|
||||
child->surface()->setPreferredScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -346,6 +346,12 @@ public:
|
|||
*/
|
||||
PresentationHint presentationHint() const;
|
||||
|
||||
/**
|
||||
* Sets a preferred scale that clients should provide buffers in
|
||||
* @param scale
|
||||
*/
|
||||
void setPreferredScale(qreal scale);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when the underlying wl_surface resource is about to be freed.
|
||||
|
|
|
@ -21,6 +21,7 @@ class SurfaceRole;
|
|||
class ViewportInterface;
|
||||
class ContentTypeV1Interface;
|
||||
class TearingControlV1Interface;
|
||||
class FractionalScaleV1Interface;
|
||||
|
||||
struct SurfaceState
|
||||
{
|
||||
|
@ -131,6 +132,7 @@ public:
|
|||
qreal pendingScaleOverride = 1.;
|
||||
|
||||
QVector<OutputInterface *> outputs;
|
||||
qreal preferredScale = 1.0;
|
||||
|
||||
LockedPointerV1Interface *lockedPointer = nullptr;
|
||||
ConfinedPointerV1Interface *confinedPointer = nullptr;
|
||||
|
@ -141,6 +143,7 @@ public:
|
|||
ViewportInterface *viewportExtension = nullptr;
|
||||
std::unique_ptr<LinuxDmaBufV1Feedback> dmabufFeedbackV1;
|
||||
QPointer<ContentTypeV1Interface> contentTypeInterface;
|
||||
FractionalScaleV1Interface *fractionalScaleExtension = nullptr;
|
||||
ClientConnection *client = nullptr;
|
||||
TearingControlV1Interface *tearing = nullptr;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "wayland/dpms_interface.h"
|
||||
#include "wayland/drmlease_v1_interface.h"
|
||||
#include "wayland/filtered_display.h"
|
||||
#include "wayland/fractionalscale_v1_interface.h"
|
||||
#include "wayland/idle_interface.h"
|
||||
#include "wayland/idleinhibit_v1_interface.h"
|
||||
#include "wayland/idlenotify_v1_interface.h"
|
||||
|
@ -408,6 +409,7 @@ bool WaylandServer::init(InitializationFlags flags)
|
|||
});
|
||||
|
||||
new ViewporterInterface(m_display, m_display);
|
||||
new FractionalScaleManagerV1Interface(m_display, m_display);
|
||||
m_display->createShm();
|
||||
m_seat = new SeatInterface(m_display, m_display);
|
||||
new PointerGesturesV1Interface(m_display, m_display);
|
||||
|
|
|
@ -159,6 +159,9 @@ bool WaylandWindow::belongsToDesktop() const
|
|||
void WaylandWindow::updateClientOutputs()
|
||||
{
|
||||
surface()->setOutputs(waylandServer()->display()->outputsIntersecting(frameGeometry().toAlignedRect()));
|
||||
if (output()) {
|
||||
surface()->setPreferredScale(output()->scale());
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandWindow::updateIcon()
|
||||
|
|
Loading…
Reference in a new issue