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.h"
#include "ui/base/x/x11_util_internal.h" #include "ui/base/x/x11_util_internal.h"
#include "ui/events/devices/x11/touch_factory_x11.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/gfx/x/x11_types.h"
#include "ui/gtk/gtk_ui.h" #include "ui/gtk/gtk_ui.h"
#include "ui/gtk/gtk_ui_delegate.h" #include "ui/gtk/gtk_ui_delegate.h"
@ -210,10 +211,36 @@ int X11EmptyErrorHandler(Display* d, XErrorEvent* error) {
int X11EmptyIOErrorHandler(Display* d) { int X11EmptyIOErrorHandler(Display* d) {
return 0; 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 #endif
} // namespace } // 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 // static
ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr; ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr;
@ -374,11 +401,19 @@ void ElectronBrowserMainParts::ToolkitInitialized() {
// In Aura/X11, Gtk-based LinuxUI implementation is used. // In Aura/X11, Gtk-based LinuxUI implementation is used.
gtk_ui_delegate_ = std::make_unique<ui::GtkUiDelegateX11>(gfx::GetXDisplay()); gtk_ui_delegate_ = std::make_unique<ui::GtkUiDelegateX11>(gfx::GetXDisplay());
ui::GtkUiDelegate::SetInstance(gtk_ui_delegate_.get()); ui::GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
views::LinuxUI::SetInstance(BuildGtkUi(ui::GtkUiDelegate::instance())); views::LinuxUI* linux_ui = BuildGtkUi(gtk_ui_delegate_.get());
#endif views::LinuxUI::SetInstance(linux_ui);
linux_ui->Initialize();
#if defined(USE_AURA) && defined(USE_X11) // Chromium does not respect GTK dark theme setting, but they may change
views::LinuxUI::instance()->Initialize(); // 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 #endif
#if defined(USE_AURA) #if defined(USE_AURA)

View file

@ -59,6 +59,10 @@ class ViewsDelegate;
class ViewsDelegateMac; class ViewsDelegateMac;
#endif #endif
#if defined(USE_X11)
class DarkThemeObserver;
#endif
class ElectronBrowserMainParts : public content::BrowserMainParts { class ElectronBrowserMainParts : public content::BrowserMainParts {
public: public:
explicit ElectronBrowserMainParts(const content::MainFunctionParams& params); explicit ElectronBrowserMainParts(const content::MainFunctionParams& params);
@ -129,6 +133,8 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
#if defined(USE_X11) #if defined(USE_X11)
std::unique_ptr<ui::GtkUiDelegate> gtk_ui_delegate_; 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 #endif
std::unique_ptr<views::LayoutProvider> layout_provider_; std::unique_ptr<views::LayoutProvider> layout_provider_;