Eu tenho alguns cron jobs que alternam entre temas claros e escuros automaticamente no meu sistema KDE (para os interessados, é lookandfeeltool
onde eu simplesmente alterno entre temas claros e escuros globais (tive que definir o meu próprio com base em outros com as alterações que eu queria fazer), ou você pode ajustar as cores usandoplasma-theme-switcher
(funciona em X e Wayland)). Funciona bem, exceto que confio em alguns aplicativos GTK, que não os respeitam. Os mais significativos deles são navegadores/aplicativos Electron baseados em Chromium, como o próprio Chrome ou VSCode.
Curiosamente, porém, o Firefox lida com isso perfeitamente e responde às mudanças de tema, apesar de ser um aplicativo GTK. É também o único aplicativo GTK que executo que parece entender que não quero usar o explorador de arquivos Nautilus e, em vez disso, usa o Dolphin para todos os prompts de arquivo.
Minha pergunta é como o Firefox faz isso e por que os aplicativos GTK regulares não lidam com isso de maneira mais elegante?
A segunda parte da minha pergunta é se existe algum tipo de comando DBUS que eu possa disparar, o que faz com que os aplicativos GTK "verifiquem se há alterações no tema", para permitir que meus programas respondam aos meus scripts.
Obrigado por qualquer indicação
Responder1
Acho que a resposta está localizada no arquivo /widget/gtk/nsLookAndFeel.cpp
.
Linhas 1190-1200 emo código estável mais recente:
// It seems GTK doesn't have an API to query if the current theme is "light" or
// "dark", so we synthesize it from the CSS2 Window/WindowText colors instead,
// by comparing their luminosity.
static bool GetThemeIsDark() {
GdkRGBA bg, fg;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &bg);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &fg);
return RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(bg)) <
RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(fg));
}
A função GDK_RGBA_TO_NS_RGBA()
pode ser simplificada como:
(Observe que esta não é a implementação real)
#define GDK_RGBA_TO_NS_RGBA(c) \
( \
((c.alpha * 255) << 24) \
| ((c.blue * 255) << 16) \
| ((c.green * 255) << 8) \
| (c.red * 255) \
)
As funçõesgtk_style_context_get_background_color()
egtk_style_context_get_color()
retorna as cores de fundo e de primeiro plano para um determinado estado (respectivamente).
Então, aparentemente, a resposta é verificar qual valor inteiro é maior, o plano de fundo ou o primeiro plano, e decidir com base nisso se o tema é escuro ou não.