settings_ui: Expose background image settings on the Appearance page

Adds Image Path, Fit and Opacity controls to the Appearance settings page
so the workspace background image can be configured in-app instead of
editing settings JSON.
This commit is contained in:
yenru0 committed 2026-09-03 11:20:07 +09:00
1 parent 4c94072003
commit 46d3b70e76
3 files changed
+66 -1

No files matched your search

@@ -4,9 +4,9 @@ use settings_macros::MergeFrom;
/// Determines how the workspace background image is fitted into the window bounds. /// Determines how the workspace background image is fitted into the window bounds.
/// ///
/// Default: cover
#[derive( #[derive(
Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom, Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom,
strum::VariantArray, strum::VariantNames,
)] )]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum BackgroundImageFit { pub enum BackgroundImageFit {
+64
View File
@@ -1530,6 +1530,69 @@ fn appearance_page() -> SettingsPage {
] ]
} }
fn background_image_section() -> [SettingsPageItem; 4] {
[
SettingsPageItem::SectionHeader("Background Image"),
SettingsPageItem::SettingItem(SettingItem {
title: "Image Path",
description: "Path to the image displayed behind the workspace UI. `~` and environment variables are expanded. Leave empty to disable.",
field: Box::new(SettingField {
organization_override: None,
json_path: Some("background.path"),
pick: |settings_content| {
settings_content.background.as_ref()?.path.as_ref()
},
write: |settings_content, value, _| {
settings_content
.background
.get_or_insert_default()
.path = value;
},
}),
metadata: None,
files: USER,
}),
SettingsPageItem::SettingItem(SettingItem {
title: "Fit",
description: "How the image is fitted into the workspace bounds.",
field: Box::new(SettingField {
organization_override: None,
json_path: Some("background.fit"),
pick: |settings_content| {
settings_content.background.as_ref()?.fit.as_ref()
},
write: |settings_content, value, _| {
settings_content
.background
.get_or_insert_default()
.fit = value;
},
}),
metadata: None,
files: USER,
}),
SettingsPageItem::SettingItem(SettingItem {
title: "Opacity",
description: "Opacity of the background image, between 0.0 (fully transparent) and 1.0 (fully opaque).",
field: Box::new(SettingField {
organization_override: None,
json_path: Some("background.opacity"),
pick: |settings_content| {
settings_content.background.as_ref()?.opacity.as_ref()
},
write: |settings_content, value, _| {
settings_content
.background
.get_or_insert_default()
.opacity = value;
},
}),
metadata: None,
files: USER,
}),
]
}
let items: Box<[SettingsPageItem]> = concat_sections!( let items: Box<[SettingsPageItem]> = concat_sections!(
theme_section(), theme_section(),
buffer_font_section(), buffer_font_section(),
@@ -1540,6 +1603,7 @@ fn appearance_page() -> SettingsPage {
cursor_section(), cursor_section(),
highlighting_section(), highlighting_section(),
guides_section(), guides_section(),
background_image_section(),
); );
SettingsPage { SettingsPage {
+1
View File
@@ -674,6 +674,7 @@ fn init_renderers(cx: &mut App) {
.add_basic_renderer::<settings::AudioInputDeviceName>(render_input_audio_device_dropdown) .add_basic_renderer::<settings::AudioInputDeviceName>(render_input_audio_device_dropdown)
.add_basic_renderer::<settings::AudioOutputDeviceName>(render_output_audio_device_dropdown) .add_basic_renderer::<settings::AudioOutputDeviceName>(render_output_audio_device_dropdown)
.add_basic_renderer::<settings::TerminalBell>(render_dropdown) .add_basic_renderer::<settings::TerminalBell>(render_dropdown)
.add_basic_renderer::<settings::BackgroundImageFit>(render_dropdown)
// please semicolon stay on next line // please semicolon stay on next line
; ;
} }