diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e54f0b90d..48ab676e7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" diff --git a/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt index b4c45b9f03..96d0baa652 100644 --- a/autotests/integration/CMakeLists.txt +++ b/autotests/integration/CMakeLists.txt @@ -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}) diff --git a/autotests/integration/activation_test.cpp b/autotests/integration/activation_test.cpp index e61ad435df..9c1e78d39c 100644 --- a/autotests/integration/activation_test.cpp +++ b/autotests/integration/activation_test.cpp @@ -515,16 +515,10 @@ void ActivationTest::stackScreensHorizontally() QRect(1280, 0, 1280, 1024), }; - const QVector screenScales{ - 1, - 1, - }; - QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, - Q_ARG(QVector, screenGeometries), - Q_ARG(QVector, screenScales)); + Q_ARG(QVector, screenGeometries)); } void ActivationTest::stackScreensVertically() @@ -537,16 +531,10 @@ void ActivationTest::stackScreensVertically() QRect(0, 1024, 1280, 1024), }; - const QVector screenScales{ - 1, - 1, - }; - QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, - Q_ARG(QVector, screenGeometries), - Q_ARG(QVector, screenScales)); + Q_ARG(QVector, screenGeometries)); } } diff --git a/autotests/integration/fractional_scaling_test.cpp b/autotests/integration/fractional_scaling_test.cpp new file mode 100644 index 0000000000..9d153da537 --- /dev/null +++ b/autotests/integration/fractional_scaling_test.cpp @@ -0,0 +1,103 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2022 David Edmundson + + 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 +#include +#include +#include +#include + +#include + +// system +#include +#include +#include + +#include + +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(); + qRegisterMetaType(); + + QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); + QVERIFY(waylandServer()->init(s_socketName)); + QMetaObject::invokeMethod(kwinApp()->outputBackend(), + "setVirtualOutputs", + Qt::DirectConnection, + Q_ARG(QVector, QVector() << QRect(0, 0, 1280, 1024) << QRect(1280, 0, 1280, 1024)), + Q_ARG(QVector, QVector() << 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 surface(Test::createSurface()); + std::unique_ptr fractionalScale(Test::createFractionalScaleV1(surface.get())); + std::unique_ptr 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" diff --git a/autotests/integration/internal_window.cpp b/autotests/integration/internal_window.cpp index 7e013a717d..fb4544d3b2 100644 --- a/autotests/integration/internal_window.cpp +++ b/autotests/integration/internal_window.cpp @@ -638,7 +638,7 @@ void InternalWindowTest::testScale() { QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(QVector, QVector({QRect(0, 0, 1280, 1024), QRect(1280 / 2, 0, 1280, 1024)})), - Q_ARG(QVector, QVector({2, 2}))); + Q_ARG(QVector, QVector({2, 2}))); QSignalSpy windowAddedSpy(workspace(), &Workspace::internalWindowAdded); HelperWindow win; diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp index e4be72498f..0695070f5c 100644 --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -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; +} } diff --git a/autotests/integration/kwin_wayland_test.h b/autotests/integration/kwin_wayland_test.h index 8486748421..40468c26dd 100644 --- a/autotests/integration/kwin_wayland_test.h +++ b/autotests/integration/kwin_wayland_test.h @@ -18,6 +18,7 @@ #include +#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, diff --git a/autotests/integration/test_helpers.cpp b/autotests/integration/test_helpers.cpp index a16a562228..c98ce38fc1 100644 --- a/autotests/integration/test_helpers.cpp +++ b/autotests/integration/test_helpers.cpp @@ -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); diff --git a/src/backends/virtual/virtual_backend.cpp b/src/backends/virtual/virtual_backend.cpp index fec9fa2bdb..d0757e9bf8 100644 --- a/src/backends/virtual/virtual_backend.cpp +++ b/src/backends/virtual/virtual_backend.cpp @@ -83,7 +83,7 @@ Output *VirtualBackend::addOutput(const QSize &size, qreal scale) return output; } -void VirtualBackend::setVirtualOutputs(const QVector &geometries, QVector scales) +void VirtualBackend::setVirtualOutputs(const QVector &geometries, QVector scales) { Q_ASSERT(scales.size() == 0 || scales.size() == geometries.size()); diff --git a/src/backends/virtual/virtual_backend.h b/src/backends/virtual/virtual_backend.h index 24c2472a71..c62ddaf3da 100644 --- a/src/backends/virtual/virtual_backend.h +++ b/src/backends/virtual/virtual_backend.h @@ -42,7 +42,8 @@ public: std::unique_ptr createOpenGLBackend() override; Output *addOutput(const QSize &size, qreal scale); - Q_INVOKABLE void setVirtualOutputs(const QVector &geometries, QVector scales = QVector()); + + Q_INVOKABLE void setVirtualOutputs(const QVector &geometries, QVector scales = QVector()); Outputs outputs() const override; diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index e0781bc2e6..193e74d705 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -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 diff --git a/src/wayland/fractionalscale_v1_interface.cpp b/src/wayland/fractionalscale_v1_interface.cpp new file mode 100644 index 0000000000..ca4dbe1e12 --- /dev/null +++ b/src/wayland/fractionalscale_v1_interface.cpp @@ -0,0 +1,92 @@ +/* + SPDX-FileCopyrightText: 2022 David Edmundson + + 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 diff --git a/src/wayland/fractionalscale_v1_interface.h b/src/wayland/fractionalscale_v1_interface.h new file mode 100644 index 0000000000..ca60b0bf41 --- /dev/null +++ b/src/wayland/fractionalscale_v1_interface.h @@ -0,0 +1,31 @@ +/* + SPDX-FileCopyrightText: 2022 David Edmundson + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#pragma once + +#include "kwin_export.h" + +#include +#include + +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 d; +}; + +} // namespace KWaylandServer diff --git a/src/wayland/fractionalscale_v1_interface_p.h b/src/wayland/fractionalscale_v1_interface_p.h new file mode 100644 index 0000000000..69c1545146 --- /dev/null +++ b/src/wayland/fractionalscale_v1_interface_p.h @@ -0,0 +1,33 @@ +/* + SPDX-FileCopyrightText: 2022 David Edmundson + + 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 + +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 surface; + +protected: + void wp_fractional_scale_v1_destroy(Resource *resource) override; + void wp_fractional_scale_v1_destroy_resource(Resource *resource) override; +}; + +} // namespace KWaylandServer diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 45949ef6b2..7ed37cbea2 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -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 diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index 3d051a1510..584a1bd366 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -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. diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index b4bf52c8ca..c1a6a0e704 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -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 outputs; + qreal preferredScale = 1.0; LockedPointerV1Interface *lockedPointer = nullptr; ConfinedPointerV1Interface *confinedPointer = nullptr; @@ -141,6 +143,7 @@ public: ViewportInterface *viewportExtension = nullptr; std::unique_ptr dmabufFeedbackV1; QPointer contentTypeInterface; + FractionalScaleV1Interface *fractionalScaleExtension = nullptr; ClientConnection *client = nullptr; TearingControlV1Interface *tearing = nullptr; diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index d03f2e86d6..95b4827aa3 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -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); diff --git a/src/waylandwindow.cpp b/src/waylandwindow.cpp index 42dc13148b..844f96d5c1 100644 --- a/src/waylandwindow.cpp +++ b/src/waylandwindow.cpp @@ -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()