7#include "theme_mode.hpp"
8#include "subpixel_orientation.hpp"
9#include "../i18n/i18n.hpp"
10#include "../geometry/geometry.hpp"
11#include "../utility/utility.hpp"
12#include "../numeric/numeric.hpp"
13#include "../observer/observer.hpp"
14#include "../dispatch/dispatch.hpp"
15#include "../concurrency/concurrency.hpp"
16#include "../telemetry/telemetry.hpp"
17#include "../time/time.hpp"
18#include "../char_maps/char_maps.hpp"
19#include "../macros.hpp"
23#include <system_error>
27hi_export_module(hikogui.settings.os_settings : intf);
39 hi_axiom(_populated.load(std::memory_order::acquire));
40 auto const lock = std::scoped_lock(_mutex);
41 return _language_tags;
50 hi_axiom(_populated.load(std::memory_order::acquire));
51 auto const lock = std::scoped_lock(_mutex);
62 hi_axiom(_populated.load(std::memory_order::acquire));
63 return _left_to_right.load(std::memory_order::relaxed);
73 return left_to_right() ? rhs : mirror(rhs);
83 return left_to_right() ? rhs : mirror(rhs);
88 [[nodiscard]]
static hi::theme_mode
theme_mode() noexcept
90 hi_axiom(_populated.load(std::memory_order::acquire));
91 return _theme_mode.load(std::memory_order::relaxed);
98 hi_axiom(_populated.load(std::memory_order::acquire));
99 return _subpixel_orientation.load(std::memory_order::relaxed);
114 hi_axiom(_populated.load(std::memory_order::acquire));
115 return _uniform_HDR.load(std::memory_order::relaxed);
122 hi_axiom(_populated.load(std::memory_order::acquire));
123 return _double_click_interval.load(std::memory_order::relaxed);
130 hi_axiom(_populated.load(std::memory_order::acquire));
131 return _double_click_distance.load(std::memory_order::relaxed);
140 hi_axiom(_populated.load(std::memory_order::acquire));
141 return _keyboard_repeat_delay.load(std::memory_order::relaxed);
150 hi_axiom(_populated.load(std::memory_order::acquire));
151 return _keyboard_repeat_interval.load(std::memory_order::relaxed);
160 hi_axiom(_populated.load(std::memory_order::acquire));
161 return _cursor_blink_delay.load(std::memory_order::relaxed);
171 hi_axiom(_populated.load(std::memory_order::acquire));
172 return _cursor_blink_interval.load(std::memory_order::relaxed);
181 hi_axiom(_populated.load(std::memory_order::acquire));
182 return _minimum_window_width.load(std::memory_order::relaxed);
191 hi_axiom(_populated.load(std::memory_order::acquire));
192 return _minimum_window_height.load(std::memory_order::relaxed);
201 hi_axiom(_populated.load(std::memory_order::acquire));
202 return _maximum_window_width.load(std::memory_order::relaxed);
211 hi_axiom(_populated.load(std::memory_order::acquire));
212 return _maximum_window_height.load(std::memory_order::relaxed);
221 hi_axiom(_populated.load(std::memory_order::acquire));
222 auto const lock = std::scoped_lock(_mutex);
223 return _primary_monitor_rectangle;
230 hi_axiom(_populated.load(std::memory_order::acquire));
231 return _primary_monitor_id.load(std::memory_order::relaxed);
240 hi_axiom(_populated.load(std::memory_order::acquire));
241 auto const lock = std::scoped_lock(_mutex);
242 return _desktop_rectangle;
251 return policy::unspecified;
260 hi_axiom(_populated.load(std::memory_order::acquire));
261 return _gpu_policy.load(std::memory_order::relaxed);
287 template<forward_of<
void()> Func>
288 [[nodiscard]]
static callback<void()> subscribe(Func &&func,
callback_flags flags = callback_flags::synchronous)
noexcept
290 auto const lock = std::scoped_lock(_mutex);
291 return _notifier.subscribe(std::forward<Func>(func), flags);
307 auto const lock = std::scoped_lock(_mutex);
308 auto setting_has_changed =
false;
310 auto const current_time = std::chrono::utc_clock::now();
311 if (current_time < _gather_last_time + gather_minimum_interval) {
314 _gather_last_time = current_time;
317 auto language_tags = gather_languages();
318 if (language_tags.empty()) {
320 language_tags.emplace_back(
"en-Latn-US");
324 language_tags = variants(language_tags);
326 if (compare_store(_language_tags, language_tags)) {
327 setting_has_changed =
true;
328 hi_log_info(
"OS language order has changed: {}", _language_tags);
331 hi_log_error(
"Failed to get OS language: {}", e.
what());
334 if (
auto optional_locale = gather_locale()) {
335 if (compare_store(_locale, *optional_locale)) {
336 setting_has_changed =
true;
337 hi_log_info(
"OS locale has changed: {}", _locale.name());
340 hi_log_error(
"Failed to get OS locale: {}", optional_locale.error().message());
343 if (compare_store(_left_to_right, gather_left_to_right())) {
344 setting_has_changed =
true;
345 hi_log_info(
"OS mirrored-GUI has changed: {}", not _left_to_right);
349 if (compare_store(_theme_mode, gather_theme_mode())) {
350 setting_has_changed =
true;
351 hi_log_info(
"OS theme-mode has changed: {}", _theme_mode.load());
354 hi_log_error(
"Failed to get OS theme-mode: {}", e.
what());
358 if (compare_store(_subpixel_orientation, gather_subpixel_orientation())) {
359 setting_has_changed =
true;
360 hi_log_info(
"OS sub-pixel orientation has changed: {}", _subpixel_orientation.load());
363 hi_log_error(
"Failed to get OS sub-pixel orientation: {}", e.
what());
367 if (compare_store(_uniform_HDR, gather_uniform_HDR())) {
368 setting_has_changed =
true;
369 hi_log_info(
"OS uniform-HDR has changed: {}", _uniform_HDR.load());
372 hi_log_error(
"Failed to get OS uniform-HDR: {}", e.
what());
376 if (compare_store(_double_click_interval, gather_double_click_interval())) {
377 setting_has_changed =
true;
378 hi_log_info(
"OS double click interval has changed: {}", _double_click_interval.load());
381 hi_log_error(
"Failed to get OS double click interval: {}", e.
what());
385 if (compare_store(_double_click_distance, gather_double_click_distance())) {
386 setting_has_changed =
true;
387 hi_log_info(
"OS double click distance has changed: {}", _double_click_distance.load());
390 hi_log_error(
"Failed to get OS double click distance: {}", e.
what());
394 if (compare_store(_keyboard_repeat_delay, gather_keyboard_repeat_delay())) {
395 setting_has_changed =
true;
396 hi_log_info(
"OS keyboard repeat delay has changed: {}", _keyboard_repeat_delay.load());
399 hi_log_error(
"Failed to get OS keyboard repeat delay: {}", e.
what());
403 if (compare_store(_keyboard_repeat_interval, gather_keyboard_repeat_interval())) {
404 setting_has_changed =
true;
405 hi_log_info(
"OS keyboard repeat interval has changed: {}", _keyboard_repeat_interval.load());
408 hi_log_error(
"Failed to get OS keyboard repeat interval: {}", e.
what());
412 if (compare_store(_cursor_blink_interval, gather_cursor_blink_interval())) {
413 setting_has_changed =
true;
415 hi_log_info(
"OS cursor blink interval has changed: {}", _cursor_blink_interval.load());
417 hi_log_info(
"OS cursor blink interval has changed: no-blinking");
421 hi_log_error(
"Failed to get OS cursor blink interval: {}", e.
what());
425 if (compare_store(_cursor_blink_delay, gather_cursor_blink_delay())) {
426 setting_has_changed =
true;
427 hi_log_info(
"OS cursor blink delay has changed: {}", _cursor_blink_delay.load());
430 hi_log_error(
"Failed to get OS cursor blink delay: {}", e.
what());
434 if (compare_store(_minimum_window_width, gather_minimum_window_width())) {
435 setting_has_changed =
true;
436 hi_log_info(
"OS minimum window width has changed: {}", _minimum_window_width.load());
439 hi_log_error(
"Failed to get OS minimum window width: {}", e.
what());
443 if (compare_store(_minimum_window_height, gather_minimum_window_height())) {
444 setting_has_changed =
true;
445 hi_log_info(
"OS minimum window height has changed: {}", _minimum_window_height.load());
448 hi_log_error(
"Failed to get OS minimum window height: {}", e.
what());
452 if (compare_store(_maximum_window_width, gather_maximum_window_width())) {
453 setting_has_changed =
true;
454 hi_log_info(
"OS maximum window width has changed: {}", _maximum_window_width.load());
457 hi_log_error(
"Failed to get OS maximum window width: {}", e.
what());
461 if (compare_store(_maximum_window_height, gather_maximum_window_height())) {
462 setting_has_changed =
true;
463 hi_log_info(
"OS maximum window height has changed: {}", _maximum_window_height.load());
466 hi_log_error(
"Failed to get OS maximum window height: {}", e.
what());
470 auto const primary_monitor_id = gather_primary_monitor_id();
471 if (compare_store(_primary_monitor_id, primary_monitor_id)) {
472 setting_has_changed =
true;
473 hi_log_info(
"OS primary monitor id has changed: {}, updating vsync source", primary_monitor_id);
474 loop::main().set_vsync_monitor_id(primary_monitor_id);
477 hi_log_error(
"Failed to get OS primary monitor id: {}", e.
what());
481 if (compare_store(_primary_monitor_rectangle, gather_primary_monitor_rectangle())) {
482 setting_has_changed =
true;
483 hi_log_info(
"OS primary monitor rectangle has changed: {}", _primary_monitor_rectangle);
486 hi_log_error(
"Failed to get OS primary monitor rectangle: {}", e.
what());
490 if (compare_store(_desktop_rectangle, gather_desktop_rectangle())) {
491 setting_has_changed =
true;
492 hi_log_info(
"OS desktop rectangle has changed: {}", _desktop_rectangle);
495 hi_log_error(
"Failed to get OS desktop rectangle: {}", e.
what());
499 if (compare_store(_gpu_policy, gather_gpu_policy())) {
500 setting_has_changed =
true;
501 hi_log_info(
"GPU policy has changed: {}", _gpu_policy.load());
504 hi_log_error(
"Failed to get the GPU policy: {}", e.
what());
507 _populated.store(
true, std::memory_order::release);
508 if (setting_has_changed) {
519 static inline unfair_mutex _mutex;
520 static inline utc_nanoseconds _gather_last_time;
522 static inline notifier<void()> _notifier;
541 static inline aarectangle _primary_monitor_rectangle = aarectangle{0.0f, 0.0f, 1920.0f, 1080.0f};
542 static inline aarectangle _desktop_rectangle = aarectangle{0.0f, 0.0f, 1920.0f, 1080.0f};
545 static inline callback<void()> _gather_cbt;
547 [[nodiscard]]
static bool subsystem_init() noexcept
549 _gather_cbt = loop::timer().repeat_function(gather_interval, [] {
550 os_settings::gather();
556 static void subsystem_deinit() noexcept
559 _gather_cbt =
nullptr;
564 [[nodiscard]] static
std::expected<
std::locale,
std::error_code> gather_locale() noexcept;
565 [[nodiscard]] static
bool gather_left_to_right() noexcept;
566 [[nodiscard]] static
hi::theme_mode gather_theme_mode();
567 [[nodiscard]] static
hi::subpixel_orientation gather_subpixel_orientation();
568 [[nodiscard]] static
bool gather_uniform_HDR();
569 [[nodiscard]] static
std::chrono::milliseconds gather_double_click_interval();
570 [[nodiscard]] static
float gather_double_click_distance();
571 [[nodiscard]] static
std::chrono::milliseconds gather_keyboard_repeat_delay();
572 [[nodiscard]] static
std::chrono::milliseconds gather_keyboard_repeat_interval();
573 [[nodiscard]] static
std::chrono::milliseconds gather_cursor_blink_interval();
574 [[nodiscard]] static
std::chrono::milliseconds gather_cursor_blink_delay();
575 [[nodiscard]] static
float gather_minimum_window_width();
576 [[nodiscard]] static
float gather_minimum_window_height();
577 [[nodiscard]] static
float gather_maximum_window_width();
578 [[nodiscard]] static
float gather_maximum_window_height();
579 [[nodiscard]] static uintptr_t gather_primary_monitor_id();
580 [[nodiscard]] static aarectangle gather_primary_monitor_rectangle();
581 [[nodiscard]] static aarectangle gather_desktop_rectangle();
582 [[nodiscard]] static
hi::policy gather_gpu_policy();
T::value_type start_subsystem(T &check_variable, typename T::value_type off_value, typename T::value_type(*init_function)(), void(*deinit_function)())
Start a sub-system.
Definition subsystem.hpp:117
horizontal_alignment
Horizontal alignment.
Definition alignment.hpp:102
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
callback_flags
Definition callback_flags.hpp:15
The HikoGUI namespace.
Definition recursive_iterator.hpp:15
policy
The performance policy to use.
Definition policy.hpp:18
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:378
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:26
Horizontal/Vertical alignment combination.
Definition alignment.hpp:244
Definition os_settings_intf.hpp:31
static std::chrono::milliseconds keyboard_repeat_delay() noexcept
Get the delay before the keyboard starts repeating.
Definition os_settings_intf.hpp:138
static aarectangle primary_monitor_rectangle() noexcept
Get the rectangle of the primary monitor.
Definition os_settings_intf.hpp:219
static bool start_subsystem() noexcept
Get the global os_settings instance.
Definition os_settings_intf.hpp:298
static hi::alignment alignment(hi::alignment rhs) noexcept
Get the alignment based on the writing direction.
Definition os_settings_intf.hpp:71
static float maximum_window_height() noexcept
The maximum height a window is allowed to be.
Definition os_settings_intf.hpp:209
static std::chrono::milliseconds keyboard_repeat_interval() noexcept
Get the keyboard repeat interval.
Definition os_settings_intf.hpp:148
static hi::subpixel_orientation subpixel_orientation() noexcept
Get the configured light/dark theme mode.
Definition os_settings_intf.hpp:96
static std::chrono::milliseconds cursor_blink_delay() noexcept
Get the cursor blink delay.
Definition os_settings_intf.hpp:158
static std::locale locale() noexcept
Get the current local.
Definition os_settings_intf.hpp:48
static aarectangle desktop_rectangle() noexcept
Get the rectangle describing the desktop.
Definition os_settings_intf.hpp:238
static void gather() noexcept
Gather the settings from the operating system now.
Definition os_settings_intf.hpp:305
static float double_click_distance() noexcept
Get the distance from the previous mouse position to detect double click.
Definition os_settings_intf.hpp:128
static uintptr_t primary_monitor_id() noexcept
Get an opaque id of the primary monitor.
Definition os_settings_intf.hpp:228
static hi::policy policy() noexcept
Get the global performance policy.
Definition os_settings_intf.hpp:249
static float minimum_window_width() noexcept
The minimum width a window is allowed to be.
Definition os_settings_intf.hpp:179
static float maximum_window_width() noexcept
The maximum width a window is allowed to be.
Definition os_settings_intf.hpp:199
static bool left_to_right() noexcept
Check if the configured writing direction is left-to-right.
Definition os_settings_intf.hpp:60
static float minimum_window_height() noexcept
The minimum height a window is allowed to be.
Definition os_settings_intf.hpp:189
static std::chrono::milliseconds double_click_interval() noexcept
Get the mouse double click interval.
Definition os_settings_intf.hpp:120
static bool uniform_HDR() noexcept
Whether SDR and HDR application can coexists on the same display.
Definition os_settings_intf.hpp:112
static hi::horizontal_alignment alignment(hi::horizontal_alignment rhs) noexcept
Get the alignment based on the writing direction.
Definition os_settings_intf.hpp:81
static hi::policy gpu_policy() noexcept
Get the policy for selecting a GPU.
Definition os_settings_intf.hpp:258
static std::vector< language_tag > language_tags() noexcept
Get the language tags for the configured languages.
Definition os_settings_intf.hpp:37
static hi::theme_mode theme_mode() noexcept
Get the configured light/dark theme mode.
Definition os_settings_intf.hpp:88
static std::chrono::milliseconds cursor_blink_interval() noexcept
Get the cursor blink interval.
Definition os_settings_intf.hpp:169