diff --git a/crates/ui/src/drawer.rs b/crates/ui/src/drawer.rs index 1535a6ed..df75a9f2 100644 --- a/crates/ui/src/drawer.rs +++ b/crates/ui/src/drawer.rs @@ -15,7 +15,9 @@ use crate::{ scroll::ScrollbarAxis, theme::ActiveTheme, title_bar::TITLE_BAR_HEIGHT, - v_flex, IconName, Placement, Sizable, StyledExt as _, + v_flex, + window_border::SHADOW_SIZE, + IconName, Placement, Sizable, StyledExt as _, }; actions!(drawer, [Escape]); @@ -119,11 +121,11 @@ impl RenderOnce for Drawer { fn render(self, cx: &mut WindowContext) -> impl IntoElement { let placement = self.placement; let titlebar_height = self.margin_top; - let size = cx.viewport_size(); + let size = cx.viewport_size() - gpui::size(SHADOW_SIZE * 2, SHADOW_SIZE * 2); let on_close = self.on_close.clone(); anchored() - .position(point(px(0.), titlebar_height)) + .position(point(px(0.) + SHADOW_SIZE, titlebar_height + SHADOW_SIZE)) .snap_to_window() .child( div() diff --git a/crates/ui/src/modal.rs b/crates/ui/src/modal.rs index 7685ae32..106739bb 100644 --- a/crates/ui/src/modal.rs +++ b/crates/ui/src/modal.rs @@ -1,7 +1,7 @@ use std::{rc::Rc, time::Duration}; use gpui::{ - actions, anchored, div, hsla, prelude::FluentBuilder, px, relative, Animation, + actions, anchored, div, hsla, point, prelude::FluentBuilder, px, relative, Animation, AnimationExt as _, AnyElement, AppContext, Bounds, ClickEvent, Div, FocusHandle, Hsla, InteractiveElement, IntoElement, KeyBinding, MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, Styled, WindowContext, @@ -11,7 +11,9 @@ use crate::{ animation::cubic_bezier, button::{Button, ButtonVariants as _}, theme::ActiveTheme as _, - v_flex, ContextModal, IconName, Sizable as _, + v_flex, + window_border::SHADOW_SIZE, + ContextModal, IconName, Sizable as _, }; actions!(modal, [Escape]); @@ -162,7 +164,7 @@ impl RenderOnce for Modal { fn render(self, cx: &mut WindowContext) -> impl gpui::IntoElement { let layer_ix = self.layer_ix; let on_close = self.on_close.clone(); - let view_size = cx.viewport_size(); + let view_size = cx.viewport_size() - gpui::size(SHADOW_SIZE * 2, SHADOW_SIZE * 2); let bounds = Bounds { origin: Point::default(), size: view_size, @@ -171,78 +173,83 @@ impl RenderOnce for Modal { let y = self.margin_top.unwrap_or(view_size.height / 10.) + offset_top; let x = bounds.center().x - self.width / 2.; - anchored().snap_to_window().child( - div() - .occlude() - .w(view_size.width) - .h(view_size.height) - .when(self.overlay_visible, |this| { - this.bg(overlay_color(self.overlay, cx)) - }) - .when(self.overlay, |this| { - this.on_mouse_down(MouseButton::Left, { + anchored() + .position(point(SHADOW_SIZE, SHADOW_SIZE)) + .snap_to_window() + .child( + div() + .occlude() + .w(view_size.width) + .h(view_size.height) + .when(self.overlay_visible, |this| { + this.bg(overlay_color(self.overlay, cx)) + }) + .on_mouse_down(MouseButton::Left, { let on_close = self.on_close.clone(); move |_, cx| { on_close(&ClickEvent::default(), cx); cx.close_modal(); } }) - }) - .child( - self.base - .id(SharedString::from(format!("modal-{layer_ix}"))) - .key_context(CONTEXT) - .track_focus(&self.focus_handle) - .when(self.keyboard, |this| { - this.on_action({ - let on_close = self.on_close.clone(); - move |_: &Escape, cx| { - // FIXME: - // - // Here some Modal have no focus_handle, so it will not work will Escape key. - // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work. - on_close(&ClickEvent::default(), cx); - cx.close_modal(); - } + .child( + self.base + .id(SharedString::from(format!("modal-{layer_ix}"))) + .key_context(CONTEXT) + .track_focus(&self.focus_handle) + .when(self.keyboard, |this| { + this.on_action({ + let on_close = self.on_close.clone(); + move |_: &Escape, cx| { + // FIXME: + // + // Here some Modal have no focus_handle, so it will not work will Escape key. + // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work. + on_close(&ClickEvent::default(), cx); + cx.close_modal(); + } + }) + }) + .absolute() + .occlude() + .relative() + .left(x) + .top(y) + .w(self.width) + .when_some(self.max_width, |this, w| this.max_w(w)) + .when_some(self.title, |this, title| { + this.child(div().line_height(relative(1.)).child(title)) }) - }) - .absolute() - .occlude() - .relative() - .left(x) - .top(y) - .w(self.width) - .when_some(self.max_width, |this, w| this.max_w(w)) - .when_some(self.title, |this, title| { - this.child(div().line_height(relative(1.)).child(title)) - }) - .when(self.show_close, |this| { - this.child( - Button::new(SharedString::from(format!("modal-close-{layer_ix}"))) + .when(self.show_close, |this| { + this.child( + Button::new(SharedString::from(format!( + "modal-close-{layer_ix}" + ))) .absolute() .top_2() .right_2() .small() .ghost() .icon(IconName::Close) - .on_click(move |_, cx| { - on_close(&ClickEvent::default(), cx); - cx.close_modal(); - }), - ) - }) - .child(self.content) - .children(self.footer) - .with_animation( - "slide-down", - Animation::new(Duration::from_secs_f64(0.25)) - .with_easing(cubic_bezier(0.32, 0.72, 0., 1.)), - move |this, delta| { - let y_offset = px(0.) + delta * px(30.); - this.top(y + y_offset).opacity(delta) - }, - ), - ), - ) + .on_click( + move |_, cx| { + on_close(&ClickEvent::default(), cx); + cx.close_modal(); + }, + ), + ) + }) + .child(self.content) + .children(self.footer) + .with_animation( + "slide-down", + Animation::new(Duration::from_secs_f64(0.25)) + .with_easing(cubic_bezier(0.32, 0.72, 0., 1.)), + move |this, delta| { + let y_offset = px(0.) + delta * px(30.); + this.top(y + y_offset).opacity(delta) + }, + ), + ), + ) } } diff --git a/crates/ui/src/root.rs b/crates/ui/src/root.rs index ea02bfbf..9150f216 100644 --- a/crates/ui/src/root.rs +++ b/crates/ui/src/root.rs @@ -405,6 +405,7 @@ impl Render for Root { window_border().child( div() .id("root") + .relative() .size_full() .font_family(".SystemUIFont") .bg(cx.theme().background) diff --git a/crates/ui/src/window_border.rs b/crates/ui/src/window_border.rs index 8670849c..31642d8c 100644 --- a/crates/ui/src/window_border.rs +++ b/crates/ui/src/window_border.rs @@ -8,7 +8,10 @@ use gpui::{ use crate::theme::ActiveTheme; -const SHADOW_SIZE: Pixels = Pixels(12.0); +#[cfg(not(target_os = "linux"))] +pub(crate) const SHADOW_SIZE: Pixels = Pixels(0.0); +#[cfg(target_os = "linux")] +pub(crate) const SHADOW_SIZE: Pixels = Pixels(12.0); const BORDER_SIZE: Pixels = Pixels(1.0); pub(crate) const BORDER_RADIUS: Pixels = Pixels(0.0);