diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp index a5ae6dac09..9bf04761a1 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/linux/linux_gtk_integration_p.h" #include "base/platform/base_platform_info.h" +#include "platform/linux/linux_desktop_environment.h" #include "platform/linux/linux_xlib_helper.h" #include "platform/linux/linux_gdk_helper.h" #include "platform/linux/linux_gtk_file_dialog.h" @@ -207,6 +208,28 @@ bool CursorSizeShouldBeSet() { return Result; } +void SetScaleFactor() { + Core::Sandbox::Instance().customEnterFromEventLoop([] { + const auto integration = GtkIntegration::Instance(); + if (!integration || !DesktopEnvironment::IsGtkBased()) { + return; + } + + const auto scaleFactor = integration->scaleFactor(); + if (!scaleFactor.has_value()) { + return; + } + + LOG(("GTK scale factor: %1").arg(*scaleFactor)); + + const int scale = *scaleFactor + * 100 + / Core::Sandbox::Instance().devicePixelRatio(); + + cSetScreenScale(std::clamp(scale, 100, 300)); + }); +} + void SetIconTheme() { Core::Sandbox::Instance().customEnterFromEventLoop([] { const auto integration = GtkIntegration::Instance(); @@ -312,6 +335,10 @@ void GtkIntegration::load() { } if (GtkLoaded) { + LOAD_GTK_SYMBOL(lib_gtk, "gdk_display_get_default", gdk_display_get_default); + LOAD_GTK_SYMBOL(lib_gtk, "gdk_display_get_primary_monitor", gdk_display_get_primary_monitor); + LOAD_GTK_SYMBOL(lib_gtk, "gdk_monitor_get_scale_factor", gdk_monitor_get_scale_factor); + LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_new_from_file_at_size", gdk_pixbuf_new_from_file_at_size); LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_has_alpha", gdk_pixbuf_get_has_alpha); LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_pixels", gdk_pixbuf_get_pixels); @@ -329,6 +356,7 @@ void GtkIntegration::load() { LOAD_GTK_SYMBOL(lib_gtk, "gtk_app_chooser_get_app_info", gtk_app_chooser_get_app_info); LOAD_GTK_SYMBOL(lib_gtk, "gtk_app_chooser_get_type", gtk_app_chooser_get_type); + SetScaleFactor(); SetIconTheme(); SetCursorSize(); @@ -417,6 +445,18 @@ std::optional GtkIntegration::getStringSetting( return str; } +std::optional GtkIntegration::scaleFactor() const { + if (!loaded() + || (gdk_display_get_default == nullptr) + || (gdk_display_get_primary_monitor == nullptr) + || (gdk_monitor_get_scale_factor == nullptr)) { + return std::nullopt; + } + + return gdk_monitor_get_scale_factor( + gdk_display_get_primary_monitor(gdk_display_get_default())); +} + bool GtkIntegration::fileDialogSupported() const { return FileDialog::Gtk::Supported(); } diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h index df393befa8..25774161b1 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h @@ -34,6 +34,8 @@ public: [[nodiscard]] std::optional getStringSetting( const QString &propertyName) const; + [[nodiscard]] std::optional scaleFactor() const; + using FileDialogType = ::FileDialog::internal::Type; [[nodiscard]] bool fileDialogSupported() const; [[nodiscard]] bool useFileDialog( diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp index 00df2f046f..59225e9475 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp @@ -43,6 +43,10 @@ std::optional GtkIntegration::getStringSetting( return std::nullopt; } +std::optional GtkIntegration::scaleFactor() const { + return std::nullopt; +} + bool GtkIntegration::fileDialogSupported() const { return false; } diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h index 301a828e54..99d3579dda 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h @@ -27,6 +27,7 @@ extern "C" { #endif // !LINK_TO_GTK // To be able to compile with gtk-2.0 headers as well +#define GdkMonitor GdkScreen typedef struct _GtkAppChooser GtkAppChooser; namespace Platform { @@ -147,6 +148,9 @@ inline bool g_type_cit_helper(Object *instance, GType iface_type) { inline gint (*gtk_dialog_run)(GtkDialog *dialog) = nullptr; inline GdkAtom (*gdk_atom_intern)(const gchar *atom_name, gboolean only_if_exists) = nullptr; +inline GdkDisplay* (*gdk_display_get_default)(void) = nullptr; +inline GdkMonitor* (*gdk_display_get_primary_monitor)(GdkDisplay *display) = nullptr; +inline int (*gdk_monitor_get_scale_factor)(GdkMonitor *monitor) = nullptr; inline GdkPixbuf* (*gdk_pixbuf_new_from_file_at_size)(const gchar *filename, int width, int height, GError **error) = nullptr; inline gboolean (*gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf) = nullptr; inline guchar* (*gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf) = nullptr;