X Tutup
Skip to content

Commit fea3366

Browse files
fix: propagate preferred color scheme to the renderer (electron#22896)
* fix: do not crash if the window is closed syncronously with a nativeTheme change * fix: propogate preferred color scheme to the renderer and keep it up to date
1 parent 212b47a commit fea3366

File tree

7 files changed

+56
-17
lines changed

7 files changed

+56
-17
lines changed

shell/browser/api/electron_api_native_theme.cc

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ namespace electron {
2323

2424
namespace api {
2525

26-
NativeTheme::NativeTheme(v8::Isolate* isolate, ui::NativeTheme* theme)
27-
: theme_(theme) {
28-
theme_->AddObserver(this);
26+
NativeTheme::NativeTheme(v8::Isolate* isolate,
27+
ui::NativeTheme* ui_theme,
28+
ui::NativeTheme* web_theme)
29+
: ui_theme_(ui_theme), web_theme_(web_theme) {
30+
ui_theme_->AddObserver(this);
2931
Init(isolate);
3032
}
3133

3234
NativeTheme::~NativeTheme() {
33-
theme_->RemoveObserver(this);
35+
ui_theme_->RemoveObserver(this);
3436
}
3537

3638
void NativeTheme::OnNativeThemeUpdatedOnUI() {
@@ -44,7 +46,8 @@ void NativeTheme::OnNativeThemeUpdated(ui::NativeTheme* theme) {
4446
}
4547

4648
void NativeTheme::SetThemeSource(ui::NativeTheme::ThemeSource override) {
47-
theme_->set_theme_source(override);
49+
ui_theme_->set_theme_source(override);
50+
web_theme_->set_theme_source(override);
4851
#if defined(OS_MACOSX)
4952
// Update the macOS appearance setting for this new override value
5053
UpdateMacOSAppearanceForOverrideValue(override);
@@ -59,15 +62,15 @@ void NativeTheme::SetThemeSource(ui::NativeTheme::ThemeSource override) {
5962
}
6063

6164
ui::NativeTheme::ThemeSource NativeTheme::GetThemeSource() const {
62-
return theme_->theme_source();
65+
return ui_theme_->theme_source();
6366
}
6467

6568
bool NativeTheme::ShouldUseDarkColors() {
66-
return theme_->ShouldUseDarkColors();
69+
return ui_theme_->ShouldUseDarkColors();
6770
}
6871

6972
bool NativeTheme::ShouldUseHighContrastColors() {
70-
return theme_->UsesHighContrastColors();
73+
return ui_theme_->UsesHighContrastColors();
7174
}
7275

7376
#if defined(OS_MACOSX)
@@ -92,8 +95,11 @@ bool NativeTheme::ShouldUseInvertedColorScheme() {
9295

9396
// static
9497
v8::Local<v8::Value> NativeTheme::Create(v8::Isolate* isolate) {
95-
ui::NativeTheme* theme = ui::NativeTheme::GetInstanceForNativeUi();
96-
return gin::CreateHandle(isolate, new NativeTheme(isolate, theme)).ToV8();
98+
ui::NativeTheme* ui_theme = ui::NativeTheme::GetInstanceForNativeUi();
99+
ui::NativeTheme* web_theme = ui::NativeTheme::GetInstanceForWeb();
100+
return gin::CreateHandle(isolate,
101+
new NativeTheme(isolate, ui_theme, web_theme))
102+
.ToV8();
97103
}
98104

99105
// static

shell/browser/api/electron_api_native_theme.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ class NativeTheme : public gin_helper::EventEmitter<NativeTheme>,
2222
v8::Local<v8::FunctionTemplate> prototype);
2323

2424
protected:
25-
NativeTheme(v8::Isolate* isolate, ui::NativeTheme* theme);
25+
NativeTheme(v8::Isolate* isolate,
26+
ui::NativeTheme* ui_theme,
27+
ui::NativeTheme* web_theme);
2628
~NativeTheme() override;
2729

2830
void SetThemeSource(ui::NativeTheme::ThemeSource override);
@@ -40,7 +42,8 @@ class NativeTheme : public gin_helper::EventEmitter<NativeTheme>,
4042
void OnNativeThemeUpdatedOnUI();
4143

4244
private:
43-
ui::NativeTheme* theme_;
45+
ui::NativeTheme* ui_theme_;
46+
ui::NativeTheme* web_theme_;
4447

4548
DISALLOW_COPY_AND_ASSIGN(NativeTheme);
4649
};

shell/browser/electron_browser_client.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,11 @@ void ElectronBrowserClient::OverrideWebkitPrefs(
524524
prefs->picture_in_picture_enabled = false;
525525
#endif
526526

527+
ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
528+
prefs->preferred_color_scheme = native_theme->ShouldUseDarkColors()
529+
? blink::PreferredColorScheme::kDark
530+
: blink::PreferredColorScheme::kLight;
531+
527532
SetFontDefaults(prefs);
528533

529534
// Custom preferences of guest page.

shell/browser/native_window.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class NativeWindow : public base::SupportsUserData,
198198
#if defined(OS_MACOSX)
199199
virtual void SetTrafficLightPosition(const gfx::Point& position) = 0;
200200
virtual gfx::Point GetTrafficLightPosition() const = 0;
201+
virtual void RedrawTrafficLights() = 0;
201202
#endif
202203

203204
// Touchbar API

shell/browser/native_window_mac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
150150
void SetWindowLevel(int level);
151151

152152
// Custom traffic light positioning
153-
void RedrawTrafficLights();
153+
void RedrawTrafficLights() override;
154154
void SetExitingFullScreen(bool flag);
155155
void SetTrafficLightPosition(const gfx::Point& position) override;
156156
gfx::Point GetTrafficLightPosition() const override;

shell/browser/native_window_mac.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,9 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
700700
}
701701

702702
void NativeWindowMac::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
703-
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
704-
base::BindOnce(&NativeWindowMac::RedrawTrafficLights,
705-
base::Unretained(this)));
703+
base::PostTask(
704+
FROM_HERE, {content::BrowserThread::UI},
705+
base::BindOnce(&NativeWindow::RedrawTrafficLights, GetWeakPtr()));
706706
}
707707

708708
bool NativeWindowMac::IsEnabled() {

spec-main/api-native-theme-spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect } from 'chai';
2-
import { nativeTheme, systemPreferences } from 'electron';
2+
import { nativeTheme, systemPreferences, BrowserWindow } from 'electron';
33
import * as os from 'os';
4+
import * as path from 'path';
45
import * as semver from 'semver';
56

67
import { delay, ifdescribe } from './spec-helpers';
78
import { emittedOnce } from './events-helpers';
9+
import { closeAllWindows } from './window-helpers';
810

911
describe('nativeTheme module', () => {
1012
describe('nativeTheme.shouldUseDarkColors', () => {
@@ -18,6 +20,8 @@ describe('nativeTheme module', () => {
1820
nativeTheme.themeSource = 'system';
1921
// Wait for any pending events to emit
2022
await delay(20);
23+
24+
closeAllWindows();
2125
});
2226

2327
it('is system by default', () => {
@@ -62,6 +66,26 @@ describe('nativeTheme module', () => {
6266
expect(systemPreferences.appLevelAppearance).to.equal('light');
6367
});
6468
});
69+
70+
const getPrefersColorSchemeIsDark = async (w: Electron.BrowserWindow) => {
71+
const isDark: boolean = await w.webContents.executeJavaScript(
72+
'matchMedia("(prefers-color-scheme: dark)").matches'
73+
);
74+
return isDark;
75+
};
76+
77+
it('should override the result of prefers-color-scheme CSS media query', async () => {
78+
const w = new BrowserWindow({ show: false });
79+
await w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
80+
const originalSystemIsDark = await getPrefersColorSchemeIsDark(w);
81+
nativeTheme.themeSource = 'dark';
82+
expect(await getPrefersColorSchemeIsDark(w)).to.equal(true);
83+
nativeTheme.themeSource = 'light';
84+
expect(await getPrefersColorSchemeIsDark(w)).to.equal(false);
85+
nativeTheme.themeSource = 'system';
86+
expect(await getPrefersColorSchemeIsDark(w)).to.equal(originalSystemIsDark);
87+
w.close();
88+
});
6589
});
6690

6791
describe('nativeTheme.shouldUseInvertedColorScheme', () => {

0 commit comments

Comments
 (0)
X Tutup