diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index a224fa23f8..c2b8aa5413 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -866,6 +866,8 @@ PRIVATE platform/linux/linux_gdk_helper.h platform/linux/linux_libs.cpp platform/linux/linux_libs.h + platform/linux/linux_xlib_helper.cpp + platform/linux/linux_xlib_helper.h platform/linux/file_utilities_linux.cpp platform/linux/file_utilities_linux.h platform/linux/launcher_linux.cpp diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 0d6a5bf1f0..0c8cb32c0d 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -8,13 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/linux/linux_libs.h" #include "base/platform/base_platform_info.h" +#include "platform/linux/linux_xlib_helper.h" #include "platform/linux/linux_gdk_helper.h" #include "platform/linux/linux_desktop_environment.h" #include "platform/linux/specific_linux.h" - -extern "C" { -#include -} +#include "core/sandbox.h" +#include "core/application.h" +#include "main/main_domain.h" +#include "mainwindow.h" namespace Platform { namespace Libs { @@ -138,7 +139,8 @@ bool setupGtkBase(QLibrary &lib_gtk) { // gtk_init will reset the Xlib error handler, and that causes // Qt applications to quit on X errors. Therefore, we need to manually restore it. - int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(nullptr); + internal::XErrorHandlerRestorer handlerRestorer; + handlerRestorer.save(); DEBUG_LOG(("Library gtk functions loaded!")); gtkTriedToInit = true; @@ -149,13 +151,40 @@ bool setupGtkBase(QLibrary &lib_gtk) { } DEBUG_LOG(("Checked gtk with gtk_init_check!")); - XSetErrorHandler(oldErrorHandler); + handlerRestorer.restore(); // Use our custom log handler. g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, nullptr); return true; } + +bool IconThemeShouldBeSet() { + // change the icon theme only if it isn't already set by a platformtheme plugin + // if QT_QPA_PLATFORMTHEME=(gtk2|gtk3), then force-apply the icon theme + static const auto Result = ((QIcon::themeName() == qstr("hicolor") // QGenericUnixTheme + && QIcon::fallbackThemeName() == qstr("hicolor")) + || (QIcon::themeName() == qstr("Adwaita") // QGnomeTheme + && QIcon::fallbackThemeName() == qstr("gnome"))) + || IsGtkIntegrationForced(); + + return Result; +} + +void SetIconTheme() { + Core::Sandbox::Instance().customEnterFromEventLoop([] { + if (IconThemeShouldBeSet()) { + DEBUG_LOG(("Set GTK icon theme")); + QIcon::setThemeName(gtkSetting("gtk-icon-theme-name")); + QIcon::setFallbackThemeName(gtkSetting("gtk-fallback-icon-theme")); + Platform::SetApplicationIcon(Window::CreateIcon()); + if (App::wnd()) { + App::wnd()->setWindowIcon(Window::CreateIcon()); + } + Core::App().domain().notifyUnreadBadgeChanged(); + } + }); +} #endif // !TDESKTOP_DISABLE_GTK_INTEGRATION } // namespace @@ -251,17 +280,10 @@ void start() { LOAD_SYMBOL(lib_gtk, "gtk_button_set_label", gtk_button_set_label); LOAD_SYMBOL(lib_gtk, "gtk_button_get_type", gtk_button_get_type); - // change the icon theme only if it isn't already set by a platformtheme plugin - // if QT_QPA_PLATFORMTHEME=(gtk2|gtk3), then force-apply the icon theme - if (((QIcon::themeName() == qstr("hicolor") // QGenericUnixTheme - && QIcon::fallbackThemeName() == qstr("hicolor")) - || (QIcon::themeName() == qstr("Adwaita") // QGnomeTheme - && QIcon::fallbackThemeName() == qstr("gnome"))) - || IsGtkIntegrationForced()) { - DEBUG_LOG(("Set GTK icon theme")); - QIcon::setThemeName(gtkSetting("gtk-icon-theme-name")); - QIcon::setFallbackThemeName(gtkSetting("gtk-fallback-icon-theme")); - } + SetIconTheme(); + + const auto settings = gtk_settings_get_default(); + g_signal_connect(settings, "notify::gtk-icon-theme-name", G_CALLBACK(SetIconTheme), nullptr); } else { LOG(("Could not load gtk-3 or gtk-x11-2.0!")); } diff --git a/Telegram/SourceFiles/platform/linux/linux_xlib_helper.cpp b/Telegram/SourceFiles/platform/linux/linux_xlib_helper.cpp new file mode 100644 index 0000000000..43e87e3855 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_xlib_helper.cpp @@ -0,0 +1,40 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "platform/linux/linux_xlib_helper.h" + +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION +extern "C" { +#include +} + +namespace Platform { +namespace internal { + +class XErrorHandlerRestorer::Private { +public: + Private() {} + int (*oldErrorHandler)(Display *, XErrorEvent *); +}; + +XErrorHandlerRestorer::XErrorHandlerRestorer() +: _private(std::make_unique()) { +} + +XErrorHandlerRestorer::~XErrorHandlerRestorer() = default; + +void XErrorHandlerRestorer::save() { + _private->oldErrorHandler = XSetErrorHandler(nullptr); +} + +void XErrorHandlerRestorer::restore() { + XSetErrorHandler(_private->oldErrorHandler); +} + +} // namespace internal +} // namespace Platform +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION diff --git a/Telegram/SourceFiles/platform/linux/linux_xlib_helper.h b/Telegram/SourceFiles/platform/linux/linux_xlib_helper.h new file mode 100644 index 0000000000..65ad563105 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_xlib_helper.h @@ -0,0 +1,29 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION +namespace Platform { +namespace internal { + +class XErrorHandlerRestorer { +public: + XErrorHandlerRestorer(); + ~XErrorHandlerRestorer(); + + void save(); + void restore(); + +private: + class Private; + const std::unique_ptr _private; +}; + +} // namespace internal +} // namespace Platform +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 7d1bb4fa0d..bdd4156182 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -519,7 +519,8 @@ void MainWindow::setSNITrayIcon(int counter, bool muted) { _sniTrayIcon->setToolTipIconByName(iconName); } else if (IsIndicatorApplication()) { if (!IsIconRegenerationNeeded(counter, muted) - && !_sniTrayIcon->iconName().isEmpty()) { + && _trayIconFile + && _sniTrayIcon->iconName() == _trayIconFile->fileName()) { return; } @@ -532,7 +533,8 @@ void MainWindow::setSNITrayIcon(int counter, bool muted) { } } else { if (!IsIconRegenerationNeeded(counter, muted) - && !_sniTrayIcon->iconPixmap().isEmpty()) { + && !_sniTrayIcon->iconPixmap().isEmpty() + && _sniTrayIcon->iconName().isEmpty()) { return; }