add active list to dock object

This commit is contained in:
Ashley Wulber 2021-12-20 23:52:59 -05:00
parent 5cda4046a6
commit 6a479899ad
20 changed files with 250 additions and 601 deletions

View file

@ -0,0 +1,79 @@
use crate::utils::BoxedSearchResults;
use gio::DesktopAppInfo;
use glib::{FromVariant, ParamFlags, ParamSpec, ToVariant, Value, Variant, VariantTy};
use gtk4::glib;
use gtk4::prelude::*;
use gtk4::subclass::prelude::*;
use once_cell::sync::Lazy;
use std::cell::RefCell;
// Object holding the state
#[derive(Default)]
pub struct DockObject {
appinfo: RefCell<Option<DesktopAppInfo>>,
active: RefCell<BoxedSearchResults>,
}
// The central trait for subclassing a GObject
#[glib::object_subclass]
impl ObjectSubclass for DockObject {
const NAME: &'static str = "DockObject";
type Type = super::DockObject;
type ParentType = glib::Object;
}
// Trait shared by all GObjects
impl ObjectImpl for DockObject {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![
ParamSpec::new_object(
// Name
"appinfo",
// Nickname
"appinfo",
// Short description
"app info",
DesktopAppInfo::static_type(),
// The property can be read and written to
ParamFlags::READWRITE,
),
ParamSpec::new_boxed(
// Name
"active",
// Nickname
"active",
// Short description
"active",
BoxedSearchResults::static_type(),
// The property can be read and written to
ParamFlags::READWRITE,
),
]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"appinfo" => {
let appinfo = value
.get()
.expect("Value needs to be Option<DesktopAppInfo>");
self.appinfo.replace(appinfo);
}
"active" => {
let active = value.get().expect("Value needs to be BoxedSearchResults");
self.active.replace(active);
}
_ => unimplemented!(),
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"appinfo" => self.appinfo.borrow().to_value(),
_ => unimplemented!(),
}
}
}

View file

@ -0,0 +1,51 @@
mod imp;
use crate::utils::BoxedSearchResults;
use gdk4::glib::Object;
use gio::DesktopAppInfo;
use gtk4::glib;
use gtk4::prelude::AppInfoExt;
glib::wrapper! {
pub struct DockObject(ObjectSubclass<imp::DockObject>);
}
impl DockObject {
pub fn new(appinfo: DesktopAppInfo) -> Self {
Object::new(&[("appinfo", &Some(appinfo))]).expect("Failed to create `DockObject`.")
}
pub fn from_search_results(results: BoxedSearchResults) -> Self {
let appinfo = xdg::BaseDirectories::new()
.expect("could not access XDG Base directory")
.get_data_dirs()
.iter_mut()
.filter_map(|xdg_data_path| {
let defaults = ["Firefox Web Browser", "Files", "Terminal", "Pop!_Shop"];
xdg_data_path.push("applications");
dbg!(&xdg_data_path);
std::fs::read_dir(xdg_data_path).ok()
})
.flatten()
.filter_map(|dir_entry| {
let defaults = ["Firefox Web Browser", "Files", "Terminal", "Pop!_Shop"];
if let Ok(dir_entry) = dir_entry {
if let Some(path) = dir_entry.path().file_name() {
if let Some(path) = path.to_str() {
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
if app_info.should_show()
&& defaults.contains(&app_info.name().as_str())
{
return Some(DockObject::new(app_info));
}
}
}
}
}
None
})
.next();
Object::new(&[("appinfo", &appinfo), ("active", &results)])
.expect("Failed to create `DockObject`.")
}
}