wip
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m25s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m13s

This commit is contained in:
2026-01-31 09:59:35 +07:00
parent 4336c67d8c
commit 9b03f873c2
28 changed files with 437 additions and 797 deletions

View File

@@ -12,6 +12,7 @@ pub enum IconName {
ArrowLeft,
ArrowRight,
Boom,
ChevronDown,
CaretDown,
CaretRight,
CaretUp,
@@ -27,6 +28,8 @@ pub enum IconName {
Eye,
Info,
Invite,
Inbox,
InboxFill,
Link,
Loader,
Moon,
@@ -52,6 +55,8 @@ pub enum IconName {
WindowMaximize,
WindowMinimize,
WindowRestore,
Fistbump,
FistbumpFill,
Zoom,
}
@@ -61,6 +66,7 @@ impl IconName {
Self::ArrowLeft => "icons/arrow-left.svg",
Self::ArrowRight => "icons/arrow-right.svg",
Self::Boom => "icons/boom.svg",
Self::ChevronDown => "icons/chevron-down.svg",
Self::CaretDown => "icons/caret-down.svg",
Self::CaretRight => "icons/caret-right.svg",
Self::CaretUp => "icons/caret-up.svg",
@@ -76,6 +82,8 @@ impl IconName {
Self::Eye => "icons/eye.svg",
Self::Info => "icons/info.svg",
Self::Invite => "icons/invite.svg",
Self::Inbox => "icons/inbox.svg",
Self::InboxFill => "icons/inbox-fill.svg",
Self::Link => "icons/link.svg",
Self::Loader => "icons/loader.svg",
Self::Moon => "icons/moon.svg",
@@ -101,6 +109,8 @@ impl IconName {
Self::WindowMaximize => "icons/window-maximize.svg",
Self::WindowMinimize => "icons/window-minimize.svg",
Self::WindowRestore => "icons/window-restore.svg",
Self::Fistbump => "icons/fistbump.svg",
Self::FistbumpFill => "icons/fistbump-fill.svg",
Self::Zoom => "icons/zoom.svg",
}
.into()

View File

@@ -145,6 +145,7 @@ impl Styled for TextInput {
impl RenderOnce for TextInput {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
const LINE_HEIGHT: Rems = Rems(1.25);
let font = window.text_style().font();
let font_size = window.text_style().font_size.to_pixels(window.rem_size());
@@ -155,6 +156,7 @@ impl RenderOnce for TextInput {
});
let state = self.state.read(cx);
let focused = state.focus_handle.is_focused(window) && !state.disabled;
let gap_x = match self.size {
Size::Small => px(4.),
@@ -266,7 +268,16 @@ impl RenderOnce for TextInput {
.when_some(self.height, |this, height| this.h(height))
})
.when(self.appearance, |this| {
this.bg(bg).rounded(cx.theme().radius)
this.bg(bg)
.rounded(cx.theme().radius)
.when(self.bordered, |this| {
this.border_color(cx.theme().border)
.border_1()
.when(cx.theme().shadow, |this| this.shadow_xs())
.when(focused && self.focus_bordered, |this| {
this.border_color(cx.theme().border_focused)
})
})
})
.items_center()
.gap(gap_x)

View File

@@ -2,10 +2,10 @@ use std::rc::Rc;
use gpui::prelude::FluentBuilder;
use gpui::{
canvas, div, point, px, rgba, AnyView, App, AppContext, Bounds, Context, CursorStyle,
canvas, div, point, px, size, AnyView, App, AppContext, Bounds, Context, CursorStyle,
Decorations, Edges, Entity, FocusHandle, HitboxBehavior, Hsla, InteractiveElement, IntoElement,
MouseButton, ParentElement as _, Pixels, Point, Render, ResizeEdge, SharedString, Size, Styled,
WeakFocusHandle, Window,
Tiling, WeakFocusHandle, Window,
};
use theme::{
ActiveTheme, CLIENT_SIDE_DECORATION_BORDER, CLIENT_SIDE_DECORATION_ROUNDING,
@@ -241,7 +241,10 @@ impl Render for Root {
window.set_rem_size(rem_size);
// Set the client inset (linux only)
window.set_client_inset(CLIENT_SIDE_DECORATION_SHADOW);
match decorations {
Decorations::Client { .. } => window.set_client_inset(CLIENT_SIDE_DECORATION_SHADOW),
Decorations::Server => window.set_client_inset(px(0.0)),
}
div()
.id("window")
@@ -267,7 +270,7 @@ impl Render for Root {
let size = window.window_bounds().get_bounds().size;
let Some(edge) =
resize_edge(mouse, CLIENT_SIDE_DECORATION_SHADOW, size)
resize_edge(mouse, CLIENT_SIDE_DECORATION_SHADOW, size, tiling)
else {
return;
};
@@ -314,7 +317,9 @@ impl Render for Root {
let size = window.window_bounds().get_bounds().size;
let pos = e.position;
if let Some(edge) = resize_edge(pos, CLIENT_SIDE_DECORATION_SHADOW, size) {
if let Some(edge) =
resize_edge(pos, CLIENT_SIDE_DECORATION_SHADOW, size, tiling)
{
window.start_window_resize(edge)
};
}),
@@ -324,9 +329,7 @@ impl Render for Root {
.map(|div| match decorations {
Decorations::Server => div,
Decorations::Client { tiling } => div
.when(!cx.theme().platform.is_mac(), |div| {
div.border_color(rgba(0x64748b33))
})
.border_color(cx.theme().border)
.when(!(tiling.top || tiling.right), |div| {
div.rounded_tr(CLIENT_SIDE_DECORATION_ROUNDING)
})
@@ -401,25 +404,59 @@ pub(crate) fn window_paddings(window: &Window, _cx: &App) -> Edges<Pixels> {
}
/// Get the window resize edge.
fn resize_edge(pos: Point<Pixels>, shadow_size: Pixels, size: Size<Pixels>) -> Option<ResizeEdge> {
let edge = if pos.y < shadow_size && pos.x < shadow_size {
ResizeEdge::TopLeft
} else if pos.y < shadow_size && pos.x > size.width - shadow_size {
ResizeEdge::TopRight
} else if pos.y < shadow_size {
ResizeEdge::Top
} else if pos.y > size.height - shadow_size && pos.x < shadow_size {
ResizeEdge::BottomLeft
} else if pos.y > size.height - shadow_size && pos.x > size.width - shadow_size {
ResizeEdge::BottomRight
} else if pos.y > size.height - shadow_size {
ResizeEdge::Bottom
} else if pos.x < shadow_size {
ResizeEdge::Left
} else if pos.x > size.width - shadow_size {
ResizeEdge::Right
} else {
fn resize_edge(
pos: Point<Pixels>,
shadow_size: Pixels,
window_size: Size<Pixels>,
tiling: Tiling,
) -> Option<ResizeEdge> {
let bounds = Bounds::new(Point::default(), window_size).inset(shadow_size * 1.5);
if bounds.contains(&pos) {
return None;
};
Some(edge)
}
let corner_size = size(shadow_size * 1.5, shadow_size * 1.5);
let top_left_bounds = Bounds::new(Point::new(px(0.), px(0.)), corner_size);
if !tiling.top && top_left_bounds.contains(&pos) {
return Some(ResizeEdge::TopLeft);
}
let top_right_bounds = Bounds::new(
Point::new(window_size.width - corner_size.width, px(0.)),
corner_size,
);
if !tiling.top && top_right_bounds.contains(&pos) {
return Some(ResizeEdge::TopRight);
}
let bottom_left_bounds = Bounds::new(
Point::new(px(0.), window_size.height - corner_size.height),
corner_size,
);
if !tiling.bottom && bottom_left_bounds.contains(&pos) {
return Some(ResizeEdge::BottomLeft);
}
let bottom_right_bounds = Bounds::new(
Point::new(
window_size.width - corner_size.width,
window_size.height - corner_size.height,
),
corner_size,
);
if !tiling.bottom && bottom_right_bounds.contains(&pos) {
return Some(ResizeEdge::BottomRight);
}
if !tiling.top && pos.y < shadow_size {
Some(ResizeEdge::Top)
} else if !tiling.bottom && pos.y > window_size.height - shadow_size {
Some(ResizeEdge::Bottom)
} else if !tiling.left && pos.x < shadow_size {
Some(ResizeEdge::Left)
} else if !tiling.right && pos.x > window_size.width - shadow_size {
Some(ResizeEdge::Right)
} else {
None
}
}