From 39075538fb1208c7626ee4e1e4b12cc527fc6244 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 12 Jan 2023 13:18:28 +0400 Subject: [PATCH] Enable RoundPreferFloor HighDpi support on Windows. Add an experimental setting for exact HighDPI on Windows. --- Telegram/SourceFiles/core/launcher.cpp | 28 +++++++++++++++++-- Telegram/SourceFiles/core/launcher.h | 3 ++ Telegram/SourceFiles/core/sandbox.cpp | 7 ++++- .../SourceFiles/platform/mac/launcher_mac.h | 1 + .../SourceFiles/platform/mac/launcher_mac.mm | 8 ++++-- .../settings/settings_experimental.cpp | 2 ++ 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index 526a5cf85..ee1cb5904 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_launcher.h" #include "platform/platform_specific.h" +#include "base/options.h" #include "base/platform/base_platform_info.h" #include "base/platform/base_platform_file_utilities.h" #include "ui/main_queue_processor.h" @@ -272,8 +273,18 @@ bool CheckPortableVersionFolder() { return true; } +base::options::toggle OptionFractionalScalingEnabled({ + .id = kOptionFractionalScalingEnabled, + .name = "Enable precise High DPI scaling", + .description = "Follow system interface scale settings exactly.", + .scope = base::options::windows, + .restartRequired = true, +}); + } // namespace +const char kOptionFractionalScalingEnabled[] = "fractional-scaling-enabled"; + std::unique_ptr Launcher::Create(int argc, char *argv[]) { return std::make_unique(argc, argv); } @@ -294,9 +305,6 @@ void Launcher::init() { initQtMessageLogging(); QApplication::setApplicationName(u"TelegramDesktop"_q); - QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true); - QApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::Floor); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // fallback session management is useless for tdesktop since it doesn't have @@ -311,6 +319,17 @@ void Launcher::init() { initHook(); } +void Launcher::initHighDpi() { + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); + if (OptionFractionalScalingEnabled.value()) { + QApplication::setHighDpiScaleFactorRoundingPolicy( + Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + } else { + QApplication::setHighDpiScaleFactorRoundingPolicy( + Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor); + } +} + int Launcher::exec() { init(); @@ -324,6 +343,9 @@ int Launcher::exec() { Logs::start(this); base::options::init(cWorkingDir() + "tdata/experimental_options.json"); + // Must be called after options are inited. + initHighDpi(); + if (Logs::DebugEnabled()) { const auto openalLogPath = QDir::toNativeSeparators( cWorkingDir() + u"DebugLogs/last_openal_log.txt"_q); diff --git a/Telegram/SourceFiles/core/launcher.h b/Telegram/SourceFiles/core/launcher.h index 366568c80..06e135630 100644 --- a/Telegram/SourceFiles/core/launcher.h +++ b/Telegram/SourceFiles/core/launcher.h @@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Core { +extern const char kOptionFractionalScalingEnabled[]; + class Launcher { public: Launcher(int argc, char *argv[]); @@ -52,6 +54,7 @@ private: void init(); virtual void initHook() { } + virtual void initHighDpi(); virtual bool launchUpdater(UpdaterLaunch action) = 0; diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp index 3de4ebb3b..b445f9e51 100644 --- a/Telegram/SourceFiles/core/sandbox.cpp +++ b/Telegram/SourceFiles/core/sandbox.cpp @@ -226,7 +226,12 @@ void Sandbox::setupScreenScale() { logEnv("QT_USE_PHYSICAL_DPI"); logEnv("QT_FONT_DPI"); - const auto useRatio = std::clamp(qCeil(ratio), 1, 3); + // Like Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor. + // Round up for .75 and higher. This favors "small UI" over "large UI". + const auto roundedRatio = ((ratio - qFloor(ratio)) < 0.75) + ? qFloor(ratio) + : qCeil(ratio); + const auto useRatio = std::clamp(roundedRatio, 1, 3); style::SetDevicePixelRatio(useRatio); const auto screen = Sandbox::primaryScreen(); diff --git a/Telegram/SourceFiles/platform/mac/launcher_mac.h b/Telegram/SourceFiles/platform/mac/launcher_mac.h index edb966a01..b4fd5c123 100644 --- a/Telegram/SourceFiles/platform/mac/launcher_mac.h +++ b/Telegram/SourceFiles/platform/mac/launcher_mac.h @@ -17,6 +17,7 @@ public: private: void initHook() override; + void initHighDpi() override; bool launchUpdater(UpdaterLaunch action) override; diff --git a/Telegram/SourceFiles/platform/mac/launcher_mac.mm b/Telegram/SourceFiles/platform/mac/launcher_mac.mm index 599dcbb50..2902c78a6 100644 --- a/Telegram/SourceFiles/platform/mac/launcher_mac.mm +++ b/Telegram/SourceFiles/platform/mac/launcher_mac.mm @@ -24,12 +24,14 @@ Launcher::Launcher(int argc, char *argv[]) } void Launcher::initHook() { - // macOS Retina display support is working fine, others are not. - QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); - base::RegisterBundledResources(u"Telegram.rcc"_q); } +void Launcher::initHighDpi() { + // macOS Retina display support is working fine. + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); +} + bool Launcher::launchUpdater(UpdaterLaunch action) { if (cExeName().isEmpty()) { return false; diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp index d9c62f313..9731130dc 100644 --- a/Telegram/SourceFiles/settings/settings_experimental.cpp +++ b/Telegram/SourceFiles/settings/settings_experimental.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/chat/chat_style_radius.h" #include "base/options.h" #include "core/application.h" +#include "core/launcher.h" #include "platform/platform_specific.h" #include "chat_helpers/tabbed_panel.h" #include "dialogs/dialogs_inner_widget.h" @@ -137,6 +138,7 @@ void SetupExperimental( }; addToggle(ChatHelpers::kOptionTabbedPanelShowOnClick); + addToggle(Core::kOptionFractionalScalingEnabled); addToggle(Window::kOptionViewProfileInChatsListContextMenu); addToggle(Dialogs::kOptionCtrlClickChatNewWindow); addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL);