fix: read GTK dark theme setting on Linux (#23678)

This commit is contained in:
Cheng Zhao 2020-05-22 07:41:25 +09:00 committed by GitHub
parent 82924679fe
commit fdf40ce07a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 4 deletions

View file

@ -67,6 +67,7 @@
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/gtk/gtk_ui.h"
#include "ui/gtk/gtk_ui_delegate.h"
@ -210,10 +211,36 @@ int X11EmptyErrorHandler(Display* d, XErrorEvent* error) {
int X11EmptyIOErrorHandler(Display* d) {
return 0;
}
// GTK does not provide a way to check if current theme is dark, so we compare
// the text and background luminosity to get a result.
// This trick comes from FireFox.
void UpdateDarkThemeSetting() {
float bg = color_utils::GetRelativeLuminance(gtk::GetBgColor("GtkLabel"));
float fg = color_utils::GetRelativeLuminance(gtk::GetFgColor("GtkLabel"));
bool is_dark = fg > bg;
// Pass it to NativeUi theme, which is used by the nativeTheme module and most
// places in Electron.
ui::NativeTheme::GetInstanceForNativeUi()->set_use_dark_colors(is_dark);
// Pass it to Web Theme, to make "prefers-color-scheme" media query work.
ui::NativeTheme::GetInstanceForWeb()->set_use_dark_colors(is_dark);
}
#endif
} // namespace
#if defined(USE_X11)
class DarkThemeObserver : public ui::NativeThemeObserver {
public:
DarkThemeObserver() = default;
// ui::NativeThemeObserver:
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override {
UpdateDarkThemeSetting();
}
};
#endif
// static
ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr;
@ -374,11 +401,19 @@ void ElectronBrowserMainParts::ToolkitInitialized() {
// In Aura/X11, Gtk-based LinuxUI implementation is used.
gtk_ui_delegate_ = std::make_unique<ui::GtkUiDelegateX11>(gfx::GetXDisplay());
ui::GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
views::LinuxUI::SetInstance(BuildGtkUi(ui::GtkUiDelegate::instance()));
#endif
views::LinuxUI* linux_ui = BuildGtkUi(gtk_ui_delegate_.get());
views::LinuxUI::SetInstance(linux_ui);
linux_ui->Initialize();
#if defined(USE_AURA) && defined(USE_X11)
views::LinuxUI::instance()->Initialize();
// Chromium does not respect GTK dark theme setting, but they may change
// in future and this code might be no longer needed. Check the Chromium
// issue to keep updated:
// https://bugs.chromium.org/p/chromium/issues/detail?id=998903
UpdateDarkThemeSetting();
// Update the naitve theme when GTK theme changes. The GetNativeTheme
// here returns a NativeThemeGtk, which monitors GTK settings.
dark_theme_observer_.reset(new DarkThemeObserver);
linux_ui->GetNativeTheme(nullptr)->AddObserver(dark_theme_observer_.get());
#endif
#if defined(USE_AURA)

View file

@ -59,6 +59,10 @@ class ViewsDelegate;
class ViewsDelegateMac;
#endif
#if defined(USE_X11)
class DarkThemeObserver;
#endif
class ElectronBrowserMainParts : public content::BrowserMainParts {
public:
explicit ElectronBrowserMainParts(const content::MainFunctionParams& params);
@ -129,6 +133,8 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
#if defined(USE_X11)
std::unique_ptr<ui::GtkUiDelegate> gtk_ui_delegate_;
// Used to notify the native theme of changes to dark mode.
std::unique_ptr<DarkThemeObserver> dark_theme_observer_;
#endif
std::unique_ptr<views::LayoutProvider> layout_provider_;