system settings
git clone https://git.lucas.co/cce-system-interface.git
Update system configuration and interface modules
Cargo.lock | 290 ++++++++++++++++++++++++++++++++++++++++++++-
src/main.rs | 51 ++++++++
src/pages/colors.rs | 10 +-
src/pages/input.rs | 10 +-
src/pages/layout.rs | 10 +-
src/pages/notifications.rs | 10 +-
src/pages/status.rs | 74 +++++-------
src/pages/typeface.rs | 114 ++++++++----------
8 files changed, 446 insertions(+), 123 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index ed8a1f7..b235c80 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -17,6 +23,12 @@ version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+[[package]]
+name = "arrayref"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
+
[[package]]
name = "arrayvec"
version = "0.7.6"
@@ -175,6 +187,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
[[package]]
name = "bit-set"
version = "0.8.0"
@@ -336,6 +354,7 @@ dependencies = [
"glyphon",
"pollster",
"raw-window-handle",
+ "resvg",
"smithay-client-toolkit",
"tokio",
"wayland-client",
@@ -353,6 +372,12 @@ dependencies = [
"unicode-width",
]
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -401,7 +426,7 @@ dependencies = [
"rangemap",
"rayon",
"rustc-hash 1.1.0",
- "rustybuzz",
+ "rustybuzz 0.14.1",
"self_cell",
"swash",
"sys-locale",
@@ -412,6 +437,15 @@ dependencies = [
"unicode-segmentation",
]
+[[package]]
+name = "crc32fast"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@@ -443,6 +477,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
+[[package]]
+name = "data-url"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
+
[[package]]
name = "dlib"
version = "0.5.3"
@@ -562,12 +602,37 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+[[package]]
+name = "fdeflate"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
+dependencies = [
+ "simd-adler32",
+]
+
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+[[package]]
+name = "flate2"
+version = "1.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "float-cmp"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
+
[[package]]
name = "foldhash"
version = "0.1.5"
@@ -589,7 +654,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
dependencies = [
- "roxmltree",
+ "roxmltree 0.20.0",
]
[[package]]
@@ -747,6 +812,16 @@ dependencies = [
"wasip3",
]
+[[package]]
+name = "gif"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
+dependencies = [
+ "color_quant",
+ "weezl",
+]
+
[[package]]
name = "gl_generator"
version = "0.14.0"
@@ -888,6 +963,12 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+[[package]]
+name = "imagesize"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
+
[[package]]
name = "indexmap"
version = "2.14.0"
@@ -934,6 +1015,12 @@ dependencies = [
"syn",
]
+[[package]]
+name = "jpeg-decoder"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
+
[[package]]
name = "js-sys"
version = "0.3.98"
@@ -963,6 +1050,17 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
+[[package]]
+name = "kurbo"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62"
+dependencies = [
+ "arrayvec",
+ "euclid",
+ "smallvec",
+]
+
[[package]]
name = "leb128fmt"
version = "0.1.0"
@@ -1087,6 +1185,16 @@ dependencies = [
"paste",
]
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
[[package]]
name = "mio"
version = "1.2.0"
@@ -1207,6 +1315,12 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+[[package]]
+name = "pico-args"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
+
[[package]]
name = "pin-project-lite"
version = "0.2.17"
@@ -1230,6 +1344,19 @@ version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
+[[package]]
+name = "png"
+version = "0.17.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
+dependencies = [
+ "bitflags 1.3.2",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
[[package]]
name = "polling"
version = "3.11.0"
@@ -1377,6 +1504,38 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
+[[package]]
+name = "resvg"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2327ced609dadeed3e9702fec3e6b2ddd208758a9268d13e06566c6101ba533"
+dependencies = [
+ "gif",
+ "jpeg-decoder",
+ "log",
+ "pico-args",
+ "png",
+ "rgb",
+ "svgtypes",
+ "tiny-skia",
+ "usvg",
+]
+
+[[package]]
+name = "rgb"
+version = "0.8.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "roxmltree"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f"
+
[[package]]
name = "roxmltree"
version = "0.20.0"
@@ -1427,6 +1586,22 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+[[package]]
+name = "rustybuzz"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88117946aa1bfb53c2ae0643ceac6506337f44887f8c9fbfb43587b1cc52ba49"
+dependencies = [
+ "bitflags 2.11.1",
+ "bytemuck",
+ "smallvec",
+ "ttf-parser 0.20.0",
+ "unicode-bidi-mirroring",
+ "unicode-ccc",
+ "unicode-properties",
+ "unicode-script",
+]
+
[[package]]
name = "rustybuzz"
version = "0.14.1"
@@ -1538,6 +1713,27 @@ dependencies = [
"libc",
]
+[[package]]
+name = "simd-adler32"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
+
+[[package]]
+name = "simplecss"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "siphasher"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+
[[package]]
name = "skrifa"
version = "0.22.3"
@@ -1622,6 +1818,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+[[package]]
+name = "strict-num"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
+dependencies = [
+ "float-cmp",
+]
+
[[package]]
name = "strum"
version = "0.26.3"
@@ -1650,6 +1855,16 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
+[[package]]
+name = "svgtypes"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc"
+dependencies = [
+ "kurbo",
+ "siphasher",
+]
+
[[package]]
name = "swash"
version = "0.1.19"
@@ -1743,6 +1958,32 @@ dependencies = [
"syn",
]
+[[package]]
+name = "tiny-skia"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "bytemuck",
+ "cfg-if",
+ "log",
+ "png",
+ "tiny-skia-path",
+]
+
+[[package]]
+name = "tiny-skia-path"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
+dependencies = [
+ "arrayref",
+ "bytemuck",
+ "strict-num",
+]
+
[[package]]
name = "tinyvec"
version = "1.11.0"
@@ -1918,6 +2159,12 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
+[[package]]
+name = "unicode-vo"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
+
[[package]]
name = "unicode-width"
version = "0.1.14"
@@ -1930,6 +2177,33 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+[[package]]
+name = "usvg"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c704361d822337cfc00387672c7b59eaa72a1f0744f62b2a68aa228a0c6927d"
+dependencies = [
+ "base64",
+ "data-url",
+ "flate2",
+ "fontdb",
+ "imagesize",
+ "kurbo",
+ "log",
+ "pico-args",
+ "roxmltree 0.19.0",
+ "rustybuzz 0.13.0",
+ "simplecss",
+ "siphasher",
+ "strict-num",
+ "svgtypes",
+ "tiny-skia-path",
+ "unicode-bidi",
+ "unicode-script",
+ "unicode-vo",
+ "xmlwriter",
+]
+
[[package]]
name = "uuid"
version = "1.23.1"
@@ -2165,6 +2439,12 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "weezl"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
+
[[package]]
name = "wgpu"
version = "24.0.5"
@@ -2570,6 +2850,12 @@ version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
+[[package]]
+name = "xmlwriter"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
+
[[package]]
name = "yazi"
version = "0.1.6"
diff --git a/src/main.rs b/src/main.rs
index d4ac2b8..03c603d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1265,6 +1265,18 @@ impl SystemInterface {
if self.app.typeface.terminal_size_box.cursor_moved(lx, ly) {
changed = true;
}
+ let query = self.app.typeface.search_box.text.to_lowercase();
+ let matching_count = self.app.typeface.all_fonts.iter()
+ .filter(|f| f.to_lowercase().contains(&query))
+ .count();
+ for i in 0..matching_count.min(self.app.typeface.font_buttons.len()) {
+ if self.app.typeface.font_buttons[i].cursor_moved(lx, ly) {
+ changed = true;
+ }
+ if self.app.typeface.copy_buttons[i].cursor_moved(lx, ly) {
+ changed = true;
+ }
+ }
}
if self.app.current_page == Page::Services {
if self.app.services.search_box.cursor_moved(lx, ly) {
@@ -1761,6 +1773,45 @@ impl SystemInterface {
}
let tf = &mut self.app.typeface;
+ let query = tf.search_box.text.to_lowercase();
+ let matching_fonts: Vec<String> = tf.all_fonts.iter()
+ .filter(|font| font.to_lowercase().contains(&query))
+ .cloned()
+ .collect();
+
+ let mut clicked_idx = None;
+ let mut is_copy = false;
+
+ for (i, btn) in tf.font_buttons.iter_mut().enumerate() {
+ if btn.mouse_input(button, state, lx, ly) {
+ self.needs_rebuild = true;
+ }
+ if btn.take_click() {
+ clicked_idx = Some(i);
+ is_copy = false;
+ }
+ }
+ for (i, btn) in tf.copy_buttons.iter_mut().enumerate() {
+ if btn.mouse_input(button, state, lx, ly) {
+ self.needs_rebuild = true;
+ }
+ if btn.take_click() {
+ clicked_idx = Some(i);
+ is_copy = true;
+ }
+ }
+
+ if let Some(idx) = clicked_idx {
+ if let Some(font_name) = matching_fonts.get(idx) {
+ let action = if is_copy {
+ AppAction::Typeface(pages::typeface::TypefaceMessage::CopyFontName(font_name.clone()))
+ } else {
+ AppAction::Typeface(pages::typeface::TypefaceMessage::SelectFont(font_name.clone()))
+ };
+ actions.push(action);
+ }
+ }
+
if tf.list_box.mouse_input(button, state, lx, ly) {
self.needs_rebuild = true;
}
diff --git a/src/pages/colors.rs b/src/pages/colors.rs
index c1d41a5..9b7cf7e 100644
--- a/src/pages/colors.rs
+++ b/src/pages/colors.rs
@@ -5,7 +5,13 @@ use clear_ui::layout::Section;
use clear_ui::widget::ColorSelector;
const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
-const CLEARWM_SOCK: &str = "/tmp/clearwm.sock";
+
+fn get_socket_path() -> String {
+ match std::env::var("WAYLAND_DISPLAY") {
+ Ok(display) => format!("/tmp/clearwm-{}.sock", display),
+ Err(_) => "/tmp/clearwm.sock".to_string(),
+ }
+}
#[derive(Debug, Clone)]
pub struct ColorsState {
@@ -157,7 +163,7 @@ fn write_config_value_path(path: &str, key: &str, value: &str) -> bool {
}
fn send_ipc_command(cmd: &str) {
- if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(CLEARWM_SOCK) {
+ if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
}
}
diff --git a/src/pages/input.rs b/src/pages/input.rs
index c3bbcc4..7d0859b 100644
--- a/src/pages/input.rs
+++ b/src/pages/input.rs
@@ -6,7 +6,13 @@ use clear_ui::layout::Section;
use clear_ui::widget::{Dropdown, Spinbox, Toggle, Widget};
const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
-const CLEARWM_SOCK: &str = "/tmp/clearwm.sock";
+
+fn get_socket_path() -> String {
+ match std::env::var("WAYLAND_DISPLAY") {
+ Ok(display) => format!("/tmp/clearwm-{}.sock", display),
+ Err(_) => "/tmp/clearwm.sock".to_string(),
+ }
+}
#[derive(Debug, Clone, serde::Deserialize)]
pub struct Finger {
@@ -250,7 +256,7 @@ fn parse_keybinds(content: &str) -> Vec<Keybind> {
}
fn send_ipc_command(cmd: &str) {
- if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(CLEARWM_SOCK) {
+ if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
}
}
diff --git a/src/pages/layout.rs b/src/pages/layout.rs
index c0da47e..a525036 100644
--- a/src/pages/layout.rs
+++ b/src/pages/layout.rs
@@ -6,7 +6,13 @@ use clear_ui::layout::Section;
use clear_ui::widget::Spinbox;
const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
-const CLEARWM_SOCK: &str = "/tmp/clearwm.sock";
+
+fn get_socket_path() -> String {
+ match std::env::var("WAYLAND_DISPLAY") {
+ Ok(display) => format!("/tmp/clearwm-{}.sock", display),
+ Err(_) => "/tmp/clearwm.sock".to_string(),
+ }
+}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WidthParam {
@@ -163,7 +169,7 @@ fn write_config_value(key: &str, value: &str) -> bool {
}
fn send_ipc_command(cmd: &str) {
- if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(CLEARWM_SOCK) {
+ if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
}
}
diff --git a/src/pages/notifications.rs b/src/pages/notifications.rs
index db56d2c..fdfe873 100644
--- a/src/pages/notifications.rs
+++ b/src/pages/notifications.rs
@@ -6,7 +6,13 @@ use clear_ui::layout::Section;
use clear_ui::widget::{Toggle, Spinbox};
const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
-const CLEARWM_SOCK: &str = "/tmp/clearwm.sock";
+
+fn get_socket_path() -> String {
+ match std::env::var("WAYLAND_DISPLAY") {
+ Ok(display) => format!("/tmp/clearwm-{}.sock", display),
+ Err(_) => "/tmp/clearwm.sock".to_string(),
+ }
+}
#[derive(Debug, Clone)]
pub struct NotificationsState {
@@ -122,7 +128,7 @@ fn parse_notifications_duration(content: &str) -> i32 {
}
fn send_ipc_command(cmd: &str) {
- if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(CLEARWM_SOCK) {
+ if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
}
}
diff --git a/src/pages/status.rs b/src/pages/status.rs
index d47da52..b7f6427 100644
--- a/src/pages/status.rs
+++ b/src/pages/status.rs
@@ -1,6 +1,7 @@
use crate::app::{AppAction, PageContent};
use clear_ui::layout::Section;
use clear_ui::widget::{Label, Widget};
+use crate::pages::typeface::{parse_u16_from, write_config_value};
#[derive(Debug, Clone)]
pub struct StatusState {
@@ -14,11 +15,11 @@ pub struct StatusState {
impl Default for StatusState {
fn default() -> Self {
Self {
- font_size: 13,
+ font_size: 11,
running: false,
loaded: false,
- status_label: Label::new("Waybar: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
- size_label: Label::new("Font size: 13px").with_font_size(13.0).with_color([212, 212, 212]),
+ status_label: Label::new("Status Interface: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
+ size_label: Label::new("Font size: 11px").with_font_size(13.0).with_color([212, 212, 212]),
}
}
}
@@ -28,22 +29,22 @@ pub enum StatusMessage {
Refreshed(StatusState),
FontSizeUp,
FontSizeDown,
- ReloadWaybar,
+ ReloadStatus,
}
pub async fn fetch_status_state() -> StatusState {
let running = tokio::process::Command::new("pgrep")
- .args(["-x", "waybar"]).output().await.ok()
+ .args(["-f", "clear-status-interface"]).output().await.ok()
.map(|o| !o.stdout.is_empty())
.unwrap_or(false);
- let font_size = read_waybar_font_size().unwrap_or(13);
+ let font_size = read_status_font_size().unwrap_or(11);
let status_color = if running { [92, 143, 97] } else { [170, 51, 51] };
StatusState {
font_size,
running,
loaded: true,
- status_label: Label::new(&format!("Waybar: {}", if running { "Running" } else { "Stopped" }))
+ status_label: Label::new(&format!("Status Interface: {}", if running { "Running" } else { "Stopped" }))
.with_font_size(14.0)
.with_color(status_color),
size_label: Label::new(&format!("Font size: {}px", font_size))
@@ -52,40 +53,19 @@ pub async fn fetch_status_state() -> StatusState {
}
}
-fn read_waybar_font_size() -> Option<u16> {
- let css = std::fs::read_to_string(
- std::path::Path::new(&std::env::var("HOME").unwrap_or_default()).join(".config/waybar/style.css")
- ).ok()?;
- for line in css.lines() {
- if line.contains("font-size") {
- let val = line.split(':').nth(1)?.trim().trim_end_matches(';').trim();
- if let Some(px) = val.strip_suffix("px") {
- return px.trim().parse::<u16>().ok();
- }
- return val.parse::<u16>().ok();
- }
- }
- None
+fn read_status_font_size() -> Option<u16> {
+ let content = std::fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").ok()?;
+ Some(parse_u16_from(&content, "status_font_size", 11))
}
-fn write_waybar_font_size(size: u16) {
- let home = std::env::var("HOME").unwrap_or_default();
- let path = std::path::Path::new(&home).join(".config/waybar/style.css");
- let css = std::fs::read_to_string(&path).unwrap_or_default();
- let mut new_lines = Vec::new();
- for line in css.lines() {
- if line.contains("font-size") {
- new_lines.push(format!(" font-size: {}px;", size));
- } else {
- new_lines.push(line.to_string());
- }
- }
- let _ = std::fs::write(&path, new_lines.join("\n"));
+fn write_status_font_size(size: u16) {
+ write_config_value("status_font_size", &size.to_string());
}
-fn waybar_reload() {
- let _ = tokio::process::Command::new("pkill")
- .args(["-x", "waybar", "-SIGUSR2"]).spawn();
+fn status_interface_reload() {
+ let _ = std::process::Command::new("pkill")
+ .args(["-f", "clear-status-interface"])
+ .spawn();
}
const TEXT_FG: [f32; 4] = [0.83, 0.83, 0.83, 1.0];
@@ -98,14 +78,14 @@ pub fn view(state: &mut StatusState, cx: f32, cy: f32, cw: f32, _ch: f32) -> Pag
let mut pc = PageContent::new();
let y = cy + 12.0;
- let mut sec = Section::new(&mut pc, cx, y, cw, "Waybar");
+ let mut sec = Section::new(&mut pc, cx, y, cw, "Status Interface");
if !state.loaded {
- sec.text(&mut pc, "Loading Waybar status...", 12.0, 0.0, 12.0, TEXT_FG);
+ sec.text(&mut pc, "Loading Status Interface status...", 12.0, 0.0, 12.0, TEXT_FG);
sec.spacing(18.0);
} else {
// Status
- let status_text = if state.running { "Waybar: Running" } else { "Waybar: Stopped" };
+ let status_text = if state.running { "Status Interface: Running" } else { "Status Interface: Stopped" };
state.status_label.set_text(status_text);
sec.widget(&mut pc, &mut state.status_label, 12.0, cw - 24.0, 20.0);
sec.spacing(12.0);
@@ -129,9 +109,9 @@ pub fn view(state: &mut StatusState, cx: f32, cy: f32, cw: f32, _ch: f32) -> Pag
// Reload button
let yt = sec.ay();
let btn_w = (cw - 24.0).min(200.0);
- pc.button("Reload Waybar", cx + cw / 2.0 - btn_w / 2.0, yt, btn_w, 32.0,
+ pc.button("Reload Status Interface", cx + cw / 2.0 - btn_w / 2.0, yt, btn_w, 32.0,
BTN_INACTIVE, BTN_HOVER, WHITE,
- AppAction::Status(StatusMessage::ReloadWaybar));
+ AppAction::Status(StatusMessage::ReloadStatus));
}
sec.finish(&mut pc);
@@ -150,17 +130,19 @@ pub fn update(state: &mut StatusState, msg: StatusMessage) {
StatusMessage::FontSizeUp => {
if state.font_size < 28 {
state.font_size += 1;
- write_waybar_font_size(state.font_size);
+ write_status_font_size(state.font_size);
+ status_interface_reload();
}
}
StatusMessage::FontSizeDown => {
if state.font_size > 8 {
state.font_size -= 1;
- write_waybar_font_size(state.font_size);
+ write_status_font_size(state.font_size);
+ status_interface_reload();
}
}
- StatusMessage::ReloadWaybar => {
- waybar_reload();
+ StatusMessage::ReloadStatus => {
+ status_interface_reload();
}
}
}
diff --git a/src/pages/typeface.rs b/src/pages/typeface.rs
index 2364a99..1112d1c 100644
--- a/src/pages/typeface.rs
+++ b/src/pages/typeface.rs
@@ -1,7 +1,7 @@
use std::fs;
use crate::app::PageContent;
use clear_ui::layout::Section;
-use clear_ui::widget::{Widget, TextLabel, ScrollBox, ScrollingList, Dropdown, TextBox, Spinbox};
+use clear_ui::widget::{Widget, TextLabel, ScrollBox, ScrollingList, Dropdown, TextBox, Spinbox, Button};
use clear_ui::widget::{ElementState, KeyEvent, MouseButton, Key, NamedKey};
const FONTS_CONF_PATH: &str = "/home/lsgalante/.config/fontconfig/fonts.conf";
@@ -38,6 +38,8 @@ pub struct TypefaceState {
pub status_size_box: Spinbox,
pub fuzzel_size_box: Spinbox,
pub terminal_size_box: Spinbox,
+ pub font_buttons: Vec<Button>,
+ pub copy_buttons: Vec<Button>,
}
impl Default for TypefaceState {
@@ -68,9 +70,11 @@ impl Default for TypefaceState {
fuzzel_menu: Dropdown::default(),
terminal_menu: Dropdown::default(),
borders_size_box: Spinbox::new(11, 6, 72, 1),
- status_size_box: Spinbox::new(13, 6, 72, 1),
+ status_size_box: Spinbox::new(11, 6, 72, 1),
fuzzel_size_box: Spinbox::new(14, 6, 72, 1),
terminal_size_box: Spinbox::new(12, 6, 72, 1),
+ font_buttons: Vec::new(),
+ copy_buttons: Vec::new(),
}
}
}
@@ -237,7 +241,7 @@ pub fn save_preferred_fonts(
.spawn();
}
-fn parse_u16_from(content: &str, key: &str, default: u16) -> u16 {
+pub fn parse_u16_from(content: &str, key: &str, default: u16) -> u16 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix(key) {
@@ -248,7 +252,7 @@ fn parse_u16_from(content: &str, key: &str, default: u16) -> u16 {
default
}
-fn write_config_value(key: &str, value: &str) -> bool {
+pub fn write_config_value(key: &str, value: &str) -> bool {
let content = fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").unwrap_or_default();
let new_line = format!("{} = {}", key, value);
let mut found = false;
@@ -274,8 +278,15 @@ fn write_config_value(key: &str, value: &str) -> bool {
} else { fs::write("/home/lsgalante/.config/clearwm/config.toml", updated).is_ok() }
}
+fn get_socket_path() -> String {
+ match std::env::var("WAYLAND_DISPLAY") {
+ Ok(display) => format!("/tmp/clearwm-{}.sock", display),
+ Err(_) => "/tmp/clearwm.sock".to_string(),
+ }
+}
+
fn send_ipc_command(cmd: &str) {
- if let Ok(mut stream) = std::os::unix::net::UnixStream::connect("/tmp/clearwm.sock") {
+ if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
use std::io::Write;
let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
}
@@ -286,34 +297,15 @@ fn read_border_font_size() -> Option<u16> {
Some(parse_u16_from(&content, "border_font_size", 11))
}
-fn read_waybar_size() -> Option<u16> {
- let css = fs::read_to_string("/home/lsgalante/.config/waybar/style.css").ok()?;
- for line in css.lines() {
- if line.contains("font-size") {
- let val = line.split(':').nth(1)?.trim().trim_end_matches(';').trim();
- if let Some(px) = val.strip_suffix("px") {
- return px.trim().parse::<u16>().ok();
- }
- return val.parse::<u16>().ok();
- }
- }
- None
+fn read_status_size() -> Option<u16> {
+ let content = fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").ok()?;
+ Some(parse_u16_from(&content, "status_font_size", 11))
}
-fn write_waybar_size(size: u16) {
- let path = "/home/lsgalante/.config/waybar/style.css";
- let css = fs::read_to_string(path).unwrap_or_default();
- let mut new_lines = Vec::new();
- for line in css.lines() {
- if line.contains("font-size") {
- new_lines.push(format!(" font-size: {}px;", size));
- } else {
- new_lines.push(line.to_string());
- }
- }
- let _ = fs::write(path, new_lines.join("\n"));
+fn write_status_size(size: u16) {
+ write_config_value("status_font_size", &size.to_string());
let _ = std::process::Command::new("pkill")
- .args(["-x", "waybar", "-SIGUSR2"])
+ .args(["-f", "clear-status-interface"])
.spawn();
}
@@ -465,7 +457,7 @@ pub async fn fetch_typeface_state() -> TypefaceState {
terminal_box.disabled = terminal_idx != 3;
let borders_size = read_border_font_size().unwrap_or(11);
- let status_size = read_waybar_size().unwrap_or(13);
+ let status_size = read_status_size().unwrap_or(11);
let fuzzel_size = read_fuzzel_size().unwrap_or(14);
let terminal_size = read_terminal_size().unwrap_or(12);
@@ -498,6 +490,8 @@ pub async fn fetch_typeface_state() -> TypefaceState {
status_size_box: Spinbox::new(status_size as i32, 6, 72, 1),
fuzzel_size_box: Spinbox::new(fuzzel_size as i32, 6, 72, 1),
terminal_size_box: Spinbox::new(terminal_size as i32, 6, 72, 1),
+ font_buttons: Vec::new(),
+ copy_buttons: Vec::new(),
}
}
@@ -644,6 +638,16 @@ pub fn view(state: &mut TypefaceState, cx: f32, cy: f32, cw: f32, _ch: f32, sec_
.filter(|font| font.to_lowercase().contains(&query))
.collect();
+ // Ensure we have exactly matching_fonts.len() buttons of each type
+ if state.font_buttons.len() != matching_fonts.len() {
+ state.font_buttons.clear();
+ state.copy_buttons.clear();
+ for _ in 0..matching_fonts.len() {
+ state.font_buttons.push(Button::new_list_row(0.0, 0.0, 0.0, 0.0));
+ state.copy_buttons.push(Button::new_copy_icon(0.0, 0.0, 0.0, 0.0));
+ }
+ }
+
let btn_h = 24.0;
let inner_x = left_x + 4.0;
let inner_w = left_w - 16.0; // leave room for scrollbar
@@ -658,41 +662,15 @@ pub fn view(state: &mut TypefaceState, cx: f32, cy: f32, cw: f32, _ch: f32, sec_
if let Some(draw_y) = state.list_box.get_item_draw_y(idx, 0.0) {
let is_selected = state.selected_font.as_ref() == Some(*font_name);
- let (bg, hover_bg, text_color) = if is_selected {
- ([0.20, 0.40, 0.65, 0.4], [0.30, 0.52, 0.78, 0.6], [0.90, 0.90, 0.95, 1.0])
- } else {
- ([0.0, 0.0, 0.0, 0.0], [0.20, 0.20, 0.25, 0.15], [0.70, 0.70, 0.75, 1.0])
- };
-
- pc.button(
- font_name,
- inner_x,
- draw_y,
- inner_w - 44.0,
- btn_h,
- bg,
- hover_bg,
- text_color,
- crate::app::AppAction::Typeface(TypefaceMessage::SelectFont((*font_name).clone())),
- );
-
- let (copy_bg, copy_hover_bg, copy_text_color) = if is_selected {
- ([0.20, 0.40, 0.65, 0.2], [0.30, 0.52, 0.78, 0.5], [0.90, 0.90, 0.95, 1.0])
- } else {
- ([0.0, 0.0, 0.0, 0.0], [0.20, 0.20, 0.25, 0.25], [0.70, 0.70, 0.75, 1.0])
- };
-
- pc.button(
- "📋",
- inner_x + inner_w - 40.0,
- draw_y,
- 40.0,
- btn_h,
- copy_bg,
- copy_hover_bg,
- copy_text_color,
- crate::app::AppAction::Typeface(TypefaceMessage::CopyFontName((*font_name).clone())),
- );
+ let font_btn = &mut state.font_buttons[idx];
+ font_btn.label = Some((*font_name).clone());
+ font_btn.selected = is_selected;
+ clear_ui::layout::render_widget(&mut pc, font_btn, inner_x, draw_y, inner_w - 44.0, btn_h);
+
+ let copy_btn = &mut state.copy_buttons[idx];
+ copy_btn.label = Some("📋".to_string());
+ copy_btn.selected = is_selected;
+ clear_ui::layout::render_widget(&mut pc, copy_btn, inner_x + inner_w - 40.0, draw_y, 40.0, btn_h);
}
}
@@ -896,6 +874,8 @@ pub fn update(state: &mut TypefaceState, msg: TypefaceMessage) {
state.status_size_box = new.status_size_box;
state.fuzzel_size_box = new.fuzzel_size_box;
state.terminal_size_box = new.terminal_size_box;
+ state.font_buttons = new.font_buttons;
+ state.copy_buttons = new.copy_buttons;
let old_scroll = state.list_box.scroll_y();
state.list_box = new.list_box;
state.list_box.set_scroll_y(old_scroll);
@@ -1193,7 +1173,7 @@ pub fn update(state: &mut TypefaceState, msg: TypefaceMessage) {
}
TypefaceMessage::SetStatusSize(val) => {
state.status_size_box.value = val;
- write_waybar_size(val as u16);
+ write_status_size(val as u16);
}
TypefaceMessage::SetFuzzelSize(val) => {
state.fuzzel_size_box.value = val;