improve title bar
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 2m20s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 2m31s

This commit is contained in:
2026-01-16 18:39:57 +07:00
parent 81b1f2b293
commit ca38cc23d9
5 changed files with 66 additions and 71 deletions

View File

@@ -1,5 +1,3 @@
use std::sync::Mutex;
use gpui::{actions, App}; use gpui::{actions, App};
use key_store::{KeyItem, KeyStore}; use key_store::{KeyItem, KeyStore};
use nostr_connect::prelude::*; 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) { pub fn reset(cx: &mut App) {
let backend = KeyStore::global(cx).read(cx).backend(); let backend = KeyStore::global(cx).read(cx).backend();
let client = NostrRegistry::global(cx).read(cx).client(); let client = NostrRegistry::global(cx).read(cx).client();
@@ -87,8 +61,3 @@ pub fn reset(cx: &mut App) {
}) })
.detach(); .detach();
} }
pub fn quit(_: &Quit, cx: &mut App) {
log::info!("Gracefully quitting the application . . .");
cx.quit();
}

View File

@@ -1,15 +1,15 @@
use std::sync::Arc; use std::sync::{Arc, Mutex};
use assets::Assets; use assets::Assets;
use common::{APP_ID, CLIENT_NAME}; use common::{APP_ID, CLIENT_NAME};
use gpui::{ use gpui::{
point, px, size, AppContext, Application, Bounds, KeyBinding, Menu, MenuItem, SharedString, point, px, size, App, AppContext, Application, Bounds, KeyBinding, Menu, MenuItem,
Size, TitlebarOptions, WindowBackgroundAppearance, WindowBounds, WindowDecorations, WindowKind, SharedString, Size, TitlebarOptions, WindowBackgroundAppearance, WindowBounds,
WindowOptions, WindowDecorations, WindowKind, WindowOptions,
}; };
use ui::Root; use ui::Root;
use crate::actions::{load_embedded_fonts, quit, Quit}; use crate::actions::Quit;
mod actions; mod actions;
mod chatspace; mod chatspace;
@@ -117,3 +117,32 @@ fn main() {
.expect("Failed to open window. Please restart the application."); .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();
}

View File

@@ -143,7 +143,7 @@ impl Render for TitleBar {
PlatformKind::Linux => { PlatformKind::Linux => {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
if matches!(decorations, Decorations::Client { .. }) { if matches!(decorations, Decorations::Client { .. }) {
this.child(LinuxWindowControls::new(None)) this.child(LinuxWindowControls::new())
.when(supported_controls.window_menu, |this| { .when(supported_controls.window_menu, |this| {
this.on_mouse_down(MouseButton::Right, move |ev, window, _| { this.on_mouse_down(MouseButton::Right, move |ev, window, _| {
window.show_window_menu(ev.position) window.show_window_menu(ev.position)

View File

@@ -4,23 +4,19 @@ use std::sync::OnceLock;
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
img, Action, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, svg, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce,
StatefulInteractiveElement, Styled, Window, SharedString, StatefulInteractiveElement, Styled, Window,
}; };
use linicon::{lookup_icon, IconType}; use linicon::{lookup_icon, IconType};
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::{h_flex, Icon, IconName, Sizable}; use ui::{h_flex, Icon, IconName, Sizable};
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct LinuxWindowControls { pub struct LinuxWindowControls {}
close_window_action: Option<Box<dyn Action>>,
}
impl LinuxWindowControls { impl LinuxWindowControls {
pub fn new(close_window_action: Option<Box<dyn Action>>) -> Self { pub fn new() -> Self {
Self { Self {}
close_window_action,
}
} }
} }
@@ -42,12 +38,10 @@ impl RenderOnce for LinuxWindowControls {
WindowControl::new(LinuxControl::Maximize, IconName::WindowMaximize) WindowControl::new(LinuxControl::Maximize, IconName::WindowMaximize)
} }
}) })
.child( .child(WindowControl::new(
WindowControl::new(LinuxControl::Close, IconName::WindowClose) LinuxControl::Close,
.when_some(self.close_window_action, |this, close_action| { IconName::WindowClose,
this.close_action(close_action) ))
}),
)
} }
} }
@@ -55,21 +49,11 @@ impl RenderOnce for LinuxWindowControls {
pub struct WindowControl { pub struct WindowControl {
kind: LinuxControl, kind: LinuxControl,
fallback: IconName, fallback: IconName,
close_action: Option<Box<dyn Action>>,
} }
impl WindowControl { impl WindowControl {
pub fn new(kind: LinuxControl, fallback: IconName) -> Self { pub fn new(kind: LinuxControl, fallback: IconName) -> Self {
Self { Self { kind, fallback }
kind,
fallback,
close_action: None,
}
}
pub fn close_action(mut self, action: Box<dyn Action>) -> Self {
self.close_action = Some(action);
self
} }
pub fn is_gnome(&self) -> bool { pub fn is_gnome(&self) -> bool {
@@ -102,7 +86,20 @@ impl RenderOnce for WindowControl {
}) })
.map(|this| { .map(|this| {
if let Some(Some(path)) = linux_controls().get(&self.kind).cloned() { 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 { } else {
this.child(Icon::new(self.fallback).flex_grow().small()) this.child(Icon::new(self.fallback).flex_grow().small())
} }
@@ -114,13 +111,7 @@ impl RenderOnce for WindowControl {
LinuxControl::Minimize => window.minimize_window(), LinuxControl::Minimize => window.minimize_window(),
LinuxControl::Restore => window.zoom_window(), LinuxControl::Restore => window.zoom_window(),
LinuxControl::Maximize => window.zoom_window(), LinuxControl::Maximize => window.zoom_window(),
LinuxControl::Close => window.dispatch_action( LinuxControl::Close => {}
self.close_action
.as_ref()
.expect("Use WindowControl::new_close() for close control.")
.boxed_clone(),
cx,
),
} }
}) })
} }

View File

@@ -325,6 +325,12 @@ impl Render for Root {
Decorations::Server => div, Decorations::Server => div,
Decorations::Client { tiling } => div Decorations::Client { tiling } => div
.border_color(cx.theme().window_border) .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| { .when(!(tiling.bottom || tiling.right), |div| {
div.rounded_br(CLIENT_SIDE_DECORATION_ROUNDING) div.rounded_br(CLIENT_SIDE_DECORATION_ROUNDING)
}) })