From bdabae0d12d51cd09286be0c6242cbce50ed2843 Mon Sep 17 00:00:00 2001 From: Cyandev Date: Thu, 31 Jul 2025 22:32:43 +0800 Subject: [PATCH] gpui: Fix opacity state management --- crates/gpui/src/window.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 6ebb1cac40..0eb92d46b4 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -835,7 +835,7 @@ pub struct Window { pub(crate) text_style_stack: Vec, pub(crate) rendered_entity_stack: Vec, pub(crate) element_offset_stack: Vec>, - pub(crate) element_opacity: Option, + pub(crate) element_opacity_stack: Vec, pub(crate) content_mask_stack: Vec>, pub(crate) requested_autoscroll: Option>, pub(crate) image_cache_stack: Vec, @@ -1146,7 +1146,7 @@ impl Window { rendered_entity_stack: Vec::new(), element_offset_stack: Vec::new(), content_mask_stack: Vec::new(), - element_opacity: None, + element_opacity_stack: Vec::new(), requested_autoscroll: None, rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), @@ -2361,14 +2361,16 @@ impl Window { opacity: Option, f: impl FnOnce(&mut Self) -> R, ) -> R { - if opacity.is_none() { - return f(self); - } - self.invalidator.debug_assert_paint_or_prepaint(); - self.element_opacity = opacity; + + let Some(opacity) = opacity else { + return f(self); + }; + + let opacity = self.element_opacity() * opacity; + self.element_opacity_stack.push(opacity); let result = f(self); - self.element_opacity = None; + self.element_opacity_stack.pop(); result } @@ -2467,7 +2469,7 @@ impl Window { /// prepaint phase of element drawing. pub(crate) fn element_opacity(&self) -> f32 { self.invalidator.debug_assert_paint_or_prepaint(); - self.element_opacity.unwrap_or(1.0) + self.element_opacity_stack.last().copied().unwrap_or(1.0) } /// Obtain the current content mask. This method should only be called during element drawing.