Update icon theme on the fly

This commit is contained in:
Ilya Fedin 2020-07-15 22:45:59 +04:00 committed by John Preston
parent df155f6cb5
commit ba50393e86
5 changed files with 114 additions and 19 deletions

View File

@ -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

View File

@ -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 <X11/Xlib.h>
}
#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!"));
}

View File

@ -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 <X11/Xlib.h>
}
namespace Platform {
namespace internal {
class XErrorHandlerRestorer::Private {
public:
Private() {}
int (*oldErrorHandler)(Display *, XErrorEvent *);
};
XErrorHandlerRestorer::XErrorHandlerRestorer()
: _private(std::make_unique<Private>()) {
}
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

View File

@ -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> _private;
};
} // namespace internal
} // namespace Platform
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION

View File

@ -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;
}