Como o Firefox detecta alterações de tema claro/escuro em sistemas KDE?

Como o Firefox detecta alterações de tema claro/escuro em sistemas KDE?

Eu tenho alguns cron jobs que alternam entre temas claros e escuros automaticamente no meu sistema KDE (para os interessados, é lookandfeeltoolonde 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.

informação relacionada