diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 023b77ab8f340a8f46e306aa0578c4037090cdd0..17ee5087bb0e4ec28771e8d4a1cef7616f790a6e 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -68,6 +68,7 @@ impl Render for CollabTitlebarItem { h_stack() .id("titlebar") + .z_index(160) // todo!("z-index") .justify_between() .w_full() .h(rems(1.75)) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 0d477fc62d76c1c24371ad811f6e8143b05f627c..57fd3d6a8af274d305d37dbc4d2d62baba8ccbd3 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1447,7 +1447,14 @@ impl Interactivity { cx.on_action(action_type, listener) } - f(style, scroll_offset.unwrap_or_default(), cx) + cx.with_z_index(style.z_index.unwrap_or(0), |cx| { + if style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { + cx.add_opaque_layer(bounds) + } + f(style, scroll_offset.unwrap_or_default(), cx) + }) }, ); diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index 4f81f604c8d3799923b9fb76742019cb1724c0b5..ab7b8d914094b677b647123074883611665d263b 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::{ - point, size, Bounds, DevicePixels, Element, ImageData, InteractiveElement, + point, size, BorrowWindow, Bounds, DevicePixels, Element, ImageData, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId, Pixels, SharedString, Size, StyleRefinement, Styled, WindowContext, }; diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 68c068dfe98473872024097d3ca1745866fc66eb..811b2b6e30897f4fe23913e879608c02a26b98bd 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -856,56 +856,3 @@ impl Bounds { .expect("Polygon should not be empty") } } - -// #[cfg(test)] -// mod tests { -// use crate::{point, size}; - -// use super::*; -// use smallvec::smallvec; - -// #[test] -// fn test_scene() { -// let mut scene = SceneBuilder::new(); -// assert_eq!(scene.layers_by_order.len(), 0); - -// scene.insert(&smallvec![1].into(), quad()); -// scene.insert(&smallvec![2].into(), shadow()); -// scene.insert(&smallvec![3].into(), quad()); - -// let mut batches_count = 0; -// for _ in scene.build().batches() { -// batches_count += 1; -// } -// assert_eq!(batches_count, 3); -// } - -// fn quad() -> Quad { -// Quad { -// order: 0, -// bounds: Bounds { -// origin: point(ScaledPixels(0.), ScaledPixels(0.)), -// size: size(ScaledPixels(100.), ScaledPixels(100.)), -// }, -// content_mask: Default::default(), -// background: Default::default(), -// border_color: Default::default(), -// corner_radii: Default::default(), -// border_widths: Default::default(), -// } -// } - -// fn shadow() -> Shadow { -// Shadow { -// order: Default::default(), -// bounds: Bounds { -// origin: point(ScaledPixels(0.), ScaledPixels(0.)), -// size: size(ScaledPixels(100.), ScaledPixels(100.)), -// }, -// corner_radii: Default::default(), -// content_mask: Default::default(), -// color: Default::default(), -// blur_radius: Default::default(), -// } -// } -// } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index f7ebddd0fea2b725e45d798b1a75e1d76ed3b5f7..1b2669b40c5cc4d95018ab6ec4a827d551b79dac 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -39,24 +39,32 @@ use std::{ Arc, }, }; -use util::ResultExt; +use util::{post_inc, ResultExt}; const ACTIVE_DRAG_Z_INDEX: u8 = 1; /// A global stacking order, which is created by stacking successive z-index values. /// Each z-index will always be interpreted in the context of its parent z-index. -#[derive(Deref, DerefMut, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)] +#[derive(Deref, DerefMut, Clone, Ord, PartialOrd, PartialEq, Eq, Default)] pub struct StackingOrder { #[deref] #[deref_mut] - z_indices: SmallVec<[u8; 64]>, + context_stack: SmallVec<[u8; 64]>, + id: u32, } -impl Default for StackingOrder { - fn default() -> Self { - StackingOrder { - z_indices: SmallVec::new(), +impl std::fmt::Debug for StackingOrder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut stacks = self.context_stack.iter().peekable(); + write!(f, "[({}): ", self.id)?; + while let Some(z_index) = stacks.next() { + write!(f, "{z_index}")?; + if stacks.peek().is_some() { + write!(f, "->")?; + } } + write!(f, "]")?; + Ok(()) } } @@ -284,6 +292,7 @@ pub(crate) struct Frame { pub(crate) scene_builder: SceneBuilder, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, + pub(crate) next_stacking_order_id: u32, content_mask_stack: Vec>, element_offset_stack: Vec>, } @@ -297,6 +306,7 @@ impl Frame { dispatch_tree, scene_builder: SceneBuilder::default(), z_index_stack: StackingOrder::default(), + next_stacking_order_id: 0, depth_map: Default::default(), content_mask_stack: Vec::new(), element_offset_stack: Vec::new(), @@ -308,6 +318,7 @@ impl Frame { self.mouse_listeners.values_mut().for_each(Vec::clear); self.dispatch_tree.clear(); self.depth_map.clear(); + self.next_stacking_order_id = 0; } fn focus_path(&self) -> SmallVec<[FocusId; 8]> { @@ -928,15 +939,6 @@ impl<'a> WindowContext<'a> { self.window.requested_cursor_style = Some(style) } - /// Called during painting to invoke the given closure in a new stacking context. The given - /// z-index is interpreted relative to the previous call to `stack`. - pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - self.window.next_frame.z_index_stack.push(z_index); - let result = f(self); - self.window.next_frame.z_index_stack.pop(); - result - } - /// Called during painting to track which z-index is on top at each pixel position pub fn add_opaque_layer(&mut self, bounds: Bounds) { let stacking_order = self.window.next_frame.z_index_stack.clone(); @@ -2046,6 +2048,18 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { result } + /// Called during painting to invoke the given closure in a new stacking context. The given + /// z-index is interpreted relative to the previous call to `stack`. + fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { + let new_stacking_order_id = + post_inc(&mut self.window_mut().next_frame.next_stacking_order_id); + self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; + self.window_mut().next_frame.z_index_stack.push(z_index); + let result = f(self); + self.window_mut().next_frame.z_index_stack.pop(); + result + } + /// Update the global element offset relative to the current offset. This is used to implement /// scrolling. fn with_element_offset( @@ -2269,13 +2283,6 @@ impl<'a, V: 'static> ViewContext<'a, V> { &mut self.window_cx } - pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - self.window.next_frame.z_index_stack.push(z_index); - let result = f(self); - self.window.next_frame.z_index_stack.pop(); - result - } - pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext) + 'static) where V: 'static, diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index e9335a4220312d33eeb1fcab4670661d3f037ba3..07910896f31320d108e45490e3aab70c06a76fb1 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -1,11 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, - Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, - FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, - IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, - PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled, - TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, + BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, + FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, + Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, + Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, + Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index 7cff2f51bd80f4dc38df6b9e2423d1627024ea33..d2e6e9518bdae89bd31506f1c1d8fad4660881fa 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -96,6 +96,7 @@ impl RenderOnce for TabBar { div() .id(self.id) + .z_index(120) // todo!("z-index") .group("tab_bar") .flex() .flex_none() diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index cd25582f36cbd397688a500e85c0e405865dae63..7436232b04e556ebe8ed648363908471512d1585 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -105,6 +105,7 @@ impl Render for Toolbar { v_stack() .p_1() .gap_2() + .z_index(80) // todo!("z-index") .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background)