progress - working on nix, transparent window

This commit is contained in:
Daniel Bulant 2024-10-09 12:07:33 +02:00
parent 7a2630310f
commit 8549937247
No known key found for this signature in database
5 changed files with 79 additions and 62 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
/result
/http-cacache

View file

@ -92,14 +92,14 @@
in in
rec { rec {
checks = { checks = {
rustnix = cargoNix.rootCrate.build.override { rshell = cargoNix.rootCrate.build.override {
runTests = true; runTests = true;
}; };
}; };
packages = { packages = {
rustnix = cargoNix.rootCrate.build; rshell = cargoNix.rootCrate.build;
default = packages.rustnix; default = packages.rshell;
inherit (pkgs) rust-toolchain; inherit (pkgs) rust-toolchain;

View file

@ -6,16 +6,7 @@
config.perSystem = config.perSystem =
{ pkgs { pkgs
, ... , ...
}: { }: let
config.devshells.default = {
imports = [
"${inputs.devshell}/extra/language/c.nix"
# "${inputs.devshell}/extra/language/rust.nix"
];
devshell = {
name = "rshell devshell";
packages = with pkgs; [ packages = with pkgs; [
libxkbcommon libxkbcommon
libGL libGL
@ -28,30 +19,40 @@
xorg.libXi xorg.libXi
xorg.libX11 xorg.libX11
openssl openssl
pkg-config
]; ];
in {
config.devshells.default = {
imports = [
"${inputs.devshell}/extra/language/c.nix"
# "${inputs.devshell}/extra/language/rust.nix"
];
devshell = {
name = "rshell devshell";
packages = packages ++ [ pkgs.pkg-config ];
}; };
env = [{
name = "LD_LIBRARY_PATH";
value = lib.makeLibraryPath packages;
} {
name = "PKG_CONFIG_PATH";
value = lib.concatStringsSep ":"
( map
( pkg: "${pkg.dev}/lib/pkgconfig" )
( packages )
);
#"${pkgs.openssl.dev}/lib/pkgconfig";
}];
commands = with pkgs; [ commands = with pkgs; [
{ package = rust-toolchain; category = "rust"; } { package = rust-toolchain; category = "rust"; }
]; ];
language.c = { language.c = {
libraries = libraries =
(with pkgs; [ packages ++
libxkbcommon
libGL
dbus
wayland
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
openssl
pkg-config
]) ++
(lib.optional pkgs.stdenv.isDarwin pkgs.libiconv); (lib.optional pkgs.stdenv.isDarwin pkgs.libiconv);
}; };
}; };

View file

@ -1,4 +1,4 @@
use cushy::{Open, PendingApp, Run, TokioRuntime}; use cushy::{styles::{components::DefaultBackgroundColor, Color}, widget::MakeWidget, Open, PendingApp, Run, TokioRuntime};
mod spotify; mod spotify;
mod vibrancy; mod vibrancy;
@ -6,7 +6,13 @@ mod vibrancy;
fn main() -> cushy::Result { fn main() -> cushy::Result {
let mut app = PendingApp::new(TokioRuntime::default()); let mut app = PendingApp::new(TokioRuntime::default());
spotify::spotify_controls() spotify::spotify_controls()
.centered()
.with(&DefaultBackgroundColor, Color::CLEAR_WHITE)
.into_window()
.transparent()
.app_name("rshell")
.open(&mut app)?; .open(&mut app)?;
app.run() app.run()

View file

@ -1,9 +1,10 @@
use std::{sync::{Arc, Mutex}, thread, time::Duration}; use std::{sync::{Arc, Mutex}, thread, time::Duration};
use http_cache_reqwest::{CACacheManager, Cache, CacheMode, HttpCache, HttpCacheOptions};
use mpris::{LoopStatus, PlaybackStatus, PlayerFinder}; use mpris::{LoopStatus, PlaybackStatus, PlayerFinder};
use cushy::{kludgine::{AnyTexture, LazyTexture}, styles::{components::WidgetBackground, Color}, value::{Destination, Dynamic, IntoReader, Source}, widget::MakeWidget, widgets::Image, Open, PendingApp}; use cushy::{figures::{units::Lp, Size}, kludgine::{AnyTexture, LazyTexture}, styles::{components::WidgetBackground, Color, Dimension, DimensionRange}, value::{Destination, Dynamic, IntoReader, Source}, widget::MakeWidget, widgets::{image::ImageCornerRadius, Image}};
use palette::Srgb;
use reqwest::Client; use reqwest::Client;
use reqwest_middleware::ClientBuilder;
use image::{self, Rgb}; use image::{self, Rgb};
use tokio::{runtime, task::JoinHandle}; use tokio::{runtime, task::JoinHandle};
use crate::vibrancy::Vibrancy; use crate::vibrancy::Vibrancy;
@ -22,10 +23,19 @@ struct PlayingTrack {
loop_status: LoopStatus, loop_status: LoopStatus,
} }
/// Renders spotify control widget, the small one
pub fn spotify_controls() -> impl MakeWidget { pub fn spotify_controls() -> impl MakeWidget {
let (progress, track) = get_track_dynamics(); let (progress, track) = get_track_dynamics();
let (texture, vibrancy) = get_texture_dynamic(track.clone()); let (texture, vibrancy) = get_texture_dynamic(track.clone());
const IMAGE_SIZE: i32 = 16 /* lineheight */ + 2 * 6 /* padding */ + 8; // Why the 8 there? I don't know, but it works.
Image::new(texture)
.aspect_fit()
// .with(&ImageCornerRadius, Lp::points(6))
// default pad is 6, default line height is 16
.size(Size::new(DimensionRange::from(Dimension::Lp(Lp::points(IMAGE_SIZE))), DimensionRange::from(Dimension::Lp(Lp::points(IMAGE_SIZE)))))
.and(
track.map_each(|track| { track.map_each(|track| {
if let Some(track) = track { if let Some(track) = track {
format!( format!(
@ -40,12 +50,10 @@ pub fn spotify_controls() -> impl MakeWidget {
.to_label() .to_label()
.centered() .centered()
.pad() .pad()
.and(
Image::new(texture)
) )
.into_rows() .into_columns()
.with(&WidgetBackground, vibrancy.map_each(|vib| vib.dark.unwrap_or(Color::BLACK).into())) .with(&WidgetBackground, Color::CLEAR_WHITE) // vibrancy.map_each(|vib| vib.muted.unwrap_or(Color::BLACK).into()))
.pad() // .size(Size::new(DimensionRange::default(), DimensionRange::from(Dimension::Lp(Lp::points(28)))))
} }
fn get_empty_texture() -> AnyTexture { fn get_empty_texture() -> AnyTexture {
@ -63,12 +71,6 @@ fn tokio_runtime() -> &'static runtime::Handle {
use std::sync::OnceLock; use std::sync::OnceLock;
use std::time::Duration; use std::time::Duration;
use cushy::value::{Destination, Dynamic};
use cushy::widget::MakeWidget;
use cushy::widgets::progress::Progressable;
use cushy::Run;
use tokio::time::sleep;
static RUNTIME: OnceLock<runtime::Handle> = OnceLock::new(); static RUNTIME: OnceLock<runtime::Handle> = OnceLock::new();
RUNTIME.get_or_init(|| { RUNTIME.get_or_init(|| {
let rt = runtime::Builder::new_multi_thread() let rt = runtime::Builder::new_multi_thread()
@ -100,7 +102,13 @@ pub struct ImageVibrancy {
} }
fn get_texture_dynamic(track: Dynamic<Option<PlayingTrack>>) -> (Dynamic<AnyTexture>, Dynamic<ImageVibrancy>) { fn get_texture_dynamic(track: Dynamic<Option<PlayingTrack>>) -> (Dynamic<AnyTexture>, Dynamic<ImageVibrancy>) {
let client = Client::new(); let client = ClientBuilder::new(Client::new())
.with(Cache(HttpCache {
mode: CacheMode::Default,
manager: CACacheManager::default(),
options: HttpCacheOptions::default(),
}))
.build();
let texture = Dynamic::new(get_empty_texture()); let texture = Dynamic::new(get_empty_texture());