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
/result
/http-cacache

View file

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

View file

@ -6,7 +6,21 @@
config.perSystem =
{ pkgs
, ...
}: {
}: let
packages = with pkgs; [
libxkbcommon
libGL
dbus
wayland
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
openssl
];
in {
config.devshells.default = {
imports = [
"${inputs.devshell}/extra/language/c.nix"
@ -16,42 +30,29 @@
devshell = {
name = "rshell devshell";
packages = with pkgs; [
libxkbcommon
libGL
dbus
wayland
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
openssl
pkg-config
];
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; [
{ package = rust-toolchain; category = "rust"; }
];
language.c = {
libraries =
(with pkgs; [
libxkbcommon
libGL
dbus
wayland
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
openssl
pkg-config
]) ++
packages ++
(lib.optional pkgs.stdenv.isDarwin pkgs.libiconv);
};
};

View file

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

View file

@ -1,9 +1,10 @@
use std::{sync::{Arc, Mutex}, thread, time::Duration};
use http_cache_reqwest::{CACacheManager, Cache, CacheMode, HttpCache, HttpCacheOptions};
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 palette::Srgb;
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 reqwest::Client;
use reqwest_middleware::ClientBuilder;
use image::{self, Rgb};
use tokio::{runtime, task::JoinHandle};
use crate::vibrancy::Vibrancy;
@ -22,30 +23,37 @@ struct PlayingTrack {
loop_status: LoopStatus,
}
/// Renders spotify control widget, the small one
pub fn spotify_controls() -> impl MakeWidget {
let (progress, track) = get_track_dynamics();
let (texture, vibrancy) = get_texture_dynamic(track.clone());
track.map_each(|track| {
if let Some(track) = track {
format!(
"{} - {}",
track.artist,
track.title,
)
} else {
"No track playing".to_string()
}
})
.to_label()
.centered()
.pad()
.and(
Image::new(texture)
)
.into_rows()
.with(&WidgetBackground, vibrancy.map_each(|vib| vib.dark.unwrap_or(Color::BLACK).into()))
.pad()
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| {
if let Some(track) = track {
format!(
"{} - {}",
track.artist,
track.title,
)
} else {
"No track playing".to_string()
}
})
.to_label()
.centered()
.pad()
)
.into_columns()
.with(&WidgetBackground, Color::CLEAR_WHITE) // vibrancy.map_each(|vib| vib.muted.unwrap_or(Color::BLACK).into()))
// .size(Size::new(DimensionRange::default(), DimensionRange::from(Dimension::Lp(Lp::points(28)))))
}
fn get_empty_texture() -> AnyTexture {
@ -63,12 +71,6 @@ fn tokio_runtime() -> &'static runtime::Handle {
use std::sync::OnceLock;
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();
RUNTIME.get_or_init(|| {
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>) {
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());