Flutter Engine
The Flutter Engine
settings_plugin.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/shell/platform/windows/settings_plugin.h"
6
7#include "flutter/shell/platform/common/json_message_codec.h"
8#include "flutter/shell/platform/windows/system_utils.h"
9
10namespace flutter {
11
12namespace {
13constexpr char kChannelName[] = "flutter/settings";
14
15constexpr char kAlwaysUse24HourFormat[] = "alwaysUse24HourFormat";
16constexpr char kTextScaleFactor[] = "textScaleFactor";
17constexpr char kPlatformBrightness[] = "platformBrightness";
18
19constexpr char kPlatformBrightnessDark[] = "dark";
20constexpr char kPlatformBrightnessLight[] = "light";
21
22constexpr wchar_t kGetPreferredBrightnessRegKey[] =
23 L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
24constexpr wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
25
26constexpr wchar_t kGetTextScaleFactorRegKey[] =
27 L"Software\\Microsoft\\Accessibility";
28constexpr wchar_t kGetTextScaleFactorRegValue[] = L"TextScaleFactor";
29
30// Return an approximation of the apparent luminance of a given color.
31int GetLuminance(DWORD color) {
32 int r = GetRValue(color);
33 int g = GetGValue(color);
34 int b = GetBValue(color);
35 return (r + r + r + b + (g << 2)) >> 3;
36}
37
38// Return kLight if light mode for apps is selected, otherwise return kDark.
39SettingsPlugin::PlatformBrightness GetThemeBrightness() {
40 DWORD use_light_theme;
41 DWORD use_light_theme_size = sizeof(use_light_theme);
42 LONG result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
43 kGetPreferredBrightnessRegValue, RRF_RT_REG_DWORD,
44 nullptr, &use_light_theme, &use_light_theme_size);
45
46 if (result == 0) {
47 return use_light_theme ? SettingsPlugin::PlatformBrightness::kLight
49 } else {
50 // The current OS does not support dark mode. (Older Windows 10 or before
51 // Windows 10)
53 }
54}
55} // namespace
56
58 TaskRunner* task_runner)
59 : channel_(std::make_unique<BasicMessageChannel<rapidjson::Document>>(
60 messenger,
62 &JsonMessageCodec::GetInstance())),
63 task_runner_(task_runner) {}
64
67}
68
70 rapidjson::Document settings(rapidjson::kObjectType);
71 auto& allocator = settings.GetAllocator();
72 settings.AddMember(kAlwaysUse24HourFormat, GetAlwaysUse24HourFormat(),
73 allocator);
74 settings.AddMember(kTextScaleFactor, GetTextScaleFactor(), allocator);
75
77 settings.AddMember(kPlatformBrightness, kPlatformBrightnessDark, allocator);
78 } else {
79 settings.AddMember(kPlatformBrightness, kPlatformBrightnessLight,
80 allocator);
81 }
82 channel_->Send(settings);
83}
84
86 RegOpenKeyEx(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
87 RRF_RT_REG_DWORD, KEY_NOTIFY, &preferred_brightness_reg_hkey_);
88 RegOpenKeyEx(HKEY_CURRENT_USER, kGetTextScaleFactorRegKey, RRF_RT_REG_DWORD,
89 KEY_NOTIFY, &text_scale_factor_reg_hkey_);
90
91 // Start watching when the keys exist.
92 if (preferred_brightness_reg_hkey_ != nullptr) {
94 }
95 if (text_scale_factor_reg_hkey_ != nullptr) {
97 }
98}
99
101 preferred_brightness_changed_watcher_ = nullptr;
102 text_scale_factor_changed_watcher_ = nullptr;
103
104 if (preferred_brightness_reg_hkey_ != nullptr) {
105 RegCloseKey(preferred_brightness_reg_hkey_);
106 }
107 if (text_scale_factor_reg_hkey_ != nullptr) {
108 RegCloseKey(text_scale_factor_reg_hkey_);
109 }
110}
111
114}
115
117 DWORD text_scale_factor;
118 DWORD text_scale_factor_size = sizeof(text_scale_factor);
119 LONG result = RegGetValue(
120 HKEY_CURRENT_USER, kGetTextScaleFactorRegKey, kGetTextScaleFactorRegValue,
121 RRF_RT_REG_DWORD, nullptr, &text_scale_factor, &text_scale_factor_size);
122
123 if (result == 0) {
124 return text_scale_factor / 100.0;
125 } else {
126 // The current OS does not have text scale factor.
127 return 1.0;
128 }
129}
130
132 if (is_high_contrast_) {
133 DWORD window_color = GetSysColor(COLOR_WINDOW);
134 int luminance = GetLuminance(window_color);
135 return luminance >= 127 ? SettingsPlugin::PlatformBrightness::kLight
137 } else {
138 return GetThemeBrightness();
139 }
140}
141
143 preferred_brightness_changed_watcher_ =
144 std::make_unique<EventWatcher>([this]() {
145 task_runner_->PostTask([this]() {
146 SendSettings();
148 });
149 });
150
151 RegNotifyChangeKeyValue(
152 preferred_brightness_reg_hkey_, FALSE, REG_NOTIFY_CHANGE_LAST_SET,
153 preferred_brightness_changed_watcher_->GetHandle(), TRUE);
154}
155
157 text_scale_factor_changed_watcher_ = std::make_unique<EventWatcher>([this]() {
158 task_runner_->PostTask([this]() {
159 SendSettings();
161 });
162 });
163
164 RegNotifyChangeKeyValue(
165 text_scale_factor_reg_hkey_, FALSE, REG_NOTIFY_CHANGE_LAST_SET,
166 text_scale_factor_changed_watcher_->GetHandle(), TRUE);
167}
168
169void SettingsPlugin::UpdateHighContrastMode(bool is_high_contrast) {
170 is_high_contrast_ = is_high_contrast;
171 SendSettings();
172}
173
174} // namespace flutter
static NSString *const kChannelName
virtual void StartWatching()
virtual void UpdateHighContrastMode(bool is_high_contrast)
virtual void WatchPreferredBrightnessChanged()
virtual bool GetAlwaysUse24HourFormat()
virtual PlatformBrightness GetPreferredBrightness()
SettingsPlugin(BinaryMessenger *messenger, TaskRunner *task_runner)
virtual void WatchTextScaleFactorChanged()
virtual float GetTextScaleFactor()
void PostTask(TaskClosure task)
Definition: task_runner.cc:88
DlColor color
static bool b
static constexpr char kPlatformBrightnessLight[]
static constexpr char kPlatformBrightnessDark[]
GAsyncResult * result
return FALSE
std::wstring GetUserTimeFormat()
bool Prefer24HourTime(std::wstring time_format)
Definition: ref_ptr.h:256
#define HKEY_CURRENT_USER
long LONG
Definition: windows_types.h:23
unsigned long DWORD
Definition: windows_types.h:22
#define KEY_NOTIFY