From ca38cc23d92b8840d83dc48388548f955e2f11a1 Mon Sep 17 00:00:00 2001 From: reya Date: Fri, 16 Jan 2026 18:39:57 +0700 Subject: [PATCH] improve title bar --- crates/coop/src/actions.rs | 31 ------------- crates/coop/src/main.rs | 39 +++++++++++++--- crates/title_bar/src/lib.rs | 2 +- crates/title_bar/src/platforms/linux.rs | 59 +++++++++++-------------- crates/ui/src/root.rs | 6 +++ 5 files changed, 66 insertions(+), 71 deletions(-) diff --git a/crates/coop/src/actions.rs b/crates/coop/src/actions.rs index 8a5798b..d69eced 100644 --- a/crates/coop/src/actions.rs +++ b/crates/coop/src/actions.rs @@ -1,5 +1,3 @@ -use std::sync::Mutex; - use gpui::{actions, App}; use key_store::{KeyItem, KeyStore}; use nostr_connect::prelude::*; @@ -37,30 +35,6 @@ impl AuthUrlHandler for CoopAuthUrlHandler { } } -pub fn load_embedded_fonts(cx: &App) { - let asset_source = cx.asset_source(); - let font_paths = asset_source.list("fonts").unwrap(); - let embedded_fonts = Mutex::new(Vec::new()); - let executor = cx.background_executor(); - - cx.foreground_executor().block_on(executor.scoped(|scope| { - for font_path in &font_paths { - if !font_path.ends_with(".ttf") { - continue; - } - - scope.spawn(async { - let font_bytes = asset_source.load(font_path).unwrap().unwrap(); - embedded_fonts.lock().unwrap().push(font_bytes); - }); - } - })); - - cx.text_system() - .add_fonts(embedded_fonts.into_inner().unwrap()) - .unwrap(); -} - pub fn reset(cx: &mut App) { let backend = KeyStore::global(cx).read(cx).backend(); let client = NostrRegistry::global(cx).read(cx).client(); @@ -87,8 +61,3 @@ pub fn reset(cx: &mut App) { }) .detach(); } - -pub fn quit(_: &Quit, cx: &mut App) { - log::info!("Gracefully quitting the application . . ."); - cx.quit(); -} diff --git a/crates/coop/src/main.rs b/crates/coop/src/main.rs index 3777c3a..6fe4ec0 100644 --- a/crates/coop/src/main.rs +++ b/crates/coop/src/main.rs @@ -1,15 +1,15 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use assets::Assets; use common::{APP_ID, CLIENT_NAME}; use gpui::{ - point, px, size, AppContext, Application, Bounds, KeyBinding, Menu, MenuItem, SharedString, - Size, TitlebarOptions, WindowBackgroundAppearance, WindowBounds, WindowDecorations, WindowKind, - WindowOptions, + point, px, size, App, AppContext, Application, Bounds, KeyBinding, Menu, MenuItem, + SharedString, Size, TitlebarOptions, WindowBackgroundAppearance, WindowBounds, + WindowDecorations, WindowKind, WindowOptions, }; use ui::Root; -use crate::actions::{load_embedded_fonts, quit, Quit}; +use crate::actions::Quit; mod actions; mod chatspace; @@ -117,3 +117,32 @@ fn main() { .expect("Failed to open window. Please restart the application."); }); } + +fn load_embedded_fonts(cx: &App) { + let asset_source = cx.asset_source(); + let font_paths = asset_source.list("fonts").unwrap(); + let embedded_fonts = Mutex::new(vec![]); + let executor = cx.background_executor(); + + cx.foreground_executor().block_on(executor.scoped(|scope| { + for font_path in &font_paths { + if !font_path.ends_with(".ttf") { + continue; + } + + scope.spawn(async { + let font_bytes = asset_source.load(font_path).unwrap().unwrap(); + embedded_fonts.lock().unwrap().push(font_bytes); + }); + } + })); + + cx.text_system() + .add_fonts(embedded_fonts.into_inner().unwrap()) + .unwrap(); +} + +fn quit(_ev: &Quit, cx: &mut App) { + log::info!("Gracefully quitting the application . . ."); + cx.quit(); +} diff --git a/crates/title_bar/src/lib.rs b/crates/title_bar/src/lib.rs index f4f9471..0ff981a 100644 --- a/crates/title_bar/src/lib.rs +++ b/crates/title_bar/src/lib.rs @@ -143,7 +143,7 @@ impl Render for TitleBar { PlatformKind::Linux => { #[cfg(target_os = "linux")] if matches!(decorations, Decorations::Client { .. }) { - this.child(LinuxWindowControls::new(None)) + this.child(LinuxWindowControls::new()) .when(supported_controls.window_menu, |this| { this.on_mouse_down(MouseButton::Right, move |ev, window, _| { window.show_window_menu(ev.position) diff --git a/crates/title_bar/src/platforms/linux.rs b/crates/title_bar/src/platforms/linux.rs index b164b6f..ba12119 100644 --- a/crates/title_bar/src/platforms/linux.rs +++ b/crates/title_bar/src/platforms/linux.rs @@ -4,23 +4,19 @@ use std::sync::OnceLock; use gpui::prelude::FluentBuilder; use gpui::{ - img, Action, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, - StatefulInteractiveElement, Styled, Window, + svg, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, + SharedString, StatefulInteractiveElement, Styled, Window, }; use linicon::{lookup_icon, IconType}; use theme::ActiveTheme; use ui::{h_flex, Icon, IconName, Sizable}; #[derive(IntoElement)] -pub struct LinuxWindowControls { - close_window_action: Option>, -} +pub struct LinuxWindowControls {} impl LinuxWindowControls { - pub fn new(close_window_action: Option>) -> Self { - Self { - close_window_action, - } + pub fn new() -> Self { + Self {} } } @@ -42,12 +38,10 @@ impl RenderOnce for LinuxWindowControls { WindowControl::new(LinuxControl::Maximize, IconName::WindowMaximize) } }) - .child( - WindowControl::new(LinuxControl::Close, IconName::WindowClose) - .when_some(self.close_window_action, |this, close_action| { - this.close_action(close_action) - }), - ) + .child(WindowControl::new( + LinuxControl::Close, + IconName::WindowClose, + )) } } @@ -55,21 +49,11 @@ impl RenderOnce for LinuxWindowControls { pub struct WindowControl { kind: LinuxControl, fallback: IconName, - close_action: Option>, } impl WindowControl { pub fn new(kind: LinuxControl, fallback: IconName) -> Self { - Self { - kind, - fallback, - close_action: None, - } - } - - pub fn close_action(mut self, action: Box) -> Self { - self.close_action = Some(action); - self + Self { kind, fallback } } pub fn is_gnome(&self) -> bool { @@ -102,7 +86,20 @@ impl RenderOnce for WindowControl { }) .map(|this| { if let Some(Some(path)) = linux_controls().get(&self.kind).cloned() { - this.child(img(path).flex_grow().size_4()) + this.child( + svg() + .external_path(SharedString::from( + path.into_os_string().into_string().unwrap(), + )) + .map(|this| { + if cx.theme().is_dark() { + this.text_color(gpui::white()) + } else { + this.text_color(gpui::black()) + } + }) + .size_4(), + ) } else { this.child(Icon::new(self.fallback).flex_grow().small()) } @@ -114,13 +111,7 @@ impl RenderOnce for WindowControl { LinuxControl::Minimize => window.minimize_window(), LinuxControl::Restore => window.zoom_window(), LinuxControl::Maximize => window.zoom_window(), - LinuxControl::Close => window.dispatch_action( - self.close_action - .as_ref() - .expect("Use WindowControl::new_close() for close control.") - .boxed_clone(), - cx, - ), + LinuxControl::Close => {} } }) } diff --git a/crates/ui/src/root.rs b/crates/ui/src/root.rs index 0998591..a69775d 100644 --- a/crates/ui/src/root.rs +++ b/crates/ui/src/root.rs @@ -325,6 +325,12 @@ impl Render for Root { Decorations::Server => div, Decorations::Client { tiling } => div .border_color(cx.theme().window_border) + .when(!(tiling.top || tiling.right), |div| { + div.rounded_tr(CLIENT_SIDE_DECORATION_ROUNDING) + }) + .when(!(tiling.top || tiling.left), |div| { + div.rounded_tl(CLIENT_SIDE_DECORATION_ROUNDING) + }) .when(!(tiling.bottom || tiling.right), |div| { div.rounded_br(CLIENT_SIDE_DECORATION_ROUNDING) })