From 0fa58f189b442811b080ccff62dad8f9654b44f2 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 17 Oct 2024 04:15:07 -0700 Subject: [PATCH] core: fix reported display resolutions when fractionally scaled (#10) Qt appears to have no way to retrieve the pixel size sent by wayland, as it overrides it with the logical size and will not return the physical one. --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 5 +++- src/SystemInfo.cpp | 6 ++--- src/WaylandScreen.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++ src/WaylandScreen.hpp | 14 ++++++++++ 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 src/WaylandScreen.cpp create mode 100644 src/WaylandScreen.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d8fd6bd..f0cf66f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ project(hsi VERSION ${VER} LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets Quick QuickControls2) +find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets Quick QuickControls2 WaylandClient) find_package(PkgConfig REQUIRED) pkg_check_modules(hyprutils REQUIRED IMPORTED_TARGET hyprutils) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 064efef..925308d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ qt_add_executable(hyprsysteminfo util/Utils.cpp SystemInfo.cpp SystemIconProvider.cpp + WaylandScreen.cpp ) qt_add_qml_module(hyprsysteminfo @@ -11,4 +12,6 @@ qt_add_qml_module(hyprsysteminfo QML_FILES main.qml ) -target_link_libraries(hyprsysteminfo PRIVATE Qt6::Widgets Qt6::QuickControls2 PkgConfig::hyprutils) +target_link_libraries(hyprsysteminfo PRIVATE + Qt6::Widgets Qt6::QuickControls2 Qt6::WaylandClientPrivate PkgConfig::hyprutils +) diff --git a/src/SystemInfo.cpp b/src/SystemInfo.cpp index 2d1f94f..daa8f0e 100644 --- a/src/SystemInfo.cpp +++ b/src/SystemInfo.cpp @@ -1,4 +1,5 @@ #include "SystemInfo.hpp" +#include "WaylandScreen.hpp" #include "util/Utils.hpp" #include #include @@ -190,9 +191,8 @@ CSystemInternals::CSystemInternals(QObject* parent) : QObject(parent) { { std::string screens; - for (auto* s : QGuiApplication::screens()) { - auto ratio = s->devicePixelRatio(); - screens += std::format("{} ({}x{}), ", s->name().toStdString(), s->size().width() * ratio, s->size().height() * ratio); + for (const auto& s : SWaylandScreenInfo::enumerateScreens()) { + screens += std::format("{} ({}x{}), ", s.name.toStdString(), s.pixelSize.width(), s.pixelSize.height()); } if (!screens.empty()) diff --git a/src/WaylandScreen.cpp b/src/WaylandScreen.cpp new file mode 100644 index 0000000..01aa7a9 --- /dev/null +++ b/src/WaylandScreen.cpp @@ -0,0 +1,60 @@ +#include "WaylandScreen.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace QtWaylandClient; + +class CWaylandScreen : public QtWayland::wl_output { + public: + explicit CWaylandScreen(QWaylandDisplay* display, uint32_t version, uint32_t id); + ~CWaylandScreen() override; + Q_DISABLE_COPY_MOVE(CWaylandScreen); + SWaylandScreenInfo info; + + protected: + void output_mode(uint32_t flags, int32_t width, int32_t height, int32_t refresh) override; + void output_name(const QString& name) override; +}; + +std::vector SWaylandScreenInfo::enumerateScreens() { + auto* display = QWaylandIntegration::instance()->display(); + + std::vector screens; + for (const auto& global : display->globals()) { + if (global.interface == QStringLiteral("wl_output")) { + screens.emplace_back(new CWaylandScreen(display, global.version, global.id)); + } + } + + display->forceRoundTrip(); + + std::vector info; + for (auto* screen : screens) { + info.push_back(screen->info); + delete screen; + } + + return info; +} + +CWaylandScreen::CWaylandScreen(QWaylandDisplay* display, uint32_t version, uint32_t id) : QtWayland::wl_output(display->wl_registry(), id, 4u) {} + +CWaylandScreen::~CWaylandScreen() { + release(); +} + +void CWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh) { + info.pixelSize = QSize(width, height); +} + +void CWaylandScreen::output_name(const QString& name) { + info.name = name; +} diff --git a/src/WaylandScreen.hpp b/src/WaylandScreen.hpp new file mode 100644 index 0000000..3033325 --- /dev/null +++ b/src/WaylandScreen.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include +#include +#include + +struct SWaylandScreenInfo { + QString name; + QSize pixelSize; + + static std::vector enumerateScreens(); +};