status bar
git clone https://git.lucas.co/cce-status-interface.git
Refactor and adapt widgets to use UiContext and scale factor
Cargo.lock | 50 +++++++++++++++----------------
Cargo.toml | 2 +-
Makefile | 2 +-
src/bin/check_metrics.rs | 7 +++--
src/main.rs | 76 +++++++++++++++++++++++++++++-------------------
5 files changed, 78 insertions(+), 59 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 558a526..a1689f2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -324,6 +324,31 @@ dependencies = [
"shlex",
]
+[[package]]
+name = "cce-status-interface"
+version = "0.1.0"
+dependencies = [
+ "bytemuck",
+ "calloop",
+ "calloop-wayland-source",
+ "chrono",
+ "clear-ui",
+ "glyphon",
+ "png",
+ "pollster",
+ "raw-window-handle",
+ "resvg",
+ "serde",
+ "serde_json",
+ "smithay-client-toolkit",
+ "tokio",
+ "tokio-stream",
+ "wayland-client",
+ "wgpu",
+ "xkeysym",
+ "zbus",
+]
+
[[package]]
name = "cfg-if"
version = "1.0.4"
@@ -349,31 +374,6 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "clear-status-interface"
-version = "0.1.0"
-dependencies = [
- "bytemuck",
- "calloop",
- "calloop-wayland-source",
- "chrono",
- "clear-ui",
- "glyphon",
- "png",
- "pollster",
- "raw-window-handle",
- "resvg",
- "serde",
- "serde_json",
- "smithay-client-toolkit",
- "tokio",
- "tokio-stream",
- "wayland-client",
- "wgpu",
- "xkeysym",
- "zbus",
-]
-
[[package]]
name = "clear-ui"
version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
index a0547ef..2d8d40e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "clear-status-interface"
+name = "cce-status-interface"
version = "0.1.0"
edition = "2021"
diff --git a/Makefile b/Makefile
index cf5cdb5..1a78e94 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ build:
install: build
mkdir -p ~/.local/bin
- install -m 755 target/release/clear-status-interface ~/.local/bin/clear-status-interface
+ install -m 755 target/release/cce-status-interface ~/.local/bin/cce-status-interface
run:
cargo run
diff --git a/src/bin/check_metrics.rs b/src/bin/check_metrics.rs
index b6ea506..582c885 100644
--- a/src/bin/check_metrics.rs
+++ b/src/bin/check_metrics.rs
@@ -2,14 +2,17 @@ use glyphon::{FontSystem, Buffer, Metrics, Attrs, Shaping};
fn main() {
let mut font_system = FontSystem::new();
- let font_size = 11.0;
+ let font_size = 28.0;
let metrics = Metrics::new(font_size, font_size * 1.4);
let mut buffer = Buffer::new(&mut font_system, metrics);
let attrs = Attrs::new().family(glyphon::Family::Name("Berkeley Mono"));
- buffer.set_text(&mut font_system, "Vol 0%", attrs, Shaping::Advanced);
+ buffer.set_text(&mut font_system, "Hello World", attrs, Shaping::Advanced);
buffer.shape_until_scroll(&mut font_system, true);
for run in buffer.layout_runs() {
println!("line_y: {}, line_w: {}", run.line_y, run.line_w);
+ for glyph in run.glyphs {
+ println!(" glyph at x: {}, w: {}", glyph.x, glyph.w);
+ }
}
}
diff --git a/src/main.rs b/src/main.rs
index 62e43e7..7b57b8a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -78,15 +78,28 @@ enum CustomEvent {
}
fn make_text_buffer(fs: &mut FontSystem, text: &str, size: f32, font_family: &str) -> Buffer {
- let metrics = Metrics::new(size, size * 1.4);
+ let scale = clear_ui::scale::scale_factor();
+ let mut font_size = size;
+
+ let (parsed_family, parsed_size) = clear_ui::layout::parse_font_string(font_family);
+ if let Some(ps) = parsed_size {
+ font_size = ps;
+ }
+ let family_name = Some(parsed_family);
+
+ let physical_size = font_size * scale;
+ let metrics = Metrics::new(physical_size, physical_size * 1.4);
let mut buf = Buffer::new(fs, metrics);
- let family = match font_family {
- "monospace" => glyphon::Family::Monospace,
- "sans-serif" => glyphon::Family::SansSerif,
- "serif" => glyphon::Family::Serif,
- _ => glyphon::Family::Name(font_family),
- };
- let attrs = Attrs::new().family(family);
+ let mut attrs = Attrs::new();
+ if let Some(ref font_name) = family_name {
+ let family = match font_name.as_str() {
+ "monospace" => glyphon::Family::Monospace,
+ "sans-serif" => glyphon::Family::SansSerif,
+ "serif" => glyphon::Family::Serif,
+ name => glyphon::Family::Name(name),
+ };
+ attrs = attrs.family(family);
+ }
buf.set_text(fs, text, attrs, glyphon::Shaping::Advanced);
buf.shape_until_scroll(fs, true);
buf
@@ -631,7 +644,8 @@ impl StatusApp {
};
let buf = make_text_buffer(&mut self.font_system, symbol, font_size, &font_family);
- let tw = buf.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0);
+ let scale = clear_ui::scale::scale_factor();
+ let tw = buf.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0) / scale;
let tx = x + (icon_size - tw) / 2.0;
let ty = y + (icon_size - font_size * 1.4) / 2.0;
self.text_items.push(TextItem {
@@ -660,7 +674,8 @@ impl StatusApp {
let tooltip_text = bound.title.as_deref().unwrap_or(bound.id.as_str());
let tooltip_font_size = font_size - 1.0;
let buf = make_text_buffer(&mut self.font_system, tooltip_text, tooltip_font_size, &font_family);
- let text_w = buf.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0);
+ let scale = clear_ui::scale::scale_factor();
+ let text_w = buf.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0) / scale;
let padding = 6.0;
let tooltip_w = text_w + padding * 2.0;
@@ -698,9 +713,9 @@ impl StatusApp {
fn get_active_tag_index() -> u32 {
let path = if let Ok(display) = std::env::var("WAYLAND_DISPLAY") {
- format!("/tmp/ccec-tags-{}", display)
+ format!("/tmp/cce-client-tags-{}", display)
} else {
- "/tmp/ccec-tags".to_string()
+ "/tmp/cce-client-tags".to_string()
};
if let Ok(content) = std::fs::read_to_string(path) {
let parts: Vec<&str> = content.split_whitespace().collect();
@@ -766,7 +781,7 @@ impl clear_ui::engine::Application for StatusApp {
fn settings(&self) -> clear_ui::engine::WindowSettings {
clear_ui::engine::WindowSettings {
title: "Clear Status Interface".to_string(),
- app_id: "clear-status-interface".to_string(),
+ app_id: "cce-status-interface".to_string(),
width: 1920,
height: read_status_height_from_config() as u32,
fullscreen: true,
@@ -814,6 +829,7 @@ impl clear_ui::engine::Application for StatusApp {
self.width = size.width as u32;
self.height = size.height as u32;
self.scale_factor = scale;
+ clear_ui::scale::set_scale_factor(scale as f32);
self.rebuild_layout();
}
let (sb_x, sb_y, sb_w, sb_h) = self.status_bar.rect();
@@ -840,9 +856,9 @@ impl clear_ui::engine::Application for StatusApp {
fn text_areas(&self, scale_f32: f32, bounds: TextBounds) -> Vec<TextArea<'_>> {
let mut areas = self.text_items().iter().map(|ti| TextArea {
buffer: &ti.buffer,
- left: ti.x * scale_f32,
- top: ti.y * scale_f32,
- scale: scale_f32,
+ left: (ti.x * scale_f32).round(),
+ top: (ti.y * scale_f32).round(),
+ scale: 1.0,
bounds,
default_color: ti.color,
custom_glyphs: &[],
@@ -851,9 +867,9 @@ impl clear_ui::engine::Application for StatusApp {
for (buf, x, y, col) in self.status_bar.get_text_items() {
areas.push(TextArea {
buffer: buf,
- left: x * scale_f32,
- top: y * scale_f32,
- scale: scale_f32,
+ left: (x * scale_f32).round(),
+ top: (y * scale_f32).round(),
+ scale: 1.0,
bounds,
default_color: col,
custom_glyphs: &[],
@@ -1122,8 +1138,8 @@ async fn spawn_status_listener(sub: &'static str, sender: calloop::channel::Send
use tokio::net::UnixStream;
loop {
let socket_path = match std::env::var("WAYLAND_DISPLAY") {
- Ok(display) => format!("/tmp/ccec-status-{}.sock", display),
- Err(_) => "/tmp/ccec-status.sock".to_string(),
+ Ok(display) => format!("/tmp/cce-client-status-{}.sock", display),
+ Err(_) => "/tmp/cce-client-status.sock".to_string(),
};
if let Ok(mut stream) = UnixStream::connect(&socket_path).await {
eprintln!("[status-listener] connected to {} for sub '{}'", socket_path, sub);
@@ -1936,12 +1952,12 @@ fn main() {
}
fn read_normal_color_from_config() -> Option<[f32; 4]> {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").ok()?;
parse_srgb_color_from_key(&content, "status_normal_color")
}
fn read_disabled_color_from_config() -> Option<[f32; 4]> {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").ok()?;
parse_srgb_color_from_key(&content, "disabled_color")
}
@@ -1973,7 +1989,7 @@ fn read_status_font_from_config() -> String {
}
fn read_status_height_from_config() -> f32 {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").unwrap_or_default();
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").unwrap_or_default();
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("bar_height") {
@@ -1987,7 +2003,7 @@ fn read_status_height_from_config() -> f32 {
}
fn read_status_font_size_from_config() -> f32 {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").unwrap_or_default();
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").unwrap_or_default();
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("status_font_size") {
@@ -2001,7 +2017,7 @@ fn read_status_font_size_from_config() -> f32 {
}
fn read_status_separators_from_config() -> bool {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").unwrap_or_default();
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").unwrap_or_default();
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("status_separators") {
@@ -2015,7 +2031,7 @@ fn read_status_separators_from_config() -> bool {
}
fn read_status_underline_from_config() -> bool {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").unwrap_or_default();
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").unwrap_or_default();
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("status_underline") {
@@ -2029,7 +2045,7 @@ fn read_status_underline_from_config() -> bool {
}
fn read_status_padding_from_config() -> f32 {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").unwrap_or_default();
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").unwrap_or_default();
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("status_padding") {
@@ -2043,7 +2059,7 @@ fn read_status_padding_from_config() -> f32 {
}
fn read_separator_color_from_config() -> Option<[f32; 4]> {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").ok()?;
parse_color_from_key(&content, "status_separator_color")
}
@@ -2075,7 +2091,7 @@ fn parse_font_for_alias(content: &str, alias: &str) -> Option<String> {
}
fn read_bg_color_from_config() -> Option<[f32; 4]> {
- let content = std::fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
+ let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.toml").ok()?;
parse_color_from_key(&content, "low_color")
.or_else(|| parse_color_from_key(&content, "background_color"))
}