diff --git a/locales/en.yml b/locales/en.yml index 0523415..bcbf0db 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -51,7 +51,11 @@ add_ssh: "+ ssh" open_local_or_ssh: "Open a local terminal or pick an SSH session." open_session: "Open Session" settings: "Settings" +ui_font_size: "UI Font Size" terminal_font_size: "Terminal Font Size" +system_default: "System Default" +ui_font_family: "UI Font" +terminal_font_family: "Terminal Font" theme_management_hint: "Theme mode and light/dark theme families are managed from the top-bar theme button." local_host: "local host" local_terminal_opened: "local terminal opened" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index d2b865a..2d2e30b 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -51,7 +51,11 @@ add_ssh: "+ SSH" open_local_or_ssh: "打开本地终端或选择一个 SSH 会话。" open_session: "打开会话" settings: "设置" +ui_font_size: "界面字体大小" terminal_font_size: "终端字体大小" +system_default: "系统默认" +ui_font_family: "界面字体" +terminal_font_family: "终端字体" theme_management_hint: "主题模式和亮/暗主题系列可通过顶栏的主题按钮管理。" local_host: "本地主机" local_terminal_opened: "已打开本地终端" diff --git a/src/config.rs b/src/config.rs index c8f647e..b962e6d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -107,6 +107,12 @@ pub struct ConfigFile { pub locale: String, #[serde(default = "default_terminal_font_size")] pub terminal_font_size: f32, + #[serde(default = "default_ui_font_size")] + pub ui_font_size: f32, + #[serde(default = "default_ui_font_family")] + pub ui_font_family: String, + #[serde(default = "default_terminal_font_family")] + pub terminal_font_family: String, #[serde(default)] pub sessions: Vec, #[serde(default)] @@ -127,6 +133,20 @@ fn default_terminal_font_size() -> f32 { 13.0 } +fn default_ui_font_size() -> f32 { + 12.0 +} + +pub fn default_ui_font_family() -> String { + // ".SystemUIFont" is a GPUI sentinel that resolves to the platform system UI font. + // This matches gpui-component's own Theme default. + ".SystemUIFont".to_string() +} + +fn default_terminal_font_family() -> String { + "Maple Mono NF CN".to_string() +} + pub struct ConfigStore { path: PathBuf, cache: ConfigFile, @@ -258,6 +278,42 @@ impl ConfigStore { self.cache.terminal_font_size = terminal_font_size.max(10.0); } + pub fn ui_font_size(&self) -> f32 { + if self.cache.ui_font_size <= 0.0 { + default_ui_font_size() + } else { + self.cache.ui_font_size + } + } + + pub fn set_ui_font_size(&mut self, ui_font_size: f32) { + self.cache.ui_font_size = ui_font_size.max(8.0); + } + + pub fn ui_font_family(&self) -> &str { + if self.cache.ui_font_family.is_empty() { + ".SystemUIFont" + } else { + &self.cache.ui_font_family + } + } + + pub fn set_ui_font_family(&mut self, family: &str) { + self.cache.ui_font_family = family.to_string(); + } + + pub fn terminal_font_family(&self) -> &str { + if self.cache.terminal_font_family.is_empty() { + "Maple Mono NF CN" + } else { + &self.cache.terminal_font_family + } + } + + pub fn set_terminal_font_family(&mut self, family: &str) { + self.cache.terminal_font_family = family.to_string(); + } + pub fn get(&self, id: &str) -> Option<&Session> { self.cache.sessions.iter().find(|s| s.id == id) } diff --git a/src/main.rs b/src/main.rs index 8189c3c..7c396f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use gpui::{ KeyDownEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, PathPromptOptions, Pixels, Point, QuitMode, Render, ScrollDelta, ScrollWheelEvent, SharedString, Size, StatefulInteractiveElement, Styled as _, UniformListScrollHandle, Window, WindowOptions, div, point, - prelude::FluentBuilder as _, px, size, uniform_list, + prelude::FluentBuilder as _, px, rems, size, uniform_list, }; use gpui_component::{ ActiveTheme as _, Disableable, ElementExt, IconName, Root, Sizable as _, Theme, ThemeMode, @@ -59,7 +59,7 @@ rust_i18n::i18n!("locales", fallback = "en"); const DEFAULT_COLS: u16 = 100; const DEFAULT_ROWS: u16 = 30; -const APP_FONT_FAMILY: &str = "Maple Mono NF CN"; + const SIDEBAR_WIDTH: f32 = 306.0; const TAB_BAR_HEIGHT: f32 = 52.0; const TERMINAL_PADDING_X: f32 = 32.0; @@ -152,7 +152,10 @@ struct Ashell { theme_mode: ThemeMode, light_theme_name: SharedString, dark_theme_name: SharedString, + ui_font_size: f32, terminal_font_size: f32, + ui_font_family: SharedString, + terminal_font_family: SharedString, tabs: Vec, sftp_handles: HashMap, active_tab: Option, @@ -285,6 +288,8 @@ impl Ashell { } rust_i18n::set_locale(&active_locale); gpui_component::set_locale(&active_locale); + let ui_font_family: SharedString = config.ui_font_family().into(); + let terminal_font_family: SharedString = config.terminal_font_family().into(); let mut this = Self { focus_handle: cx.focus_handle(), selector_focus_handle: cx.focus_handle(), @@ -302,7 +307,10 @@ impl Ashell { theme_mode, light_theme_name, dark_theme_name, + ui_font_size: config.ui_font_size(), terminal_font_size: config.terminal_font_size(), + ui_font_family, + terminal_font_family, tabs: Vec::new(), sftp_handles: HashMap::new(), active_tab: None, @@ -771,6 +779,42 @@ impl Ashell { cx.notify(); } + fn change_ui_font_size(&mut self, delta: f32, cx: &mut Context) { + self.ui_font_size = (self.ui_font_size + delta).clamp(8.0, 24.0); + self.config.set_ui_font_size(self.ui_font_size); + if let Err(err) = self.config.save() { + tracing::warn!("failed to save UI font size: {err:#}"); + } + Theme::global_mut(cx).font_size = px(self.ui_font_size); + self.status = format!("UI font size: {:.0}px", self.ui_font_size).into(); + cx.notify(); + } + + fn change_ui_font_family( + &mut self, + family: &str, + window: &mut Window, + cx: &mut Context, + ) { + self.ui_font_family = family.into(); + self.config.set_ui_font_family(family); + if let Err(err) = self.config.save() { + tracing::warn!("failed to save UI font family: {err:#}"); + } + set_theme_font_names(Theme::global_mut(cx), &self.ui_font_family); + cx.notify(); + window.refresh(); + } + + fn change_terminal_font_family(&mut self, family: &str, cx: &mut Context) { + self.terminal_font_family = family.into(); + self.config.set_terminal_font_family(family); + if let Err(err) = self.config.save() { + tracing::warn!("failed to save terminal font family: {err:#}"); + } + cx.notify(); + } + fn show_ssh_dialog(&mut self, window: &mut Window, cx: &mut Context) { let view = cx.entity(); let session_name_input = self.session_name_input.clone(); @@ -953,13 +997,13 @@ impl Ashell { .gap_1() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .child(t!("local_terminal")), ) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(_cx.theme().muted_foreground) .child(t!("open_local_shell_tab")), ), @@ -995,13 +1039,13 @@ impl Ashell { .gap_1() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .child(t!("new_ssh_connection")), ) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(_cx.theme().muted_foreground) .child(t!("create_or_edit_ssh_session")), ), @@ -1057,7 +1101,7 @@ impl Ashell { .gap_1() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight( FontWeight::SEMIBOLD, ) @@ -1065,7 +1109,7 @@ impl Ashell { ) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color( _cx.theme() .muted_foreground, @@ -1316,6 +1360,40 @@ impl Ashell { content.child( v_flex() .gap_3() + .child( + h_flex() + .items_center() + .gap_3() + .child( + div() + .w(px(240.)) + .child(t!("ui_font_size").to_string()), + ) + .child( + Button::new("ui-font-size-down") + .label("-") + .on_click(window.listener_for( + &view, + |this, _, _, cx| { + this.change_ui_font_size(-1.0, cx) + }, + )), + ) + .child(div().min_w(px(64.)).text_center().child(format!( + "{:.0}px", + view.read(cx).ui_font_size + ))) + .child( + Button::new("ui-font-size-up") + .label("+") + .on_click(window.listener_for( + &view, + |this, _, _, cx| { + this.change_ui_font_size(1.0, cx) + }, + )), + ), + ) .child( h_flex() .items_center() @@ -1325,20 +1403,187 @@ impl Ashell { .w(px(240.)) .child(t!("terminal_font_size").to_string()), ) - .child(Button::new("font-size-down").label("-").on_click( - window.listener_for(&view, |this, _, _, cx| { - this.change_terminal_font_size(-1.0, cx) - }), - )) + .child( + Button::new("font-size-down") + .label("-") + .on_click(window.listener_for( + &view, + |this, _, _, cx| { + this.change_terminal_font_size(-1.0, cx) + }, + )), + ) .child(div().min_w(px(64.)).text_center().child(format!( "{:.0}px", view.read(cx).terminal_font_size ))) - .child(Button::new("font-size-up").label("+").on_click( - window.listener_for(&view, |this, _, _, cx| { - this.change_terminal_font_size(1.0, cx) - }), - )), + .child( + Button::new("font-size-up") + .label("+") + .on_click(window.listener_for( + &view, + |this, _, _, cx| { + this.change_terminal_font_size(1.0, cx) + }, + )), + ), + ) + .child( + h_flex() + .items_center() + .gap_3() + .child( + div() + .w(px(180.)) + .child(t!("ui_font_family").to_string()), + ) + .child( + Button::new("ui-font-dropdown") + .small() + .icon(IconName::ChevronsUpDown) + .label({ + let current = view + .read(cx) + .ui_font_family + .to_string(); + let names = cx.text_system().all_font_names(); + if current == *".SystemUIFont" + || current.is_empty() + || !names.contains(¤t) + { + t!("system_default").to_string() + } else { + current + } + }) + .dropdown_menu_with_anchor( + Anchor::BottomRight, + { + let view = view.clone(); + move |mut menu, window, cx| { + let current = view + .read(cx) + .ui_font_family + .to_string(); + let names = + cx.text_system().all_font_names(); + menu = menu.min_w(200.).max_h( + px(320.), + ).scrollable(true); + // "System Default" entry + menu = menu.item( + PopupMenuItem::new( + t!( + "system_default" + ) + .to_string(), + ) + .checked( + current == *".SystemUIFont" + || current + .is_empty(), + ) + .on_click(window + .listener_for( + &view, + move |this, _, window, + cx| { + this.change_ui_font_family( + ".SystemUIFont", + window, + cx, + ); + }, + )), + ); + for name in names { + let checked = + name == current; + menu = menu.item( + PopupMenuItem::new( + name.clone(), + ) + .checked(checked) + .on_click(window + .listener_for( + &view, + move |this, _, + window, cx| { + this + .change_ui_font_family( + &name, + window, + cx, + ); + }, + )), + ); + } + menu + } + }, + ), + ), + ) + .child( + h_flex() + .items_center() + .gap_3() + .child( + div() + .w(px(180.)) + .child(t!("terminal_font_family").to_string()), + ) + .child( + Button::new("terminal-font-dropdown") + .small() + .icon(IconName::ChevronsUpDown) + .label({ + view.read(cx) + .terminal_font_family + .to_string() + }) + .dropdown_menu_with_anchor( + Anchor::BottomRight, + { + let view = view.clone(); + move |mut menu, window, cx| { + let current = view + .read(cx) + .terminal_font_family + .to_string(); + let names = + cx.text_system().all_font_names(); + menu = menu.min_w(200.).max_h( + px(320.), + ).scrollable(true); + for name in names { + let checked = + name == current; + menu = menu.item( + PopupMenuItem::new( + name.clone(), + ) + .checked(checked) + .on_click(window + .listener_for( + &view, + move |this, _, + _window, cx| { + this + .change_terminal_font_family( + &name, + cx, + ); + }, + )), + ); + } + menu + } + }, + ), + ), ) .child( h_flex() @@ -1438,7 +1683,7 @@ impl Ashell { ) .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(cx.theme().muted_foreground) .child(t!("theme_management_hint")), ), @@ -1718,6 +1963,11 @@ impl Ashell { return; } self.mark_sftp_entry_selected(&entry.full_path, cx); + if let Some(sftp) = self.active_sftp_mut() { + if !sftp.selected_entries.remove(&entry.full_path) { + sftp.selected_entries.insert(entry.full_path); + } + } } fn mark_sftp_entry_selected(&mut self, path: &str, cx: &mut Context) { @@ -1969,7 +2219,8 @@ impl Ashell { let theme = Theme::global_mut(cx); theme.light_theme = light_theme; theme.dark_theme = dark_theme; - set_theme_font_names(theme); + theme.font_size = px(self.ui_font_size); + set_theme_font_names(theme, &self.ui_font_family); if self.follow_system_theme { Theme::sync_system_appearance(Some(window), cx); @@ -2337,13 +2588,13 @@ impl Ashell { .gap_4() .child( div() - .text_size(px(28.)) + .text_size(rems(2.333)) .font_weight(FontWeight::BOLD) .child("ashell"), ) .child( div() - .text_size(px(13.)) + .text_size(rems(1.083)) .text_color(cx.theme().muted_foreground) .child(t!("open_local_or_ssh")), ) @@ -2484,7 +2735,7 @@ impl Ashell { .gap_2() .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .font_weight(FontWeight::SEMIBOLD) .text_color(fill) .child(label.clone()), @@ -2492,7 +2743,7 @@ impl Ashell { .child(div().flex_1()) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .flex_none() .child(format!("{:.0}%", percent * 100.0)), @@ -2510,7 +2761,7 @@ impl Ashell { .w_full() .min_w(px(0.)) .overflow_hidden() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(detail), ) @@ -2530,7 +2781,7 @@ impl Ashell { .gap_2() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .text_color(cx.theme().chart_4) .child(t!("net")), @@ -2538,7 +2789,7 @@ impl Ashell { .child(div().flex_1()) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(t!("live")), ), @@ -2554,11 +2805,11 @@ impl Ashell { .child( div() .flex_none() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(cx.theme().chart_4) .child("↓"), ) - .child(div().text_size(px(12.)).child(self.system.net_rx.clone())), + .child(div().text_size(rems(1.0)).child(self.system.net_rx.clone())), ) .child( h_flex() @@ -2568,11 +2819,11 @@ impl Ashell { .child( div() .flex_none() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(cx.theme().chart_5) .child("↑"), ) - .child(div().text_size(px(12.)).child(self.system.net_tx.clone())), + .child(div().text_size(rems(1.0)).child(self.system.net_tx.clone())), ), ) } @@ -2598,14 +2849,14 @@ impl Ashell { .flex_1() .min_w(px(0.)) .overflow_hidden() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().foreground) .child(mount.clone()), ) .child( div() .flex_none() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(format!("{:.0}%", percent * 100.0)), ), @@ -2621,7 +2872,7 @@ impl Ashell { div() .min_w(px(0.)) .overflow_hidden() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(format!( "{}/{}", @@ -2821,7 +3072,7 @@ impl Ashell { .bg(cx.theme().tab_bar) .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .text_color(cx.theme().primary) .child(t!("remote_files")), @@ -2910,7 +3161,7 @@ impl Ashell { .p_3() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(cx.theme().muted_foreground) .child(t!("open_ssh_tab_sftp")), ), @@ -3007,7 +3258,7 @@ impl Ashell { .child( div() .flex_1() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(t!("name")), ), @@ -3016,7 +3267,7 @@ impl Ashell { div() .w(size_col_width) .flex_none() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(t!("size")), ) @@ -3024,7 +3275,7 @@ impl Ashell { div() .w(modified_col_width) .flex_none() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(t!("modified")), ) @@ -3148,7 +3399,7 @@ impl Ashell { div() .w(icon_col_width) .flex_none() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(name_color) .child(if entry.is_dir { "📁" @@ -3161,7 +3412,7 @@ impl Ashell { .flex_1() .min_w(px(0.)) .overflow_hidden() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(name_color) .child(entry.name), ), @@ -3170,7 +3421,7 @@ impl Ashell { div() .w(size_col_width) .flex_none() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(if entry.is_dir { "-".to_string() @@ -3182,7 +3433,7 @@ impl Ashell { div() .w(modified_col_width) .flex_none() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(format_mtime(entry.modified)), ) @@ -3221,7 +3472,7 @@ impl Ashell { div() .min_w(px(0.)) .overflow_hidden() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(status), ), @@ -3261,13 +3512,13 @@ impl Ashell { .child( div() .font_weight(FontWeight::BOLD) - .text_size(px(20.)) + .text_size(rems(1.667)) .text_color(cx.theme().primary) .child("ashell"), ) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child({ if let Some(kind) = self.active_kind() { @@ -3291,7 +3542,7 @@ impl Ashell { .items_center() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .text_color(cx.theme().primary) .child(t!("system")), @@ -3299,7 +3550,7 @@ impl Ashell { .child(div().flex_1()) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(self.system_target_label()), ), @@ -3307,7 +3558,7 @@ impl Ashell { .when_some(self.system_status.clone(), |this, text| { this.child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(text), ) @@ -3344,7 +3595,7 @@ impl Ashell { .bg(cx.theme().muted) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().chart_5) .child(t!("disk")), ) @@ -3370,7 +3621,7 @@ impl Ashell { .gap_2() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .text_color(cx.theme().primary) .child(t!("saved")), @@ -3449,13 +3700,13 @@ impl Ashell { .gap_1() .child( div() - .text_size(px(12.)) + .text_size(rems(1.0)) .font_weight(FontWeight::SEMIBOLD) .child(name), ) .child( div() - .text_size(px(11.)) + .text_size(rems(0.917)) .text_color(cx.theme().muted_foreground) .child(detail), ), @@ -3514,7 +3765,7 @@ impl Render for Ashell { .size_full() .bg(cx.theme().background) .text_color(cx.theme().foreground) - .font_family(APP_FONT_FAMILY) + .font_family(self.ui_font_family.clone()) .child( h_resizable("ashell-workspace") .with_state(&self.workspace_panels) @@ -3624,8 +3875,8 @@ impl Render for Ashell { .p_4() .bg(cx.theme().background) .text_color(cx.theme().foreground) - .font_family(APP_FONT_FAMILY) - .text_size(px(13.)) + .font_family(self.ui_font_family.clone()) + .text_size(rems(1.083)) .line_height(px(18.)) .overflow_hidden() .track_focus(&self.focus_handle) @@ -3660,7 +3911,7 @@ impl Render for Ashell { self.focus_handle.clone(), snapshot, self.terminal_marked_text.clone(), - APP_FONT_FAMILY, + self.terminal_font_family.clone(), px(self.terminal_font_size), px(self.terminal_line_height()), px(self.terminal_cell_width()), @@ -3676,7 +3927,7 @@ impl Render for Ashell { .child( resizable_panel() .size(px(self.config.body_panels().and_then(|s| s.get(1).copied()).unwrap_or(248.0))) - .size_range(px(180.)..px(420.)) + .size_range(px(180.)..px(1000.)) .child(self.render_sftp_panel(window, cx)), ), ), @@ -3782,7 +4033,7 @@ impl Render for Ashell { .gap_2() .children(progress.lines.iter().cloned().map(|line| { div() - .text_size(px(12.)) + .text_size(rems(1.0)) .text_color(if progress.failed { cx.theme().danger } else { @@ -3827,7 +4078,9 @@ fn load_fonts(cx: &mut App) -> Result<()> { cx.text_system() .add_fonts(vec![regular, bold]) .context("load Maple Mono NF CN fonts")?; - set_theme_font_names(cx.global_mut::()); + // At startup we don't have a config yet, so pass the default UI font family. + // It will be reapplied in Ashell::new() -> apply_theme_preferences. + set_theme_font_names(cx.global_mut::(), ".SystemUIFont"); Ok(()) } @@ -3840,9 +4093,9 @@ fn load_embedded_themes(cx: &mut App) { } } -fn set_theme_font_names(theme: &mut Theme) { - theme.font_family = APP_FONT_FAMILY.into(); - theme.mono_font_family = APP_FONT_FAMILY.into(); +fn set_theme_font_names(theme: &mut Theme, ui_font_family: &str) { + theme.font_family = ui_font_family.into(); + theme.mono_font_family = ui_font_family.into(); } #[cfg(target_os = "macos")] diff --git a/src/terminal_element.rs b/src/terminal_element.rs index dfd2ea5..8fe2c17 100644 --- a/src/terminal_element.rs +++ b/src/terminal_element.rs @@ -4,7 +4,7 @@ use alacritty_terminal::{ }; use gpui::{ App, Bounds, Element, ElementId, Entity, FocusHandle, Font, FontStyle, FontWeight, - GlobalElementId, Hsla, InputHandler, IntoElement, LayoutId, Pixels, Point, Rgba, + GlobalElementId, Hsla, InputHandler, IntoElement, LayoutId, Pixels, Point, Rgba, SharedString, StrikethroughStyle, TextRun, TextStyle, UTF16Selection, UnderlineStyle, Window, fill, point, px, relative, rgb, }; @@ -127,7 +127,7 @@ pub struct TerminalElement { focus_handle: FocusHandle, snapshot: RenderSnapshot, marked_text: Option, - font_family: &'static str, + font_family: SharedString, font_size: Pixels, line_height: Pixels, cell_width: Pixels, @@ -250,7 +250,7 @@ impl TerminalElement { focus_handle: FocusHandle, snapshot: RenderSnapshot, marked_text: Option, - font_family: &'static str, + font_family: SharedString, font_size: Pixels, line_height: Pixels, cell_width: Pixels, @@ -270,7 +270,7 @@ impl TerminalElement { fn base_text_style(&self, cx: &App) -> TextStyle { TextStyle { color: cx.theme().foreground, - font_family: self.font_family.into(), + font_family: self.font_family.clone(), font_size: self.font_size.into(), line_height: self.line_height.into(), ..Default::default() @@ -319,7 +319,7 @@ impl TerminalElement { color: fg, background_color: None, font: Font { - family: self.font_family.into(), + family: self.font_family.clone(), weight, style, ..Font::default() @@ -514,7 +514,7 @@ impl Element for TerminalElement { &[TextRun { len: marked_text.len(), font: Font { - family: self.font_family.into(), + family: self.font_family.clone(), ..Font::default() }, color: base_style.color,