Как Firefox определяет смену светлой/тёмной темы в системах KDE?

Как Firefox определяет смену светлой/тёмной темы в системах KDE?

У меня есть несколько заданий cron, которые автоматически переключают светлую и темную темы в моей системе KDE (для тех, кому интересно, есть задание, в lookandfeeltoolкотором я просто переключаюсь между глобальными светлой и темной темами (мне пришлось определить свою собственную на основе других с изменениями, которые я хотел внести), или вы можете настроить цвета с помощьюplasma-theme-switcher(работает на X и Wayland)). Работает хорошо, за исключением того, что мне приходится полагаться на несколько приложений GTK, которые их не уважают. Наиболее значимыми из них являются браузеры на основе Chromium / приложения Electron, такие как сам Chrome или VSCode.

Интересно, однако, что Firefox отлично справляется с этим и реагирует на изменения темы, несмотря на то, что это приложение GTK. Это также единственное приложение GTK, которое я запускаю, которое, похоже, понимает, что я не хочу использовать проводник Nautilus, и вместо этого использует Dolphin для всех запросов на файлы.

У меня вопрос: как Firefox это делает и почему обычные приложения GTK не справляются с этим более изящно?

Вторая часть моего вопроса заключается в том, существует ли какая-то команда DBUS, которую я могу запустить, чтобы заставить приложения GTK «проверять наличие изменений темы», чтобы позволить моим программам реагировать на мои скрипты.

Спасибо за любые указания.

решение1

Я думаю, что ответ находится в файле /widget/gtk/nsLookAndFeel.cpp.

Строки 1190-1200 впоследний стабильный код:


// 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));
}

Функцию GDK_RGBA_TO_NS_RGBA()можно упростить следующим образом:

(Обратите внимание, что это не фактическая реализация.)

#define GDK_RGBA_TO_NS_RGBA(c)                             \
  (                                                        \
      ((c.alpha * 255) << 24)                              \
    | ((c.blue * 255) << 16)                               \
    | ((c.green * 255) << 8)                               \
    | (c.red * 255)                                        \
  )

Функцииgtk_style_context_get_background_color()иgtk_style_context_get_color()возвращает цвета фона и переднего плана для заданного состояния (соответственно).

Таким образом, очевидно, ответ заключается в проверке того, какое целое значение больше — фонового или переднего плана, и на основе этого принятия решения о том, является ли тема темной или нет.

Связанный контент