| Flutter Windows Embedder |

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
10 namespace flutter {
11
12 namespace {
13 constexpr char kChannelName[] = "flutter/settings";
14
15 constexpr char kAlwaysUse24HourFormat[] = "alwaysUse24HourFormat";
16 constexpr char kTextScaleFactor[] = "textScaleFactor";
17 constexpr char kPlatformBrightness[] = "platformBrightness";
18
19 constexpr char kPlatformBrightnessDark[] = "dark";
20 constexpr char kPlatformBrightnessLight[] = "light";
21
22 constexpr wchar_t kGetPreferredBrightnessRegKey[] =
23 L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
24 constexpr wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
25
26 constexpr wchar_t kGetTextScaleFactorRegKey[] =
27 L"Software\\Microsoft\\Accessibility";
28 constexpr wchar_t kGetTextScaleFactorRegValue[] = L"TextScaleFactor";
29
30 // Return an approximation of the apparent luminance of a given color.
31 int 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.
39 SettingsPlugin::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
48 : SettingsPlugin::PlatformBrightness::kDark;
49 } else {
50 // The current OS does not support dark mode. (Older Windows 10 or before
51 // Windows 10)
52 return SettingsPlugin::PlatformBrightness::kLight;
53 }
54 }
55 } // namespace
56
57 SettingsPlugin::SettingsPlugin(BinaryMessenger* messenger,
58 TaskRunner* task_runner)
59 : channel_(std::make_unique<BasicMessageChannel<rapidjson::Document>>(
60 messenger,
61 kChannelName,
62 &JsonMessageCodec::GetInstance())),
63 task_runner_(task_runner) {}
64
65 SettingsPlugin::~SettingsPlugin() {
66 StopWatching();
67 }
68
69 void SettingsPlugin::SendSettings() {
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
76 if (GetPreferredBrightness() == PlatformBrightness::kDark) {
77 settings.AddMember(kPlatformBrightness, kPlatformBrightnessDark, allocator);
78 } else {
79 settings.AddMember(kPlatformBrightness, kPlatformBrightnessLight,
80 allocator);
81 }
82 channel_->Send(settings);
83 }
84
85 void SettingsPlugin::StartWatching() {
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) {
93 WatchPreferredBrightnessChanged();
94 }
95 if (text_scale_factor_reg_hkey_ != nullptr) {
96 WatchTextScaleFactorChanged();
97 }
98 }
99
100 void SettingsPlugin::StopWatching() {
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
112 bool SettingsPlugin::GetAlwaysUse24HourFormat() {
113 return Prefer24HourTime(GetUserTimeFormat());
114 }
115
116 float SettingsPlugin::GetTextScaleFactor() {
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
131 SettingsPlugin::PlatformBrightness SettingsPlugin::GetPreferredBrightness() {
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
136 : SettingsPlugin::PlatformBrightness::kDark;
137 } else {
138 return GetThemeBrightness();
139 }
140 }
141
142 void SettingsPlugin::WatchPreferredBrightnessChanged() {
143 preferred_brightness_changed_watcher_ =
144 std::make_unique<EventWatcher>([this]() {
145 task_runner_->PostTask([this]() {
146 SendSettings();
147 WatchPreferredBrightnessChanged();
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
156 void SettingsPlugin::WatchTextScaleFactorChanged() {
157 text_scale_factor_changed_watcher_ = std::make_unique<EventWatcher>([this]() {
158 task_runner_->PostTask([this]() {
159 SendSettings();
160 WatchTextScaleFactorChanged();
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
169 void SettingsPlugin::UpdateHighContrastMode(bool is_high_contrast) {
170 is_high_contrast_ = is_high_contrast;
171 SendSettings();
172 }
173
174 } // namespace flutter
flutter::BasicMessageChannel
Definition: basic_message_channel.h:56
flutter::BinaryMessenger
Definition: binary_messenger.h:28
flutter::JsonMessageCodec
Definition: json_message_codec.h:16
flutter::SettingsPlugin::PlatformBrightness
PlatformBrightness
Definition: settings_plugin.h:27
flutter::SettingsPlugin::PlatformBrightness::kDark
@ kDark
flutter::SettingsPlugin::PlatformBrightness::kLight
@ kLight
flutter::SettingsPlugin::~SettingsPlugin
virtual ~SettingsPlugin()
Definition: settings_plugin.cc:65
flutter::SettingsPlugin::is_high_contrast_
bool is_high_contrast_
Definition: settings_plugin.h:62
flutter::SettingsPlugin::StartWatching
virtual void StartWatching()
Definition: settings_plugin.cc:85
flutter::SettingsPlugin::UpdateHighContrastMode
virtual void UpdateHighContrastMode(bool is_high_contrast)
Definition: settings_plugin.cc:169
flutter::SettingsPlugin::WatchPreferredBrightnessChanged
virtual void WatchPreferredBrightnessChanged()
Definition: settings_plugin.cc:142
flutter::SettingsPlugin::GetAlwaysUse24HourFormat
virtual bool GetAlwaysUse24HourFormat()
Definition: settings_plugin.cc:112
flutter::SettingsPlugin::SendSettings
void SendSettings()
Definition: settings_plugin.cc:69
flutter::SettingsPlugin::GetPreferredBrightness
virtual PlatformBrightness GetPreferredBrightness()
Definition: settings_plugin.cc:131
flutter::SettingsPlugin::SettingsPlugin
SettingsPlugin(BinaryMessenger *messenger, TaskRunner *task_runner)
Definition: settings_plugin.cc:57
flutter::SettingsPlugin::WatchTextScaleFactorChanged
virtual void WatchTextScaleFactorChanged()
Definition: settings_plugin.cc:156
flutter::SettingsPlugin::GetTextScaleFactor
virtual float GetTextScaleFactor()
Definition: settings_plugin.cc:116
flutter::SettingsPlugin::StopWatching
virtual void StopWatching()
Definition: settings_plugin.cc:100
flutter::TaskRunner
Definition: task_runner.h:26
flutter::TaskRunner::PostTask
void PostTask(TaskClosure task)
Definition: task_runner.cc:88
kChannelName
static constexpr char kChannelName[]
Definition: cursor_handler.cc:13
json_message_codec.h
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::GetUserTimeFormat
std::wstring GetUserTimeFormat()
Definition: system_utils.cc:101
flutter::Prefer24HourTime
bool Prefer24HourTime(std::wstring time_format)
Definition: system_utils.cc:113
settings_plugin.h
system_utils.h