feat(plugin-pop-shell): Get window icon from desktop entry

This commit is contained in:
Michael Aaron Murphy 2021-11-18 15:09:14 +01:00 • committed by Jeremy Soller
parent 170c6bbfb2
commit d62225baf3

View file

@ -2,10 +2,11 @@
// Copyright © 2021 System76 // Copyright © 2021 System76
use crate::*; use crate::*;
use freedesktop_desktop_entry as fde;
use futures_lite::{AsyncWrite, AsyncWriteExt, StreamExt}; use futures_lite::{AsyncWrite, AsyncWriteExt, StreamExt};
use pop_launcher::*; use pop_launcher::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::convert::TryFrom; use std::{convert::TryFrom, fs, path::PathBuf};
use zbus::Connection; use zbus::Connection;
use zvariant::{Signature, Type}; use zvariant::{Signature, Type};
@ -17,11 +18,12 @@ struct Item {
entity: (u32, u32), entity: (u32, u32),
name: String, name: String,
description: String, description: String,
desktop_entry: String,
} }
impl Type for Item { impl Type for Item {
fn signature() -> Signature<'static> { fn signature() -> Signature<'static> {
Signature::try_from("((uu)ss)").expect("bad dbus signature") Signature::try_from("((uu)sss)").expect("bad dbus signature")
} }
} }
@ -56,6 +58,7 @@ pub async fn main() {
} }
struct App<W> { struct App<W> {
desktop_entries: Vec<(fde::PathSource, PathBuf)>,
entries: Vec<Item>, entries: Vec<Item>,
connection: Connection, connection: Connection,
tx: W, tx: W,
@ -64,6 +67,7 @@ struct App<W> {
impl<W: AsyncWrite + Unpin> App<W> { impl<W: AsyncWrite + Unpin> App<W> {
fn new(connection: Connection, tx: W) -> Self { fn new(connection: Connection, tx: W) -> Self {
Self { Self {
desktop_entries: fde::Iter::new(fde::default_paths()).collect(),
entries: Vec::new(), entries: Vec::new(),
connection, connection,
tx, tx,
@ -111,13 +115,33 @@ impl<W: AsyncWrite + Unpin> App<W> {
continue; continue;
} }
let mut icon_name = Cow::Borrowed("application-x-executable");
if let Some(desktop_entry) = item.desktop_entry.strip_suffix(".desktop") {
for (_, path) in &self.desktop_entries {
if let Some(name) = path.file_stem() {
if desktop_entry == name {
if let Ok(data) = fs::read_to_string(path) {
if let Ok(entry) = fde::DesktopEntry::decode(path, &data) {
if let Some(icon) = entry.icon() {
icon_name = Cow::Owned(icon.to_owned());
}
}
}
break;
}
}
}
}
send( send(
&mut self.tx, &mut self.tx,
PluginResponse::Append(PluginSearchResult { PluginResponse::Append(PluginSearchResult {
id: id as u32, id: id as u32,
name: item.name.clone(), name: item.name.clone(),
description: item.description.clone(), description: item.description.clone(),
icon: Some(IconSource::Window(item.entity)), icon: Some(IconSource::Name(icon_name)),
window: Some(item.entity), window: Some(item.entity),
..Default::default() ..Default::default()
}), }),