mirror of
https://github.com/Noratrieb/colouncher.git
synced 2026-03-14 13:16:10 +01:00
cleanup
This commit is contained in:
parent
bee16cced1
commit
eaaa474eb5
2 changed files with 49 additions and 13 deletions
|
|
@ -1,8 +1,36 @@
|
|||
use eyre::{Context, Result};
|
||||
use freedesktop_file_parser::{DesktopFile, EntryType};
|
||||
use palette::{IntoColor, Oklab, Oklaba};
|
||||
use palette::{IntoColor, Oklab, Oklaba, color_difference::EuclideanDistance};
|
||||
use std::{collections::HashMap, ffi::OsStr, fs::DirEntry, path::Path};
|
||||
|
||||
pub struct DesktopEntries {
|
||||
entries: Vec<DesktopEntry>,
|
||||
}
|
||||
|
||||
pub struct DesktopEntry {
|
||||
pub _id: String,
|
||||
pub file: DesktopFile,
|
||||
pub avg_icon_color: Oklab,
|
||||
}
|
||||
|
||||
impl DesktopEntries {
|
||||
pub fn count(&self) -> usize {
|
||||
self.entries.len()
|
||||
}
|
||||
pub fn find_entry(&self, color: Oklab) -> Option<&DesktopEntry> {
|
||||
self.entries.iter().min_by(|x, y| {
|
||||
f32::total_cmp(
|
||||
&diff_color(x.avg_icon_color, color),
|
||||
&diff_color(y.avg_icon_color, color),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn diff_color(icon: Oklab, color: Oklab) -> f32 {
|
||||
icon.distance_squared(color)
|
||||
}
|
||||
|
||||
fn walkdir(path: &Path, f: &mut impl FnMut(&DirEntry) -> Result<()>) -> Result<()> {
|
||||
for entry in path.read_dir()? {
|
||||
let entry = entry?;
|
||||
|
|
@ -14,7 +42,7 @@ fn walkdir(path: &Path, f: &mut impl FnMut(&DirEntry) -> Result<()>) -> Result<(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn find_desktop_files() -> Result<Vec<(DesktopFile, Oklab)>> {
|
||||
pub(crate) fn find_desktop_files() -> Result<DesktopEntries> {
|
||||
// https://specifications.freedesktop.org/desktop-entry/latest/file-naming.html
|
||||
let paths = std::env::var("XDG_DATA_DIRS").unwrap_or("/usr/local/share/:/usr/share/".into());
|
||||
let paths = std::env::split_paths(&paths);
|
||||
|
|
@ -55,7 +83,14 @@ pub(crate) fn find_desktop_files() -> Result<Vec<(DesktopFile, Oklab)>> {
|
|||
.decode()
|
||||
.wrap_err_with(|| format!("decoding {}", icon.display()))?;
|
||||
let color = average_color(&icon);
|
||||
results.insert(id, (file, color));
|
||||
results.insert(
|
||||
id.clone(),
|
||||
DesktopEntry {
|
||||
_id: id,
|
||||
file,
|
||||
avg_icon_color: color,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -63,7 +98,9 @@ pub(crate) fn find_desktop_files() -> Result<Vec<(DesktopFile, Oklab)>> {
|
|||
.wrap_err_with(|| format!("{}", base.display()))?;
|
||||
}
|
||||
|
||||
Ok(results.into_values().collect())
|
||||
Ok(DesktopEntries {
|
||||
entries: results.into_values().collect(),
|
||||
})
|
||||
}
|
||||
|
||||
fn average_color(image: &image::DynamicImage) -> palette::Oklab {
|
||||
|
|
|
|||
17
src/main.rs
17
src/main.rs
|
|
@ -6,9 +6,9 @@ use std::{
|
|||
};
|
||||
|
||||
use eyre::{Context, Result, bail};
|
||||
use freedesktop_file_parser::{DesktopFile, EntryType};
|
||||
use freedesktop_file_parser::EntryType;
|
||||
use log::{error, info, warn};
|
||||
use palette::{FromColor, IntoColor, Oklab, color_difference::EuclideanDistance};
|
||||
use palette::{FromColor, IntoColor, Oklab};
|
||||
use smithay_client_toolkit::{
|
||||
compositor::{CompositorHandler, CompositorState},
|
||||
output::{OutputHandler, OutputState},
|
||||
|
|
@ -33,6 +33,8 @@ use wayland_client::{
|
|||
protocol::{wl_buffer, wl_output::WlOutput, wl_pointer::WlPointer, wl_seat::WlSeat, wl_shm},
|
||||
};
|
||||
|
||||
use crate::desktop::DesktopEntries;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::builder()
|
||||
.filter(None, log::LevelFilter::Info)
|
||||
|
|
@ -42,7 +44,7 @@ fn main() -> Result<()> {
|
|||
let desktop_files = desktop::find_desktop_files().wrap_err("loading .desktop files")?;
|
||||
info!(
|
||||
"Loaded {} desktop icons in {:?}",
|
||||
desktop_files.len(),
|
||||
desktop_files.count(),
|
||||
now.elapsed()
|
||||
);
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ struct App {
|
|||
shm: Shm,
|
||||
seat_state: SeatState,
|
||||
|
||||
desktop_files: Vec<(DesktopFile, Oklab)>,
|
||||
desktop_files: DesktopEntries,
|
||||
pointers: HashMap<WlSeat, WlPointer>,
|
||||
layer_surfaces: Vec<OutputSurface>,
|
||||
}
|
||||
|
|
@ -400,13 +402,10 @@ impl PointerHandler for App {
|
|||
|
||||
let oklab: Oklab = srgb.into_format::<f32>().into_color();
|
||||
|
||||
let best_match = self
|
||||
.desktop_files
|
||||
.iter()
|
||||
.min_by_key(|(_, icon_color)| (oklab.distance(*icon_color) * 1000000.0) as u32);
|
||||
let best_match = self.desktop_files.find_entry(oklab);
|
||||
|
||||
if let Some(best_match) = best_match
|
||||
&& let EntryType::Application(app) = &best_match.0.entry.entry_type
|
||||
&& let EntryType::Application(app) = &best_match.file.entry.entry_type
|
||||
&& let Some(exec) = &app.exec
|
||||
{
|
||||
// lol terrible implementation that works well enough
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue