From 16c4dde30d89d6872a723e3871e07a4c81e87774 Mon Sep 17 00:00:00 2001 From: Delvin Date: Fri, 17 Oct 2025 21:42:22 +1030 Subject: [PATCH 1/3] fix: allow inactive opacity to be configured in UI --- .../settings/src/settings_content/editor.rs | 25 ++++++++++++++++++ .../src/settings_content/workspace.rs | 5 ++-- crates/settings_ui/src/page_data.rs | 13 +++++----- crates/settings_ui/src/settings_ui.rs | 1 + crates/ui_input/src/number_field.rs | 26 ++++++++++++++++++- crates/workspace/src/pane_group.rs | 2 +- crates/workspace/src/workspace_settings.rs | 6 ++--- 7 files changed, 64 insertions(+), 14 deletions(-) diff --git a/crates/settings/src/settings_content/editor.rs b/crates/settings/src/settings_content/editor.rs index 171cb874fcdea2..7bc447346c8a20 100644 --- a/crates/settings/src/settings_content/editor.rs +++ b/crates/settings/src/settings_content/editor.rs @@ -803,3 +803,28 @@ impl Display for MinimumContrast { write!(f, "{:.1}", self.0) } } + +/// Opacity of the inactive panes. 0 means transparent, 1 means opaque. +/// +/// Valid range: 0.0 to 1.0 +/// Default: 1.0 +#[derive( + Clone, + Copy, + Debug, + Serialize, + Deserialize, + JsonSchema, + MergeFrom, + PartialEq, + PartialOrd, + derive_more::FromStr, +)] +#[serde(transparent)] +pub struct InactiveOpacity(pub f32); + +impl Display for InactiveOpacity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:.1}", self.0) + } +} diff --git a/crates/settings/src/settings_content/workspace.rs b/crates/settings/src/settings_content/workspace.rs index 21b25d6d3c47fb..7ebb468f79bf19 100644 --- a/crates/settings/src/settings_content/workspace.rs +++ b/crates/settings/src/settings_content/workspace.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use settings_macros::MergeFrom; -use crate::{DockPosition, DockSide, ScrollbarSettingsContent, ShowIndentGuides}; +use crate::{DockPosition, DockSide, InactiveOpacity, ScrollbarSettingsContent, ShowIndentGuides}; #[skip_serializing_none] #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)] @@ -256,7 +256,8 @@ pub struct ActivePaneModifiers { /// Values are clamped to the [0.0, 1.0] range. /// /// Default: `1.0` - pub inactive_opacity: Option, + #[schemars(range(min = 0.0, max = 1.0))] + pub inactive_opacity: Option, } #[derive( diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index b54231580f269e..9faa2fd1aeb1f4 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -2642,13 +2642,12 @@ pub(crate) fn settings_data(cx: &App) -> Vec { title: "Inactive Opacity", description: "Opacity of inactive panels (0.0 - 1.0)", field: Box::new(SettingField { - pick: |settings_content| match settings_content - .workspace - .active_pane_modifiers - .as_ref() - { - Some(modifiers) => &modifiers.inactive_opacity, - None => &None, + pick: |settings_content| { + settings_content + .workspace + .active_pane_modifiers + .as_ref() + .map_or(&None, |modifiers| &modifiers.inactive_opacity) }, pick_mut: |settings_content| { &mut settings_content diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index 7c79a3719f829c..bb18f983caf826 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -421,6 +421,7 @@ fn init_renderers(cx: &mut App) { .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) + .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_dropdown) .add_basic_renderer::(render_dropdown) diff --git a/crates/ui_input/src/number_field.rs b/crates/ui_input/src/number_field.rs index 37ef4db53b2620..b72566947771be 100644 --- a/crates/ui_input/src/number_field.rs +++ b/crates/ui_input/src/number_field.rs @@ -8,7 +8,7 @@ use std::{ use editor::{Editor, EditorStyle}; use gpui::{ClickEvent, Entity, FocusHandle, Focusable, FontWeight, Modifiers}; -use settings::{CodeFade, MinimumContrast}; +use settings::{CodeFade, InactiveOpacity, MinimumContrast}; use ui::prelude::*; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] @@ -79,6 +79,30 @@ impl NumberFieldType for settings::CodeFade { } } +impl NumberFieldType for settings::InactiveOpacity { + fn default_step() -> Self { + InactiveOpacity(0.10) + } + fn large_step() -> Self { + InactiveOpacity(0.20) + } + fn small_step() -> Self { + InactiveOpacity(0.05) + } + fn min_value() -> Self { + InactiveOpacity(0.0) + } + fn max_value() -> Self { + InactiveOpacity(1.0) + } + fn saturating_add(self, rhs: Self) -> Self { + InactiveOpacity((self.0 + rhs.0).min(Self::max_value().0)) + } + fn saturating_sub(self, rhs: Self) -> Self { + InactiveOpacity((self.0 - rhs.0).max(Self::min_value().0)) + } +} + impl NumberFieldType for settings::MinimumContrast { fn default_step() -> Self { MinimumContrast(1.0) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 88ec56de6fa2e8..36898b127bdd74 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -1306,7 +1306,7 @@ mod element { let overlay_opacity = WorkspaceSettings::get(None, cx) .active_pane_modifiers .inactive_opacity - .map(|val| val.clamp(0.0, 1.0)) + .map(|val| val.0.clamp(0.0, 1.0)) .and_then(|val| (val <= 1.).then_some(val)); let mut overlay_background = cx.theme().colors().editor_background; diff --git a/crates/workspace/src/workspace_settings.rs b/crates/workspace/src/workspace_settings.rs index 541194b0044dd8..4463a3db410d39 100644 --- a/crates/workspace/src/workspace_settings.rs +++ b/crates/workspace/src/workspace_settings.rs @@ -4,11 +4,11 @@ use crate::DockPosition; use collections::HashMap; use serde::Deserialize; pub use settings::AutosaveSetting; -use settings::Settings; pub use settings::{ BottomDockLayout, PaneSplitDirectionHorizontal, PaneSplitDirectionVertical, RestoreOnStartupBehavior, }; +use settings::{InactiveOpacity, Settings}; pub struct WorkspaceSettings { pub active_pane_modifiers: ActivePanelModifiers, @@ -50,7 +50,7 @@ pub struct ActivePanelModifiers { /// /// Default: `1.0` // TODO: make this not an option, it is never None - pub inactive_opacity: Option, + pub inactive_opacity: Option, } #[derive(Deserialize)] @@ -124,7 +124,7 @@ impl Settings for WorkspaceSettings { .workspace .active_pane_modifiers .get_or_insert_default() - .inactive_opacity = Some(opacity as f32); + .inactive_opacity = Some(InactiveOpacity(opacity as f32)) } vscode.enum_setting( From 28db1b3791749b0f492ec5b1475127c3b3368b77 Mon Sep 17 00:00:00 2001 From: Danilo Leal Date: Fri, 17 Oct 2025 19:28:37 -0300 Subject: [PATCH 2/3] Add changes post merge with main --- crates/settings/src/vscode_import.rs | 2 +- crates/settings_ui/src/settings_ui.rs | 1 + crates/workspace/src/workspace_settings.rs | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/settings/src/vscode_import.rs b/crates/settings/src/vscode_import.rs index cc55613c63ef7d..13cabe9c3db955 100644 --- a/crates/settings/src/vscode_import.rs +++ b/crates/settings/src/vscode_import.rs @@ -843,7 +843,7 @@ impl VsCodeSettings { { Some(ActivePaneModifiers { border_size: None, - inactive_opacity: Some(opacity), + inactive_opacity: Some(InactiveOpacity(opacity as f32)), }) } else { None diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index 2cd18d0a3da34f..7856164a12a346 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -418,6 +418,7 @@ fn init_renderers(cx: &mut App) { .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) + .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_dropdown) .add_basic_renderer::(render_dropdown) diff --git a/crates/workspace/src/workspace_settings.rs b/crates/workspace/src/workspace_settings.rs index ffa6767427d150..6ed2aeb5cb85ae 100644 --- a/crates/workspace/src/workspace_settings.rs +++ b/crates/workspace/src/workspace_settings.rs @@ -4,11 +4,11 @@ use crate::DockPosition; use collections::HashMap; use serde::Deserialize; pub use settings::AutosaveSetting; -use settings::Settings; pub use settings::{ BottomDockLayout, PaneSplitDirectionHorizontal, PaneSplitDirectionVertical, RestoreOnStartupBehavior, }; +use settings::{InactiveOpacity, Settings}; pub struct WorkspaceSettings { pub active_pane_modifiers: ActivePanelModifiers, @@ -50,7 +50,7 @@ pub struct ActivePanelModifiers { /// /// Default: `1.0` // TODO: make this not an option, it is never None - pub inactive_opacity: Option, + pub inactive_opacity: Option, } #[derive(Deserialize)] From ccb584b6a238af0a346f5b6ed23630a7a70afe0e Mon Sep 17 00:00:00 2001 From: Danilo Leal Date: Fri, 17 Oct 2025 19:35:17 -0300 Subject: [PATCH 3/3] Fix clippy --- crates/settings/src/vscode_import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/settings/src/vscode_import.rs b/crates/settings/src/vscode_import.rs index 13cabe9c3db955..e1cce43f6227bb 100644 --- a/crates/settings/src/vscode_import.rs +++ b/crates/settings/src/vscode_import.rs @@ -843,7 +843,7 @@ impl VsCodeSettings { { Some(ActivePaneModifiers { border_size: None, - inactive_opacity: Some(InactiveOpacity(opacity as f32)), + inactive_opacity: Some(InactiveOpacity(opacity)), }) } else { None