Compare commits

...

8 commits

Author SHA1 Message Date
Stephen Seo fb6d3b7c13 Update README.md, version 0.4.5 2023-03-02 21:36:42 +09:00
Stephen Seo 3064784139 Backport: Impl passing password via file 2023-03-02 21:33:01 +09:00
Stephen Seo d576a0ff8c Version 0.4.4, update README.md 2023-03-01 22:00:24 +09:00
Stephen Seo 6bf05623d8 Backport: Fix timer bg not updating
This commit fixes the bg mesh (slightly-transparent-black-bg for text)
not updating when the timer-text changes size.
2023-03-01 21:54:13 +09:00
Stephen Seo 675df211cd Update README.md 2023-02-04 19:44:59 +09:00
Stephen Seo c782a3048d Update version, README.md 2023-02-04 19:42:02 +09:00
Stephen Seo 27c3d8c5cd Backport Fix: display not working when no password
Previous implementation only worked if MPD was accessed with a password.
This commit fixes no-password access of MPD.
2023-02-04 19:40:27 +09:00
Stephen Seo cd4d4f60e4 workaround version 0.4.2 2023-02-04 19:33:57 +09:00
6 changed files with 82 additions and 24 deletions

2
Cargo.lock generated
View file

@ -1668,7 +1668,7 @@ dependencies = [
[[package]] [[package]]
name = "mpd_info_screen" name = "mpd_info_screen"
version = "0.3.7" version = "0.4.5"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"freetype", "freetype",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "mpd_info_screen" name = "mpd_info_screen"
version = "0.3.7" version = "0.4.5"
edition = "2018" edition = "2018"
description = "Displays info on currently playing music from an MPD daemon" description = "Displays info on currently playing music from an MPD daemon"
license = "MIT" license = "MIT"

View file

@ -12,6 +12,23 @@ A Rust program that displays info about the currently running MPD server.
The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining" The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining"
counter, and the filename currently being played counter, and the filename currently being played
## Known Bugs ❗❗
Version `0.4.5` is a "workaround" release that is branched off of version
`0.3.7`. Once a new release of `ggez` is released that fixes the known bugs,
a new version will be released with the fixes. Because this is based on
`0.3.7` of `mpd_info_screen`, Wayland support may not work. Try using `xwayland`
with the environment variable `WINIT_UNIX_BACKEND=x11` set. A future release
using the latest version of `ggez` should work with Wayland.
Currently, the dependency "ggez 0.8.1"
[fails to render album art](https://github.com/Stephen-Seo/mpd_info_screen/issues/1)
on my machines using the latest version of this program (`main` branch). A
version with this fix cannot be published to https://crates.io due to this
version referring to a git commit as a dependency. Once ggez has released a new
version with the commit that fixes this bug, this repository will be updated to
use that version.
## Unicode Support ## Unicode Support
By default, unicode characters will not display properly. Build the project with By default, unicode characters will not display properly. Build the project with
@ -23,11 +40,13 @@ installed already).
cargo build --release --features unicode_support cargo build --release --features unicode_support
or through crates.io:
cargo install --features unicode_support mpd_info_screen
# Usage # Usage
mpd_info_screen 0.3.7
USAGE: USAGE:
mpd_info_screen [FLAGS] [OPTIONS] <host> [port] mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
@ -44,10 +63,11 @@ installed already).
OPTIONS: OPTIONS:
-l, --log-level <log-level> [default: Error] [possible values: Error, Warning, Debug, Verbose] -l, --log-level <log-level> [default: Error] [possible values: Error, Warning, Debug, Verbose]
-p <password> -p <password>
--pfile <password-file> read password from file
-t, --text-bg-opacity <text-bg-opacity> sets the opacity of the text background (0-255) [default: 190] -t, --text-bg-opacity <text-bg-opacity> sets the opacity of the text background (0-255) [default: 190]
ARGS: ARGS:
<host> <host>
<port> [default: 6600] <port> [default: 6600]

View file

@ -203,11 +203,17 @@ pub struct MPDDisplay {
album_string_cache: String, album_string_cache: String,
album_transform: Transform, album_transform: Transform,
timer_text: Text, timer_text: Text,
timer_text_len: usize,
timer_transform: Transform, timer_transform: Transform,
timer_x: f32, timer_x: f32,
timer_y: f32, timer_y: f32,
timer: f64, timer: f64,
length: f64, length: f64,
cached_filename_y: f32,
cached_album_y: f32,
cached_artist_y: f32,
cached_title_y: f32,
cached_timer_y: f32,
text_bg_mesh: Option<Mesh>, text_bg_mesh: Option<Mesh>,
hide_text: bool, hide_text: bool,
tried_album_art_in_dir: bool, tried_album_art_in_dir: bool,
@ -237,11 +243,17 @@ impl MPDDisplay {
title_text: Text::default(), title_text: Text::default(),
title_transform: Transform::default(), title_transform: Transform::default(),
timer_text: Text::new("0"), timer_text: Text::new("0"),
timer_text_len: 0,
timer_transform: Transform::default(), timer_transform: Transform::default(),
timer_x: INIT_FONT_SIZE_X, timer_x: INIT_FONT_SIZE_X,
timer_y: INIT_FONT_SIZE_Y, timer_y: INIT_FONT_SIZE_Y,
timer: 0.0, timer: 0.0,
length: 0.0, length: 0.0,
cached_filename_y: 0.0f32,
cached_album_y: 0.0f32,
cached_artist_y: 0.0f32,
cached_title_y: 0.0f32,
cached_timer_y: 0.0f32,
text_bg_mesh: None, text_bg_mesh: None,
hide_text: false, hide_text: false,
tried_album_art_in_dir: false, tried_album_art_in_dir: false,
@ -446,12 +458,6 @@ impl MPDDisplay {
let mut offset_y: f32 = screen_coords.h; let mut offset_y: f32 = screen_coords.h;
let mut filename_y: f32 = 0.0;
let mut album_y: f32 = 0.0;
let mut artist_y: f32 = 0.0;
let mut title_y: f32 = 0.0;
let mut timer_y: f32 = 0.0;
let set_transform = |text: &mut Text, let set_transform = |text: &mut Text,
transform: &mut Transform, transform: &mut Transform,
offset_y: &mut f32, offset_y: &mut f32,
@ -535,7 +541,7 @@ impl MPDDisplay {
&mut self.filename_text, &mut self.filename_text,
&mut self.filename_transform, &mut self.filename_transform,
&mut offset_y, &mut offset_y,
&mut filename_y, &mut self.cached_filename_y,
true, true,
false, false,
false, false,
@ -555,7 +561,7 @@ impl MPDDisplay {
&mut self.album_text, &mut self.album_text,
&mut self.album_transform, &mut self.album_transform,
&mut offset_y, &mut offset_y,
&mut album_y, &mut self.cached_album_y,
true, true,
false, false,
true, true,
@ -569,7 +575,7 @@ impl MPDDisplay {
&mut self.artist_text, &mut self.artist_text,
&mut self.artist_transform, &mut self.artist_transform,
&mut offset_y, &mut offset_y,
&mut artist_y, &mut self.cached_artist_y,
true, true,
true, true,
false, false,
@ -589,7 +595,7 @@ impl MPDDisplay {
&mut self.title_text, &mut self.title_text,
&mut self.title_transform, &mut self.title_transform,
&mut offset_y, &mut offset_y,
&mut title_y, &mut self.cached_title_y,
true, true,
false, false,
false, false,
@ -608,7 +614,7 @@ impl MPDDisplay {
&mut self.timer_text, &mut self.timer_text,
&mut self.timer_transform, &mut self.timer_transform,
&mut offset_y, &mut offset_y,
&mut timer_y, &mut self.cached_timer_y,
false, false,
false, false,
false, false,
@ -616,6 +622,12 @@ impl MPDDisplay {
&mut self.timer_y, &mut self.timer_y,
); );
self.update_bg_mesh(ctx)?;
Ok(())
}
fn update_bg_mesh(&mut self, ctx: &mut Context) -> GameResult<()> {
let filename_dimensions = self.filename_text.dimensions(ctx); let filename_dimensions = self.filename_text.dimensions(ctx);
let album_dimensions = self.album_text.dimensions(ctx); let album_dimensions = self.album_text.dimensions(ctx);
let artist_dimensions = self.artist_text.dimensions(ctx); let artist_dimensions = self.artist_text.dimensions(ctx);
@ -628,7 +640,7 @@ impl MPDDisplay {
DrawMode::fill(), DrawMode::fill(),
Rect { Rect {
x: TEXT_X_OFFSET, x: TEXT_X_OFFSET,
y: filename_y, y: self.cached_filename_y,
w: filename_dimensions.w, w: filename_dimensions.w,
h: filename_dimensions.h, h: filename_dimensions.h,
}, },
@ -640,7 +652,7 @@ impl MPDDisplay {
DrawMode::fill(), DrawMode::fill(),
Rect { Rect {
x: TEXT_X_OFFSET, x: TEXT_X_OFFSET,
y: album_y, y: self.cached_album_y,
w: album_dimensions.w, w: album_dimensions.w,
h: album_dimensions.h, h: album_dimensions.h,
}, },
@ -652,7 +664,7 @@ impl MPDDisplay {
DrawMode::fill(), DrawMode::fill(),
Rect { Rect {
x: TEXT_X_OFFSET, x: TEXT_X_OFFSET,
y: artist_y, y: self.cached_artist_y,
w: artist_dimensions.w, w: artist_dimensions.w,
h: artist_dimensions.h, h: artist_dimensions.h,
}, },
@ -664,7 +676,7 @@ impl MPDDisplay {
DrawMode::fill(), DrawMode::fill(),
Rect { Rect {
x: TEXT_X_OFFSET, x: TEXT_X_OFFSET,
y: title_y, y: self.cached_title_y,
w: title_dimensions.w, w: title_dimensions.w,
h: title_dimensions.h, h: title_dimensions.h,
}, },
@ -676,7 +688,7 @@ impl MPDDisplay {
DrawMode::fill(), DrawMode::fill(),
Rect { Rect {
x: TEXT_X_OFFSET, x: TEXT_X_OFFSET,
y: timer_y, y: self.cached_timer_y,
w: timer_dimensions.w, w: timer_dimensions.w,
h: timer_dimensions.h, h: timer_dimensions.h,
}, },
@ -885,6 +897,7 @@ impl EventHandler for MPDDisplay {
let delta = timer::delta(ctx); let delta = timer::delta(ctx);
self.timer += delta.as_secs_f64(); self.timer += delta.as_secs_f64();
let timer_diff = seconds_to_time(self.length - self.timer); let timer_diff = seconds_to_time(self.length - self.timer);
let timer_diff_len = timer_diff.len();
self.timer_text = Text::new(timer_diff); self.timer_text = Text::new(timer_diff);
self.timer_text.set_font( self.timer_text.set_font(
Font::default(), Font::default(),
@ -893,6 +906,10 @@ impl EventHandler for MPDDisplay {
y: self.timer_y, y: self.timer_y,
}, },
); );
if timer_diff_len != self.timer_text_len {
self.timer_text_len = timer_diff_len;
self.update_bg_mesh(ctx)?;
}
Ok(()) Ok(())
} }

View file

@ -10,6 +10,8 @@ use ggez::event::{self, ControlFlow, EventHandler};
use ggez::filesystem::mount; use ggez::filesystem::mount;
use ggez::graphics::{self, Rect}; use ggez::graphics::{self, Rect};
use ggez::{ContextBuilder, GameError}; use ggez::{ContextBuilder, GameError};
use std::fs::File;
use std::io::Read;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::path::PathBuf; use std::path::PathBuf;
use std::thread; use std::thread;
@ -36,6 +38,8 @@ pub struct Opt {
disable_show_filename: bool, disable_show_filename: bool,
#[structopt(long = "pprompt", help = "input password via prompt")] #[structopt(long = "pprompt", help = "input password via prompt")]
enable_prompt_password: bool, enable_prompt_password: bool,
#[structopt(long = "pfile", help = "read password from file")]
password_file: Option<PathBuf>,
#[structopt( #[structopt(
long = "no-scale-fill", long = "no-scale-fill",
help = "don't scale-fill the album art to the window" help = "don't scale-fill the album art to the window"
@ -59,9 +63,26 @@ pub struct Opt {
} }
fn main() -> Result<(), String> { fn main() -> Result<(), String> {
let opt = Opt::from_args(); let mut opt = Opt::from_args();
println!("Got host addr == {}, port == {}", opt.host, opt.port); println!("Got host addr == {}, port == {}", opt.host, opt.port);
// Read password from file if exists, error otherwise.
if let Some(psswd_file_path) = opt.password_file.as_ref() {
let mut file = File::open(psswd_file_path).expect("pfile/password_file should exist");
let mut content: String = String::new();
file.read_to_string(&mut content)
.expect("Should be able to read from pfile/password_file");
if content.ends_with("\r\n") {
content.truncate(content.len() - 2);
} else if content.ends_with('\n') {
content.truncate(content.len() - 1);
}
opt.password = Some(content);
}
let (mut ctx, event_loop) = ContextBuilder::new("mpd_info_screen", "Stephen Seo") let (mut ctx, event_loop) = ContextBuilder::new("mpd_info_screen", "Stephen Seo")
.window_setup(WindowSetup { .window_setup(WindowSetup {
title: "mpd info screen".into(), title: "mpd info screen".into(),

View file

@ -263,10 +263,10 @@ impl MPDHandler {
current_binary_size: 0, current_binary_size: 0,
poll_state: PollState::None, poll_state: PollState::None,
stream, stream,
password, password: password.clone(),
error_text: String::new(), error_text: String::new(),
can_authenticate: true, can_authenticate: true,
is_authenticated: false, is_authenticated: password.is_empty(),
can_get_album_art: true, can_get_album_art: true,
can_get_album_art_in_dir: true, can_get_album_art_in_dir: true,
can_get_status: true, can_get_status: true,