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 
6 
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
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 
66  StopWatching();
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 
169 void SettingsPlugin::UpdateHighContrastMode(bool is_high_contrast) {
170  is_high_contrast_ = is_high_contrast;
171  SendSettings();
172 }
173 
174 } // namespace flutter
flutter::SettingsPlugin::PlatformBrightness
PlatformBrightness
Definition: settings_plugin.h:27
flutter::SettingsPlugin::PlatformBrightness::kLight
@ kLight
settings_plugin.h
flutter::SettingsPlugin::WatchTextScaleFactorChanged
virtual void WatchTextScaleFactorChanged()
Definition: settings_plugin.cc:156
flutter::SettingsPlugin::SendSettings
void SendSettings()
Definition: settings_plugin.cc:69
flutter::TaskRunner::PostTask
void PostTask(TaskClosure task)
Definition: task_runner.cc:88
flutter::GetUserTimeFormat
std::wstring GetUserTimeFormat()
Definition: system_utils.cc:101
system_utils.h
json_message_codec.h
flutter::SettingsPlugin::is_high_contrast_
bool is_high_contrast_
Definition: settings_plugin.h:62
flutter::Prefer24HourTime
bool Prefer24HourTime(std::wstring time_format)
Definition: system_utils.cc:113
flutter::BinaryMessenger
Definition: binary_messenger.h:28
flutter::SettingsPlugin::PlatformBrightness::kDark
@ kDark
flutter::SettingsPlugin::GetTextScaleFactor
virtual float GetTextScaleFactor()
Definition: settings_plugin.cc:116
flutter::BasicMessageChannel
Definition: basic_message_channel.h:56
flutter::SettingsPlugin::GetPreferredBrightness
virtual PlatformBrightness GetPreferredBrightness()
Definition: settings_plugin.cc:131
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::SettingsPlugin::~SettingsPlugin
virtual ~SettingsPlugin()
Definition: settings_plugin.cc:65
flutter::TaskRunner
Definition: task_runner.h:26
flutter::JsonMessageCodec
Definition: json_message_codec.h:16
flutter::SettingsPlugin::SettingsPlugin
SettingsPlugin(BinaryMessenger *messenger, TaskRunner *task_runner)
Definition: settings_plugin.cc:57
kChannelName
static constexpr char kChannelName[]
Definition: cursor_handler.cc:13
flutter::SettingsPlugin::UpdateHighContrastMode
virtual void UpdateHighContrastMode(bool is_high_contrast)
Definition: settings_plugin.cc:169
flutter::SettingsPlugin::StartWatching
virtual void StartWatching()
Definition: settings_plugin.cc:85
flutter::SettingsPlugin::StopWatching
virtual void StopWatching()
Definition: settings_plugin.cc:100
flutter::SettingsPlugin::GetAlwaysUse24HourFormat
virtual bool GetAlwaysUse24HourFormat()
Definition: settings_plugin.cc:112
flutter::SettingsPlugin::WatchPreferredBrightnessChanged
virtual void WatchPreferredBrightnessChanged()
Definition: settings_plugin.cc:142