diff --git a/dash-frontend/assets/gui/view/popup_window.xml b/dash-frontend/assets/gui/view/popup_window.xml
index 88245458..fca9b563 100644
--- a/dash-frontend/assets/gui/view/popup_window.xml
+++ b/dash-frontend/assets/gui/view/popup_window.xml
@@ -23,7 +23,7 @@
diff --git a/dash-frontend/assets/lang/de.json b/dash-frontend/assets/lang/de.json
index 4692b502..f671d5ad 100644
--- a/dash-frontend/assets/lang/de.json
+++ b/dash-frontend/assets/lang/de.json
@@ -191,7 +191,6 @@
"COLOR_PALETTES": "Farbpaletten",
"COLOR_PALETTE_CURRENT": "Derzeit aktives Thema.",
"COLOR_PALETTE_ACTIVATE": "Klicken Sie hier, um dieses Thema zu verwenden.",
- "APPLY_CHANGES_RESTART": "WayVR neu starten, um die Änderungen zu übernehmen?",
"COLOR_PALETTE_HELP": "Klicken, um Farbpaletten zu durchsuchen.\nUm eigene zu erstellen, besuche die Webseite!",
"COLOR_PALETTE_CUSTOM_URL": "Füge dein eigenes benutzerdefiniertes Thema hinzu!",
"COLOR_PALETTE_CUSTOM_URL2": "Klicken Sie hier, um das Web-Handbuch zu öffnen.",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "Aus Favoriten entfernen",
"EMPTY": "Leer",
"PINNED_APPS": "Angepinnte Anwendungen"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json
index 3fc32f94..53a831ca 100644
--- a/dash-frontend/assets/lang/en.json
+++ b/dash-frontend/assets/lang/en.json
@@ -103,7 +103,6 @@
"COLOR_PALETTE_CUSTOM_URL": "Add your own custom theme!",
"COLOR_PALETTE_CUSTOM_URL2": "Click to open web manual.",
"COLOR_PALETTE_ACTIVATE": "Click to use this theme.",
- "APPLY_CHANGES_RESTART": "Restart WayVR to apply changes?",
"CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens",
"CLEAR_PIPEWIRE_TOKENS_HELP": "Prompt for screen selection on next start",
"CLEAR_SAVED_STATE": "Clear saved state",
diff --git a/dash-frontend/assets/lang/es.json b/dash-frontend/assets/lang/es.json
index 3e95ba63..883a4602 100644
--- a/dash-frontend/assets/lang/es.json
+++ b/dash-frontend/assets/lang/es.json
@@ -191,7 +191,6 @@
"COLOR_PALETTES": "Paletas de colores",
"COLOR_PALETTE_CURRENT": "Tema actualmente activo.",
"COLOR_PALETTE_ACTIVATE": "Haz clic para usar este tema.",
- "APPLY_CHANGES_RESTART": "¿Reiniciar WayVR para aplicar los cambios?",
"COLOR_PALETTE_HELP": "Haz clic para explorar paletas de colores.\nPara crear paletas personalizadas, ¡visita el sitio web!",
"COLOR_PALETTE_CUSTOM_URL": "¡Añade tu propio tema personalizado!",
"COLOR_PALETTE_CUSTOM_URL2": "Haz clic para abrir el manual web.",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "Eliminar de favoritos",
"EMPTY": "Vacío",
"PINNED_APPS": "Aplicaciones ancladas"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/assets/lang/it.json b/dash-frontend/assets/lang/it.json
index 37e0bdc6..1eb9b658 100644
--- a/dash-frontend/assets/lang/it.json
+++ b/dash-frontend/assets/lang/it.json
@@ -212,7 +212,6 @@
"COLOR_PALETTES": "Tavolozze colori",
"COLOR_PALETTE_CURRENT": "Tema attualmente attivo.",
"COLOR_PALETTE_ACTIVATE": "Clicca per usare questo tema.",
- "APPLY_CHANGES_RESTART": "Riavviare WayVR per applicare le modifiche?",
"COLOR_PALETTE_HELP": "Clicca per sfogliare le palette di colori.\nPer crearne di personalizzate, visita il sito web!",
"COLOR_PALETTE_CUSTOM_URL": "Aggiungi il tuo tema personalizzato!",
"COLOR_PALETTE_CUSTOM_URL2": "Clicca per aprire il manuale web.",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "Rimuovi dai preferiti",
"EMPTY": "Vuoto",
"PINNED_APPS": "Applicazioni fissate"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/assets/lang/ja.json b/dash-frontend/assets/lang/ja.json
index 04618528..6dbb6ca4 100644
--- a/dash-frontend/assets/lang/ja.json
+++ b/dash-frontend/assets/lang/ja.json
@@ -191,7 +191,6 @@
"COLOR_PALETTES": "カラーパレット",
"COLOR_PALETTE_CURRENT": "現在有効なテーマ。",
"COLOR_PALETTE_ACTIVATE": "クリックしてこのテーマを適用します。",
- "APPLY_CHANGES_RESTART": "変更を適用するためにWayVRを再起動しますか?",
"COLOR_PALETTE_HELP": "クリックしてカラーパレットを選択してください。\nカスタムパレットの作成については、ウェブサイトを参照してください!",
"COLOR_PALETTE_CUSTOM_URL": "カスタムテーマを追加しましょう!",
"COLOR_PALETTE_CUSTOM_URL2": "クリックしてウェブマニュアルを開く。",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "お気に入りから削除",
"EMPTY": "空",
"PINNED_APPS": "ピン留めされたアプリケーション"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json
index 585ffdbb..aa372bd0 100644
--- a/dash-frontend/assets/lang/pl.json
+++ b/dash-frontend/assets/lang/pl.json
@@ -186,7 +186,6 @@
"COLOR_PALETTES": "Palety kolorów",
"COLOR_PALETTE_CURRENT": "Obecnie aktywny motyw.",
"COLOR_PALETTE_ACTIVATE": "Kliknij, aby użyć tego motywu.",
- "APPLY_CHANGES_RESTART": "Zrestartować WayVR, aby zastosować zmiany?",
"COLOR_PALETTE_HELP": "Kliknij, aby przeglądać palety kolorów.\nAby stworzyć własne, odwiedź stronę internetową!",
"COLOR_PALETTE_CUSTOM_URL": "Dodaj własny motyw!",
"COLOR_PALETTE_CUSTOM_URL2": "Kliknij, aby otworzyć instrukcję internetową.",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "Usuń z ulubionych",
"EMPTY": "Puste",
"PINNED_APPS": "Przypięte aplikacje"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/assets/lang/zh_CN.json b/dash-frontend/assets/lang/zh_CN.json
index 08107d48..a9437312 100644
--- a/dash-frontend/assets/lang/zh_CN.json
+++ b/dash-frontend/assets/lang/zh_CN.json
@@ -212,7 +212,6 @@
"COLOR_PALETTES": "配色方案",
"COLOR_PALETTE_CURRENT": "当前激活的主题。",
"COLOR_PALETTE_ACTIVATE": "点击以使用此主题。",
- "APPLY_CHANGES_RESTART": "重启 WayVR 以应用更改吗?",
"COLOR_PALETTE_HELP": "点击浏览配色方案。\n如需创建自定义配色,请参阅网站!",
"COLOR_PALETTE_CUSTOM_URL": "添加自定义主题!",
"COLOR_PALETTE_CUSTOM_URL2": "点击打开网页版手册。",
@@ -329,4 +328,4 @@
"REMOVE_FROM_FAVOURITES": "从收藏中移除",
"EMPTY": "空",
"PINNED_APPS": "已固定应用程序"
-}
\ No newline at end of file
+}
diff --git a/dash-frontend/src/tab/settings/tab_look_and_feel.rs b/dash-frontend/src/tab/settings/tab_look_and_feel.rs
index a8245f24..bc264bb0 100644
--- a/dash-frontend/src/tab/settings/tab_look_and_feel.rs
+++ b/dash-frontend/src/tab/settings/tab_look_and_feel.rs
@@ -11,7 +11,7 @@ use wgui::{
use crate::{
frontend::FrontendTasks,
tab::settings::{
- SettingType, SettingsMountParams, SettingsTab, Task as SettingsTask, horiz_cell,
+ SettingType, SettingsMountParams, SettingsTab, horiz_cell,
macros::{options_category, options_checkbox, options_dropdown, options_slider_f32},
mount_requires_restart,
},
@@ -29,7 +29,6 @@ pub struct State {
frontend_tasks: FrontendTasks,
globals: WguiGlobals,
tasks: Tasks
,
- settings_tasks: Tasks,
}
impl SettingsTab for State {
@@ -43,7 +42,6 @@ impl SettingsTab for State {
self.frontend_tasks.clone(),
self.globals.clone(),
self.popup_color_palettes.clone(),
- self.settings_tasks.clone(),
par.general_config.color_palette.clone(),
);
}
@@ -81,7 +79,6 @@ impl State {
frontend_tasks: par.frontend_tasks.clone(),
globals: par.mp.doc_params.globals.clone(),
tasks,
- settings_tasks: par.mp.tasks.clone(),
})
}
}
diff --git a/dash-frontend/src/views/color_palettes.rs b/dash-frontend/src/views/color_palettes.rs
index 9bfd222e..26e368d6 100644
--- a/dash-frontend/src/views/color_palettes.rs
+++ b/dash-frontend/src/views/color_palettes.rs
@@ -1,11 +1,16 @@
+use crate::{
+ frontend::{FrontendTask, FrontendTasks},
+ util::popup_manager::{MountPopupOnceParams, PopupHolder},
+ views::{ViewTrait, ViewUpdateParams},
+};
use std::{rc::Rc, sync::Arc};
+use wgui::color::WguiColorName;
use wgui::{
assets::AssetPath,
- color::WguiColorName,
components::button::ComponentButton,
globals::WguiGlobals,
i18n::Translation,
- layout::{Layout, WidgetID},
+ layout::{Layout, LayoutTask, WidgetID},
log::LogErr,
palette::PALETTES,
parser::{Fetchable, ParseDocumentParams, TemplateParams},
@@ -16,19 +21,10 @@ use wlx_common::{
palette::{list_palette_files, load_custom_palette},
};
-use crate::{
- frontend::{FrontendTask, FrontendTasks},
- tab::settings::Task as SettingsTask,
- util::popup_manager::{MountPopupOnceParams, PopupHolder},
- views::{self, ViewTrait, ViewUpdateParams},
-};
-
#[derive(Clone)]
enum Task {
SelectPalette(String),
CustomPaletteUrl,
- Restart,
- Cancel,
}
pub struct Params<'a> {
@@ -36,40 +32,30 @@ pub struct Params<'a> {
pub layout: &'a mut Layout,
pub parent_id: WidgetID,
pub frontend_tasks: &'a FrontendTasks,
- pub settings_tasks: Tasks,
+ pub on_close_request: Box,
pub current_palette: Arc,
}
pub struct View {
tasks: Tasks,
frontend_tasks: FrontendTasks,
- globals: WguiGlobals,
- popup_dialog: PopupHolder,
- settings_tasks: Tasks,
- chosen_palette: Option>,
+ on_close_request: Option>,
}
impl ViewTrait for View {
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
- self.popup_dialog.update(par)?;
-
for task in self.tasks.drain() {
match task {
Task::SelectPalette(profile) => {
- self.chosen_palette = Some(profile.into());
- self.show_restart_dialog_box()?;
- }
- Task::Cancel => {
- let close_dialog = self.popup_dialog.get_close_callback(par.layout);
- close_dialog();
- }
- Task::Restart => {
- if let Some(palette) = self.chosen_palette.take() {
- par.general_config.color_palette = palette;
- par.config_change_kind.replace(ConfigChangeKind::WguiThemeChange);
+ let mut globals = par.layout.state.globals.get();
+ let new_palette = wlx_common::palette::load_palette(&profile);
+ globals.palette = new_palette;
+ par.general_config.color_palette = profile.into();
+ par.layout.tasks.push(LayoutTask::RefreshPalette);
+ par.config_change_kind.replace(ConfigChangeKind::WguiColorPaletteChange);
+ if let Some(c) = self.on_close_request.take() {
+ c();
}
-
- self.settings_tasks.push(SettingsTask::RestartSoftware);
}
Task::CustomPaletteUrl => {
self.frontend_tasks.push(FrontendTask::OpenURL(
@@ -113,7 +99,6 @@ impl View {
let list_parent = parser_state.fetch_widget(¶ms.layout.state, "list_parent")?.id;
let tasks = Tasks::new();
- let popup_dialog = PopupHolder::::default();
for (idx, name) in list_palette_files().into_iter().enumerate() {
let Ok(palette) = load_custom_palette(&name).log_warn("Could not load custom color palette") else {
@@ -246,58 +231,15 @@ impl View {
Ok(Self {
tasks,
frontend_tasks: params.frontend_tasks.clone(),
- globals: params.globals.clone(),
- popup_dialog,
- settings_tasks: params.settings_tasks,
- chosen_palette: None,
+ on_close_request: Some(params.on_close_request),
})
}
-
- fn show_restart_dialog_box(&mut self) -> anyhow::Result<()> {
- const ACTION_RESTART: &str = "restart";
- const ACTION_CANCEL: &str = "cancel";
-
- let tasks = self.tasks.clone();
-
- views::dialog_box::mount_popup(
- self.popup_dialog.clone(),
- self.frontend_tasks.clone(),
- views::dialog_box::Params {
- globals: self.globals.clone(),
- message: Translation::from_translation_key("APP_SETTINGS.APPLY_CHANGES_RESTART"),
- entries: vec![
- views::dialog_box::ButtonEntry {
- content: Translation::from_translation_key("APP_SETTINGS.CANCEL"),
- icon: "dashboard/close.svg",
- action: ACTION_CANCEL,
- },
- views::dialog_box::ButtonEntry {
- content: Translation::from_translation_key("APP_SETTINGS.RESTART_SOFTWARE"),
- icon: "dashboard/refresh.svg",
- action: ACTION_RESTART,
- },
- ],
- on_action_click: Box::new(move |action| match action {
- ACTION_RESTART => {
- tasks.push(Task::Restart);
- }
- ACTION_CANCEL => {
- tasks.push(Task::Cancel);
- }
- _ => unreachable!(),
- }),
- },
- );
-
- Ok(())
- }
}
pub fn mount_popup(
frontend_tasks: FrontendTasks,
globals: WguiGlobals,
popup: PopupHolder,
- settings_tasks: Tasks,
current_palette: Arc,
) {
frontend_tasks
@@ -305,13 +247,14 @@ pub fn mount_popup(
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
Translation::from_translation_key("APP_SETTINGS.COLOR_PALETTES"),
Box::new(move |data| {
+ let on_close_request = popup.get_close_callback(data.layout);
let view = View::new(Params {
globals: globals.clone(),
layout: data.layout,
parent_id: data.id_content,
frontend_tasks: &frontend_tasks,
- settings_tasks,
current_palette,
+ on_close_request,
})?;
popup.set_view(data.handle, view, None);
diff --git a/wayvr/src/backend/task.rs b/wayvr/src/backend/task.rs
index 7a145fa4..c2885ed7 100644
--- a/wayvr/src/backend/task.rs
+++ b/wayvr/src/backend/task.rs
@@ -107,6 +107,7 @@ pub enum SpawnPos {
pub enum GlobalChange {
Settings,
Keyboard,
+ ColorPalette,
}
pub type ModifyOverlayTask = dyn FnOnce(&mut AppState, &mut OverlayWindowConfig) + Send;
diff --git a/wayvr/src/gui/panel/mod.rs b/wayvr/src/gui/panel/mod.rs
index 88296dc6..bcd8ffff 100644
--- a/wayvr/src/gui/panel/mod.rs
+++ b/wayvr/src/gui/panel/mod.rs
@@ -29,7 +29,7 @@ use wgui::{
},
gfx::cmd::WGfxClearMode,
i18n::Translation,
- layout::{Layout, LayoutParams, LayoutUpdateParams, WidgetID},
+ layout::{Layout, LayoutParams, LayoutTask, LayoutUpdateParams, WidgetID},
parser::{self, CustomAttribsInfoOwned, Fetchable, ParseDocumentExtra, ParserState},
renderer_vk::{context::Context as WguiContext, text::custom_glyph::CustomGlyphData},
widget::{
@@ -360,6 +360,9 @@ impl OverlayBackend for GuiPanel {
}
fn notify(&mut self, app: &mut AppState, data: OverlayEventData) -> anyhow::Result<()> {
+ if let OverlayEventData::ColorPaletteRefresh = data {
+ self.layout.tasks.push(LayoutTask::RefreshPalette);
+ }
let Some(on_notify) = self.on_notify.take() else {
return Ok(());
};
diff --git a/wayvr/src/overlays/dashboard.rs b/wayvr/src/overlays/dashboard.rs
index b8301793..e3824542 100644
--- a/wayvr/src/overlays/dashboard.rs
+++ b/wayvr/src/overlays/dashboard.rs
@@ -538,11 +538,17 @@ impl DashInterface for DashInterfaceLive {
data.session.config_dirty = true;
match kind {
+ ConfigChangeKind::WguiColorPaletteChange => {
+ data.tasks
+ .enqueue(TaskType::Overlay(OverlayTask::GlobalChange(
+ GlobalChange::ColorPalette,
+ )));
+ }
ConfigChangeKind::OverlayConfig => {
data.tasks
.enqueue(TaskType::Overlay(OverlayTask::GlobalChange(
GlobalChange::Settings,
- )))
+ )));
}
ConfigChangeKind::EnvironmentBlend => {
#[cfg(feature = "openxr")]
diff --git a/wayvr/src/state.rs b/wayvr/src/state.rs
index c95f40f1..3b802e68 100644
--- a/wayvr/src/state.rs
+++ b/wayvr/src/state.rs
@@ -189,8 +189,6 @@ impl AppState {
)
.ok();
- let palette = load_palette(&*session.config.color_palette);
-
let mut app_state = Self {
tasks,
gfx,
@@ -208,7 +206,7 @@ impl AppState {
&lang_provider,
&WguiFontConfig::default(),
get_config_file_path(&theme_path),
- palette,
+ load_palette(&*session.config.color_palette),
)?,
wgui_theme: Rc::new(theme),
dbus,
diff --git a/wayvr/src/windowing/backend.rs b/wayvr/src/windowing/backend.rs
index f9bf7651..0ca522ba 100644
--- a/wayvr/src/windowing/backend.rs
+++ b/wayvr/src/windowing/backend.rs
@@ -130,6 +130,7 @@ pub enum OverlayEventData {
},
WvrCommand(WvrCommand),
ResizeRequest([u32; 2]),
+ ColorPaletteRefresh,
}
pub trait OverlayBackend: Any {
diff --git a/wayvr/src/windowing/manager.rs b/wayvr/src/windowing/manager.rs
index 02278935..596409bb 100644
--- a/wayvr/src/windowing/manager.rs
+++ b/wayvr/src/windowing/manager.rs
@@ -333,6 +333,20 @@ where
self.overlays_changed(app)?;
self.sets_changed(app);
}
+ OverlayTask::GlobalChange(GlobalChange::ColorPalette) => {
+ {
+ let mut globals = app.wgui_globals.get();
+ globals.palette =
+ wlx_common::palette::load_palette(&app.session.config.color_palette);
+ }
+
+ for o in self.overlays.values_mut() {
+ let _ = o
+ .config
+ .backend
+ .notify(app, OverlayEventData::ColorPaletteRefresh);
+ }
+ }
OverlayTask::CleanupMirrors => {
let mut ids_to_remove = vec![];
for (oid, o) in &self.overlays {
diff --git a/wgui/src/layout.rs b/wgui/src/layout.rs
index 8984261c..b57cea30 100644
--- a/wgui/src/layout.rs
+++ b/wgui/src/layout.rs
@@ -155,6 +155,7 @@ pub enum LayoutTask {
PlaySound(WguiSoundType),
Dispatch(LayoutDispatchFunc),
SetFocus(ComponentWeak),
+ RefreshPalette,
Unfocus,
}
@@ -748,6 +749,10 @@ impl Layout {
let mut tasks = self.tasks.drain();
while let Some(task) = tasks.pop_front() {
match task {
+ LayoutTask::RefreshPalette => {
+ let root = self.tree_root_widget;
+ LayoutState::refresh_palette_recur(&mut self.common(), root);
+ }
LayoutTask::RemoveWidget(widget_id) => {
self.remove_widget(widget_id);
}
@@ -1028,4 +1033,27 @@ impl LayoutState {
// safety: we just checked the type
unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0).cast())) }
}
+
+ fn refresh_palette_recur(common: &mut CallbackDataCommon, widget_id: WidgetID) {
+ if let Some(widget) = common.state.widgets.get(widget_id) {
+ widget.state().obj.palette_updated(common);
+ } else {
+ debug_assert!(false);
+ return;
+ }
+
+ let Some(node_id) = common.state.nodes.get(widget_id) else {
+ /* node/widget desync, this shouldn't happen */
+ debug_assert!(false);
+ return;
+ };
+
+ for child_node_id in common.state.tree.child_ids(*node_id) {
+ let Some(widget_id) = common.state.tree.get_node_context(child_node_id) else {
+ debug_assert!(false);
+ continue;
+ };
+ LayoutState::refresh_palette_recur(common, *widget_id);
+ }
+ }
}
diff --git a/wgui/src/palette.rs b/wgui/src/palette.rs
index ddd8b339..8490e5e3 100644
--- a/wgui/src/palette.rs
+++ b/wgui/src/palette.rs
@@ -22,7 +22,7 @@ impl WguiColorPalette {
}
log::warn!("No color palette with name '{palette_name}', using default colors.");
- return DEFAULT.clone();
+ DEFAULT.clone()
}
pub const fn from_inner(colors: [drawing::Color; WguiColorName::COUNT]) -> Self {
diff --git a/wgui/src/widget/label.rs b/wgui/src/widget/label.rs
index 834c6f9e..43474aca 100644
--- a/wgui/src/widget/label.rs
+++ b/wgui/src/widget/label.rs
@@ -129,11 +129,11 @@ impl WidgetLabel {
}
}
- pub fn get_color(&self) -> WguiColor {
+ pub const fn get_color(&self) -> WguiColor {
self.params.style.color.unwrap() // create_ex populates this
}
- pub fn parent_color(&self) -> ParentColor {
+ pub const fn parent_color(&self) -> ParentColor {
self.params.parent_color
}
}
@@ -188,6 +188,11 @@ impl WidgetObj for WidgetLabel {
})
}
+ fn palette_updated(&mut self, common: &mut CallbackDataCommon) {
+ let cur_color = self.get_color();
+ self.set_color(common, cur_color, true);
+ }
+
fn get_id(&self) -> WidgetID {
self.id
}
diff --git a/wgui/src/widget/mod.rs b/wgui/src/widget/mod.rs
index 3236cff6..d00e172d 100644
--- a/wgui/src/widget/mod.rs
+++ b/wgui/src/widget/mod.rs
@@ -191,6 +191,8 @@ pub trait WidgetObj: AnyTrait {
fn draw(&mut self, state: &mut DrawState, params: &DrawParams);
+ fn palette_updated(&mut self, _common: &mut CallbackDataCommon) {}
+
fn measure(
&mut self,
_globals: &Globals,
diff --git a/wlx-common/src/dash_interface.rs b/wlx-common/src/dash_interface.rs
index 8c63345b..420931a4 100644
--- a/wlx-common/src/dash_interface.rs
+++ b/wlx-common/src/dash_interface.rs
@@ -84,7 +84,7 @@ pub trait DashInterface {
pub enum ConfigChangeKind {
OverlayConfig,
EnvironmentBlend,
- WguiThemeChange, // TODO: does not do anything right now
+ WguiColorPaletteChange,
WvrServerConfig,
/// Marks the config for saving but doesn't notify any components
#[default]