From 2f272b026f8882a8658416a21e7eb7f1ffaffeb9 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Wed, 8 Jan 2025 20:39:43 +0100 Subject: [PATCH] progress - working spotify, time --- Cargo.lock | 121 ++++++++++++++++++++++++++++++++------------- Cargo.toml | 3 +- src/bar/mod.rs | 25 +++++++--- src/bar/spotify.rs | 29 ++--------- src/bar/time.rs | 48 ++++++++++++++++++ src/main.rs | 9 ++-- src/rt.rs | 25 ++++++++++ src/theme.rs | 9 +++- 8 files changed, 195 insertions(+), 74 deletions(-) create mode 100644 src/bar/time.rs create mode 100644 src/rt.rs diff --git a/Cargo.lock b/Cargo.lock index 9c36494..027e4ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,6 +94,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -405,9 +411,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.84" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1244b10dcd56c92219da4e14caa97e312079e185f04ba3eea25061561dc0a0" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote 1.0.38", @@ -746,10 +752,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] -name = "clap" -version = "4.5.23" +name = "chrono" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "clap" +version = "4.5.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", "clap_derive", @@ -757,9 +777,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -769,9 +789,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1296,9 +1316,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -2057,6 +2077,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -2414,7 +2457,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kludgine" version = "0.11.0" -source = "git+https://github.com/khonsulabs/kludgine#ac9f91e5a92257b5635ecf3c48075d143e337876" +source = "git+https://github.com/khonsulabs/kludgine#2d8bb23f6c2b1c2b563490cbd115089a9fba9121" dependencies = [ "ahash", "alot", @@ -2503,9 +2546,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -3361,9 +3404,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -3371,9 +3414,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand", @@ -3381,9 +3424,9 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", @@ -3394,9 +3437,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] @@ -3970,6 +4013,7 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" name = "rshell" version = "0.1.0" dependencies = [ + "chrono", "clap", "color_quant", "cushy", @@ -4002,9 +4046,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags 2.6.0", "errno", @@ -4133,9 +4177,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -4178,9 +4222,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -4294,9 +4338,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "skrifa" @@ -5477,7 +5521,7 @@ dependencies = [ "web-sys", "wgpu-types", "windows", - "windows-core", + "windows-core 0.58.0", ] [[package]] @@ -5540,7 +5584,16 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets 0.52.6", ] @@ -5975,9 +6028,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" [[package]] name = "xxhash-rust" diff --git a/Cargo.toml b/Cargo.toml index 6649ac6..c81c530 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ cushy = { git = "https://github.com/khonsulabs/cushy.git", branch = "main", feat "plotters", "roboto-flex", ] } -tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread"] } +tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread", "time"] } plotters = { version = "0.3.7", default-features = false } image = { version = "0.25.0", features = ["png"] } mpris = "2.0.1" @@ -27,6 +27,7 @@ clap = { version = "4.5.20", features = ["derive"] } fuzzy-matcher = "0.3.5" freedesktop-desktop-entry = "0.7.5" which = "7.0.1" +chrono = "0.4.39" [patch.crates-io] winit = { path = "../winit" } diff --git a/src/bar/mod.rs b/src/bar/mod.rs index 7038039..1f71fe4 100644 --- a/src/bar/mod.rs +++ b/src/bar/mod.rs @@ -1,24 +1,35 @@ use cushy::{ - figures::{units::Px, Point}, + figures::{ + units::{Lp, UPx}, + Size, + }, kludgine::app::winit::{platform::wayland::Anchor, window::WindowLevel}, - value::{Destination, Dynamic, Source}, + value::Dynamic, widget::MakeWidget, Application, Open, }; mod spotify; +mod time; pub fn start_bar(app: &mut impl Application) -> cushy::Result { - let pos = Dynamic::default(); - let mut window = spotify::spotify_controls() - .pad() + let monitors = (app.as_app().monitors()).unwrap(); + let mut monitor_size: Size = monitors.available[0].size().into(); + monitor_size.height = UPx::new(40); + let size = Dynamic::new(monitor_size); + let mut window = (time::time_widget().pad()) + .and(spotify::spotify_controls().pad()) + .into_columns() .centered() .expand_horizontally() + .height(Lp::points(30)) .into_window() + .inner_size(size.clone()) + .titled("rshell") .transparent() .app_name("rshell") .decorated(false) - .outer_position(pos.clone(), false) + .resize_to_fit(false) .window_level(WindowLevel::AlwaysOnTop); window @@ -26,7 +37,7 @@ pub fn start_bar(app: &mut impl Application) -> cushy::Result { .push(cushy::styles::FamilyOwned::Name("Iosevka NF".into())); window.open(app).map(|handle| { - handle.execute(|ctx| { + handle.execute(move |ctx| { // safe unwrap: we just created the window let winit = ctx.winit().unwrap(); winit.set_exclusive_zone(40); diff --git a/src/bar/spotify.rs b/src/bar/spotify.rs index 26d295b..0381fee 100644 --- a/src/bar/spotify.rs +++ b/src/bar/spotify.rs @@ -5,6 +5,7 @@ use std::{ }; use crate::{ + rt::tokio_runtime, theme::{BG_DEFAULT, CORNER_RADIUS, TEXT_SPOTIFY}, vibrancy::Vibrancy, }; @@ -72,8 +73,8 @@ pub fn spotify_controls() -> impl MakeWidget { }) .into_label() .with(&TextColor, TEXT_SPOTIFY) - // .with(&FontWeight, Weight::BOLD) - .with(&TextSize, Dimension::Lp(Lp::points(10))) + .with(&FontWeight, Weight::BOLD) + .with(&TextSize, Dimension::Lp(Lp::points(8))) .with(&LineHeight, Dimension::Lp(Lp::points(10))) .centered() .pad(), @@ -90,30 +91,6 @@ fn get_empty_texture() -> AnyTexture { )) } -fn tokio_runtime() -> &'static runtime::Handle { - use std::sync::OnceLock; - use std::time::Duration; - - static RUNTIME: OnceLock = OnceLock::new(); - RUNTIME.get_or_init(|| { - let rt = runtime::Builder::new_multi_thread() - .enable_all() - .build() - .expect("tokio initialization error"); - let handle = rt.handle().clone(); - std::thread::spawn(move || { - // Replace with the async main loop, or some sync structure to - // control shutting it down if desired. - rt.block_on(async { - loop { - tokio::time::sleep(Duration::from_secs(10000)).await - } - }); - }); - handle - }) -} - #[derive(Debug, PartialEq, Eq, Default)] pub struct ImageVibrancy { primary: Option, diff --git a/src/bar/time.rs b/src/bar/time.rs new file mode 100644 index 0000000..06d8033 --- /dev/null +++ b/src/bar/time.rs @@ -0,0 +1,48 @@ +use chrono::{Local, Timelike}; +use cushy::{ + styles::components::{TextColor, WidgetBackground}, + value::{Destination, Dynamic, MapEach}, + widget::MakeWidget, +}; + +use crate::{ + rt::tokio_runtime, + theme::{BG_DEFAULT, TEXT_CLOCK}, +}; + +const FORMAT: &'static str = " %H:%M %p 󰃭 %a %d"; +const FORMAT_ALT: &'static str = " %H:%M  %b %Y"; + +const CLOCK_ICONS: [&'static str; 12] = + ["", "", "", "", "", "", "", "", "", "", "", ""]; +const CLOCK_ICONS_ALT: [&'static str; 12] = + ["󱑊", "󱐿", "󱑀", "󱑁", "󱑂", "󱑃", "󱑄", "󱑅", "󱑆", "󱑇", "󱑈", "󱑉"]; + +pub fn time_widget() -> impl MakeWidget { + let current_time = Dynamic::new(Local::now()); + tokio_runtime().spawn({ + let current_time = current_time.clone(); + async move { + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(1)); + loop { + interval.tick().await; + current_time.set(Local::now()); + } + } + }); + let show_year = Dynamic::new(false); + + (¤t_time, &show_year) + .map_each(|(current_time, show_year)| { + let (icon_set, format) = match show_year { + true => (&CLOCK_ICONS_ALT, FORMAT_ALT), + false => (&CLOCK_ICONS, FORMAT), + }; + let icon = icon_set[current_time.hour12().1 as usize % 12].to_string(); + icon + ¤t_time.format(format).to_string() + }) + .with(&TextColor, TEXT_CLOCK) + .pad() + .centered() + .with(&WidgetBackground, BG_DEFAULT) +} diff --git a/src/main.rs b/src/main.rs index a64aec7..3d64776 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use menu::start_menu; mod bar; mod cli; mod menu; +pub mod rt; mod theme; mod vibrancy; @@ -14,11 +15,11 @@ fn main() -> cushy::Result { let args = Args::parse(); let mut app = PendingApp::new(TokioRuntime::default()); - match args.cmd { - Commands::Bar => start_bar(&mut app)?, - Commands::Menu => start_menu(&mut app)?, + app.on_startup(move |app| match args.cmd { + Commands::Bar => start_bar(app).unwrap(), + Commands::Menu => start_menu(app).unwrap(), Commands::Power => todo!(), - } + }); // Ok(()) app.run() diff --git a/src/rt.rs b/src/rt.rs new file mode 100644 index 0000000..638f0f3 --- /dev/null +++ b/src/rt.rs @@ -0,0 +1,25 @@ +use tokio::runtime; + +pub fn tokio_runtime() -> &'static runtime::Handle { + use std::sync::OnceLock; + use std::time::Duration; + + static RUNTIME: OnceLock = OnceLock::new(); + RUNTIME.get_or_init(|| { + let rt = runtime::Builder::new_multi_thread() + .enable_all() + .build() + .expect("tokio initialization error"); + let handle = rt.handle().clone(); + std::thread::spawn(move || { + // Replace with the async main loop, or some sync structure to + // control shutting it down if desired. + rt.block_on(async { + loop { + tokio::time::sleep(Duration::from_secs(10000)).await + } + }); + }); + handle + }) +} diff --git a/src/theme.rs b/src/theme.rs index 49ecfea..410ec28 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -3,6 +3,11 @@ use cushy::{ styles::{Color, Dimension}, }; -pub const TEXT_SPOTIFY: Color = Color(0x1DB954FF); -pub const BG_DEFAULT: Color = Color(0x191724FF); pub const CORNER_RADIUS: Dimension = Dimension::Lp(Lp::points(6)); + +pub const BG_DEFAULT: Color = Color(0x191724FF); +pub const TEXT_SPOTIFY: Color = Color(0x1DB954FF); +pub const TEXT_CLOCK: Color = Color(0xF6C177FF); +pub const TEXT_CPU: Color = Color(0xff671fFF); +pub const TEXT_MEM: Color = Color(0x1DB954FF); +pub const TEXT_TEMP: Color = Color(0x97f993FF);