Skip to content

Commit

Permalink
feat: enable dark mode on GTK UIs (#40009)
Browse files Browse the repository at this point in the history
feat: port DarkModeManagerLinux

This is needed after https://bugs.chromium.org/p/chromium/issues/detail?id=998903
and replaces the previous workaround to detect dark mode on GTK.
Detect system dark theme preference via xdg settings portal:
https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Settings

Closes: #38961
Closes: #28838

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Robert Günzler <r@gnzler.io>
  • Loading branch information
trop[bot] and robertgzr committed Sep 27, 2023
1 parent 5868f9a commit b4742f9
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 48 deletions.
4 changes: 4 additions & 0 deletions chromium_src/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ static_library("chrome") {
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h",
]
sources += [
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
]
public_deps += [
"//components/dbus/menu",
"//components/dbus/thread_linux",
Expand Down
45 changes: 5 additions & 40 deletions shell/browser/electron_browser_main_parts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@

#if BUILDFLAG(IS_LINUX)
#include "base/environment.h"
#include "chrome/browser/ui/views/dark_mode_manager_linux.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
#include "electron/electron_gtk_stubs.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/base/ime/linux/linux_input_method_context_factory.h"
#include "ui/gfx/color_utils.h"
#include "ui/gtk/gtk_compat.h" // nogncheck
#include "ui/gtk/gtk_util.h" // nogncheck
#include "ui/linux/linux_ui.h"
Expand Down Expand Up @@ -176,36 +176,8 @@ std::u16string MediaStringProvider(media::MessageId id) {
}
}

#if BUILDFLAG(IS_LINUX)
// 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 BUILDFLAG(IS_LINUX)
class DarkThemeObserver : public ui::NativeThemeObserver {
public:
DarkThemeObserver() = default;

// ui::NativeThemeObserver:
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override {
UpdateDarkThemeSetting();
}
};
#endif

// static
ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr;

Expand Down Expand Up @@ -440,17 +412,10 @@ void ElectronBrowserMainParts::ToolkitInitialized() {
CHECK(electron::IsElectron_gdk_pixbufInitialized())
<< "Failed to initialize libgdk_pixbuf-2.0.so.0";

// 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 native theme when GTK theme changes. The GetNativeTheme
// here returns a NativeThemeGtk, which monitors GTK settings.
dark_theme_observer_ = std::make_unique<DarkThemeObserver>();
auto* linux_ui_theme = ui::LinuxUiTheme::GetForProfile(nullptr);
CHECK(linux_ui_theme);
linux_ui_theme->GetNativeTheme()->AddObserver(dark_theme_observer_.get());
// source theme changes from system settings, including settings portal:
// https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Settings
dark_mode_manager_ = std::make_unique<ui::DarkModeManagerLinux>();

ui::LinuxUi::SetInstance(linux_ui);

// Cursor theme changes are tracked by LinuxUI (via a CursorThemeManager
Expand Down
11 changes: 3 additions & 8 deletions shell/browser/electron_browser_main_parts.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class Screen;

namespace ui {
class LinuxUiGetter;
}
class DarkModeManagerLinux;
} // namespace ui

namespace electron {

Expand All @@ -62,10 +63,6 @@ class ViewsDelegate;
class ViewsDelegateMac;
#endif

#if BUILDFLAG(IS_LINUX)
class DarkThemeObserver;
#endif

class ElectronBrowserMainParts : public content::BrowserMainParts {
public:
ElectronBrowserMainParts();
Expand Down Expand Up @@ -142,9 +139,7 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
#endif

#if BUILDFLAG(IS_LINUX)
// Used to notify the native theme of changes to dark mode.
std::unique_ptr<DarkThemeObserver> dark_theme_observer_;

std::unique_ptr<ui::DarkModeManagerLinux> dark_mode_manager_;
std::unique_ptr<ui::LinuxUiGetter> linux_ui_getter_;
#endif

Expand Down

0 comments on commit b4742f9

Please sign in to comment.