diff --git a/config/src/color.rs b/config/src/color.rs index d78a36ebd..31d324ccb 100644 --- a/config/src/color.rs +++ b/config/src/color.rs @@ -235,6 +235,22 @@ pub struct WindowFrameConfig { pub button_hover_fg: RgbColor, #[serde(default = "default_button_hover_bg")] pub button_hover_bg: RgbColor, + + #[serde(default = "default_title_font")] + pub font: TextStyle, + #[serde(default = "default_title_font_size", deserialize_with = "de_number")] + pub font_size: f64, +} + +fn default_title_font_size() -> f64 { + 10. +} + +fn default_title_font() -> TextStyle { + TextStyle { + foreground: None, + font: vec![FontAttributes::new("DejaVu Sans")], + } } impl Default for WindowFrameConfig { @@ -250,6 +266,8 @@ impl Default for WindowFrameConfig { button_bg: default_button_bg(), button_hover_fg: default_button_hover_fg(), button_hover_bg: default_button_hover_bg(), + font: default_title_font(), + font_size: default_font_size(), } } } diff --git a/wezterm-font/src/lib.rs b/wezterm-font/src/lib.rs index 3bac4a7fb..45b9989ff 100644 --- a/wezterm-font/src/lib.rs +++ b/wezterm-font/src/lib.rs @@ -176,6 +176,7 @@ struct FontConfigInner { font_dirs: RefCell>, built_in: RefCell>, no_glyphs: RefCell>, + title_font: RefCell>>, } /// Matches and loads fonts for a given input style @@ -192,6 +193,7 @@ impl FontConfigInner { fonts: RefCell::new(HashMap::new()), locator, metrics: RefCell::new(None), + title_font: RefCell::new(None), font_scale: RefCell::new(1.0), dpi: RefCell::new(dpi), config: RefCell::new(config.clone()), @@ -206,6 +208,7 @@ impl FontConfigInner { *self.config.borrow_mut() = config.clone(); // Config was reloaded, invalidate our caches fonts.clear(); + self.title_font.borrow_mut().take(); self.metrics.borrow_mut().take(); self.no_glyphs.borrow_mut().clear(); *self.font_dirs.borrow_mut() = Arc::new(FontDatabase::with_font_dirs(config)?); @@ -359,6 +362,66 @@ impl FontConfigInner { }); } + fn title_font(&self, myself: &Rc) -> anyhow::Result> { + let config = self.config.borrow(); + + let mut title_font = self.title_font.borrow_mut(); + + if let Some(entry) = title_font.as_ref() { + return Ok(Rc::clone(entry)); + } + + let attributes = config.window_frame.font.font_with_fallback(); + let preferred_attributes = attributes + .iter() + .filter(|a| !a.is_fallback) + .map(|a| a.clone()) + .collect::>(); + let fallback_attributes = attributes + .iter() + .filter(|a| a.is_fallback) + .map(|a| a.clone()) + .collect::>(); + let mut loaded = HashSet::new(); + + let mut handles = vec![]; + for attrs in &[&preferred_attributes, &fallback_attributes] { + self.font_dirs + .borrow() + .resolve_multiple(attrs, &mut handles, &mut loaded); + handles.append(&mut self.locator.load_fonts(attrs, &mut loaded)?); + self.built_in + .borrow() + .resolve_multiple(attrs, &mut handles, &mut loaded); + } + + let shaper = new_shaper(&*config, &handles)?; + + let font_size = config.window_frame.font_size; + let dpi = *self.dpi.borrow() as u32; + let metrics = shaper.metrics(font_size, dpi).with_context(|| { + format!( + "obtaining metrics for font_size={} @ dpi {}", + font_size, dpi + ) + })?; + + let loaded = Rc::new(LoadedFont { + rasterizers: RefCell::new(HashMap::new()), + handles: RefCell::new(handles), + shaper: RefCell::new(shaper), + metrics, + font_size, + dpi, + font_config: Rc::downgrade(myself), + pending_fallback: Arc::new(Mutex::new(vec![])), + }); + + title_font.replace(Rc::clone(&loaded)); + + Ok(loaded) + } + /// Given a text style, load (with caching) the font that best /// matches according to the fontconfig pattern. fn resolve_font(&self, myself: &Rc, style: &TextStyle) -> anyhow::Result> { @@ -563,6 +626,10 @@ impl FontConfiguration { self.inner.config.borrow().clone() } + pub fn title_font(&self) -> anyhow::Result> { + self.inner.title_font(&self.inner) + } + /// Given a text style, load (with caching) the font that best /// matches according to the fontconfig pattern. pub fn resolve_font(&self, style: &TextStyle) -> anyhow::Result> { diff --git a/window/src/os/wayland/frame.rs b/window/src/os/wayland/frame.rs index f7db628dc..54c037c89 100644 --- a/window/src/os/wayland/frame.rs +++ b/window/src/os/wayland/frame.rs @@ -444,7 +444,7 @@ impl ConceptFrame { } } - let font = font_config.default_font().ok()?; + let font = font_config.title_font().ok()?; let metrics = font.metrics(); let infos = font .shape( @@ -795,7 +795,7 @@ impl Frame for ConceptFrame { pool.resize(4 * pxcount as usize) .expect("I/O Error while redrawing the borders"); - // draw the white header bar + // draw the header bar { let mmap = pool.mmap(); { @@ -831,6 +831,7 @@ impl Frame for ConceptFrame { if let Some(shaped) = self.shaped_title.as_ref() { let mut x = 8.; + let limit = (scaled_header_width - 4 * HEADER_SIZE) as f64; let identity = Transform::identity(); let paint = PixmapPaint::default(); for item in &shaped.glyphs { @@ -856,6 +857,10 @@ impl Frame for ConceptFrame { } x += item.info.x_advance.get(); + if x >= limit { + // Don't overflow the buttons + break; + } } }