Add mounter abstraction, enable minimal GVfs support
This commit is contained in:
parent
8913c4198b
commit
02b6cda872
8 changed files with 254 additions and 19 deletions
124
Cargo.lock
generated
124
Cargo.lock
generated
|
|
@ -510,8 +510,8 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
|
@ -1099,6 +1099,7 @@ dependencies = [
|
|||
"fork",
|
||||
"freedesktop_entry_parser",
|
||||
"fs_extra",
|
||||
"gio",
|
||||
"i18n-embed",
|
||||
"i18n-embed-fl",
|
||||
"image",
|
||||
|
|
@ -2092,9 +2093,9 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
|
||||
dependencies = [
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gio-sys 0.18.1",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
|
@ -2107,9 +2108,9 @@ checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2"
|
|||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gio-sys 0.18.1",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"pkg-config",
|
||||
|
|
@ -2193,19 +2194,50 @@ version = "0.28.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f91a0518c2ec539f099d3f945ab2d6a83ec372a9ef40a21906343b191182845"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"gio-sys 0.19.0",
|
||||
"glib",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf8e1d9219bb294636753d307b030c1e8a032062cba74f493c431a5c8b81ce4"
|
||||
dependencies = [
|
||||
"glib-sys 0.19.0",
|
||||
"gobject-sys 0.19.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gl_generator"
|
||||
version = "0.14.0"
|
||||
|
|
@ -2223,6 +2255,41 @@ version = "0.24.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1407b2ce171e654720be10d57d4054d3ff2f10a13d5b37e6819b41439832f7"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"gio-sys 0.19.0",
|
||||
"glib-macros",
|
||||
"glib-sys 0.19.0",
|
||||
"gobject-sys 0.19.0",
|
||||
"libc",
|
||||
"memchr",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8bba315e8ce8aa59631545358450f4962557e89b5f7db7442e7153b47037f71"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro-crate 3.1.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.18.1"
|
||||
|
|
@ -2233,6 +2300,16 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630f097773d7c7a0bb3258df4e8157b47dc98bbfa0e60ad9ab56174813feced4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
|
|
@ -2277,7 +2354,18 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"glib-sys 0.18.1",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c85e2b1080b9418dd0c58b498da3a5c826030343e0ef07bde6a955d28de54979"
|
||||
dependencies = [
|
||||
"glib-sys 0.19.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
|
@ -2350,9 +2438,9 @@ dependencies = [
|
|||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gdk-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gio-sys 0.18.1",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
|
|
@ -3789,8 +3877,8 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
|
@ -4286,8 +4374,8 @@ dependencies = [
|
|||
"ashpd 0.6.8",
|
||||
"block",
|
||||
"dispatch",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"glib-sys 0.18.1",
|
||||
"gobject-sys 0.18.0",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"log",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ dirs = "5.0.1"
|
|||
env_logger = "0.11"
|
||||
freedesktop_entry_parser = { version = "1.3", optional = true }
|
||||
fs_extra = "1.3"
|
||||
gio = { version = "0.19", optional = true }
|
||||
image = "0.24"
|
||||
once_cell = "1.19"
|
||||
open = "5.0.2"
|
||||
|
|
@ -49,8 +50,9 @@ version = "0.2.1"
|
|||
features = ["serde"]
|
||||
|
||||
[features]
|
||||
default = ["desktop", "wgpu"]
|
||||
default = ["desktop", "gvfs", "wgpu"]
|
||||
desktop = ["libcosmic/desktop", "dep:freedesktop_entry_parser", "dep:xdg"]
|
||||
gvfs = ["dep:gio"]
|
||||
wgpu = ["libcosmic/wgpu"]
|
||||
|
||||
[profile.dev]
|
||||
|
|
|
|||
1
debian/control
vendored
1
debian/control
vendored
|
|
@ -6,6 +6,7 @@ Build-Depends:
|
|||
debhelper-compat (=13),
|
||||
git,
|
||||
just (>= 1.13.0),
|
||||
libglib2.0-dev,
|
||||
pkg-config,
|
||||
rust-all,
|
||||
Standards-Version: 4.6.2
|
||||
|
|
|
|||
25
examples/gvfs.rs
Normal file
25
examples/gvfs.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use gio::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let monitor = gio::VolumeMonitor::get();
|
||||
for drive in monitor.connected_drives() {
|
||||
println!("Drive: {}", drive.name());
|
||||
for volume in drive.volumes() {
|
||||
println!(" Volume: {}", volume.name());
|
||||
if let Some(mount) = volume.get_mount() {
|
||||
println!(" Mount: {}", mount.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for mount in monitor.mounts() {
|
||||
println!("Mount: {}", mount.name());
|
||||
}
|
||||
|
||||
for volume in monitor.volumes() {
|
||||
println!("Volume: {}", volume.name());
|
||||
if let Some(mount) = volume.get_mount() {
|
||||
println!(" Mount: {}", mount.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/app.rs
31
src/app.rs
|
|
@ -48,6 +48,7 @@ use crate::{
|
|||
fl, home_dir,
|
||||
key_bind::key_binds,
|
||||
menu, mime_app,
|
||||
mounter::{mounters, Mounters},
|
||||
operation::Operation,
|
||||
spawn_detached::spawn_detached,
|
||||
tab::{self, HeadingOptions, ItemMetadata, Location, Tab},
|
||||
|
|
@ -268,6 +269,7 @@ pub struct App {
|
|||
dialog_text_input: widget::Id,
|
||||
key_binds: HashMap<KeyBind, Action>,
|
||||
modifiers: Modifiers,
|
||||
mounters: Mounters,
|
||||
pending_operation_id: u64,
|
||||
pending_operations: BTreeMap<u64, (Operation, f32)>,
|
||||
complete_operations: BTreeMap<u64, Operation>,
|
||||
|
|
@ -727,6 +729,34 @@ impl Application for App {
|
|||
.data(Location::Trash)
|
||||
});
|
||||
|
||||
//TODO: dynamic mount list
|
||||
let mounters = mounters();
|
||||
for (mounter_name, mounter) in mounters.iter() {
|
||||
println!("Mounter {}", mounter_name);
|
||||
match mounter.items() {
|
||||
Ok(items) => {
|
||||
for item in items {
|
||||
let name = item.name();
|
||||
println!(" - {}", name);
|
||||
let icon = item.icon(16);
|
||||
let dir_opt = item.path();
|
||||
nav_model = nav_model.insert(move |mut b| {
|
||||
b = b
|
||||
.text(name.clone())
|
||||
.icon(widget::icon::icon(icon.clone()).size(16));
|
||||
match &dir_opt {
|
||||
Some(dir) => b.data(Location::Path(dir.clone())),
|
||||
None => b,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("failed to get items: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut app = App {
|
||||
core,
|
||||
nav_model: nav_model.build(),
|
||||
|
|
@ -741,6 +771,7 @@ impl Application for App {
|
|||
dialog_text_input: widget::Id::unique(),
|
||||
key_binds: key_binds(),
|
||||
modifiers: Modifiers::empty(),
|
||||
mounters,
|
||||
pending_operation_id: 0,
|
||||
pending_operations: BTreeMap::new(),
|
||||
complete_operations: BTreeMap::new(),
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ mod localize;
|
|||
mod menu;
|
||||
mod mime_app;
|
||||
pub mod mime_icon;
|
||||
mod mounter;
|
||||
mod mouse_area;
|
||||
mod operation;
|
||||
mod spawn_detached;
|
||||
|
|
|
|||
54
src/mounter/gvfs.rs
Normal file
54
src/mounter/gvfs.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use cosmic::widget;
|
||||
use gio::prelude::*;
|
||||
use gio::{Mount, ThemedIcon, Volume, VolumeMonitor};
|
||||
use std::{error::Error, path::PathBuf};
|
||||
|
||||
use super::{Mounter, MounterItem, MounterItems};
|
||||
|
||||
pub struct Gvfs {
|
||||
monitor: VolumeMonitor,
|
||||
}
|
||||
|
||||
impl Gvfs {
|
||||
pub fn new() -> Self {
|
||||
let monitor = VolumeMonitor::get();
|
||||
Self { monitor }
|
||||
}
|
||||
}
|
||||
|
||||
impl Mounter for Gvfs {
|
||||
fn items(&self) -> Result<MounterItems, Box<dyn Error>> {
|
||||
let mut items = MounterItems::new();
|
||||
for mount in self.monitor.mounts() {
|
||||
items.push(Box::new(mount));
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
}
|
||||
|
||||
impl MounterItem for Mount {
|
||||
fn name(&self) -> String {
|
||||
MountExt::name(self).to_string()
|
||||
}
|
||||
|
||||
fn icon(&self, size: u16) -> widget::icon::Handle {
|
||||
let icon = MountExt::symbolic_icon(self);
|
||||
if let Some(themed_icon) = icon.downcast_ref::<ThemedIcon>() {
|
||||
for name in themed_icon.names() {
|
||||
let named = widget::icon::from_name(name.as_str()).size(size);
|
||||
if let Some(path) = named.path() {
|
||||
return widget::icon::from_path(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: handle more gio icon types
|
||||
widget::icon::from_name("folder-symbolic")
|
||||
.size(size)
|
||||
.handle()
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<PathBuf> {
|
||||
MountExt::root(self).path()
|
||||
}
|
||||
}
|
||||
33
src/mounter/mod.rs
Normal file
33
src/mounter/mod.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use cosmic::widget;
|
||||
use std::error::Error;
|
||||
use std::{collections::BTreeMap, path::PathBuf, sync::Arc};
|
||||
|
||||
#[cfg(feature = "gvfs")]
|
||||
mod gvfs;
|
||||
|
||||
pub trait MounterItem {
|
||||
fn name(&self) -> String;
|
||||
fn icon(&self, size: u16) -> widget::icon::Handle;
|
||||
fn path(&self) -> Option<PathBuf>;
|
||||
}
|
||||
|
||||
pub type MounterItems = Vec<Box<dyn MounterItem>>;
|
||||
|
||||
pub trait Mounter {
|
||||
fn items(&self) -> Result<MounterItems, Box<dyn Error>>;
|
||||
}
|
||||
|
||||
pub type MounterKey = &'static str;
|
||||
pub type MounterMap = BTreeMap<MounterKey, Box<dyn Mounter>>;
|
||||
pub type Mounters = Arc<MounterMap>;
|
||||
|
||||
pub fn mounters() -> Mounters {
|
||||
let mut mounters = MounterMap::new();
|
||||
|
||||
#[cfg(feature = "gvfs")]
|
||||
{
|
||||
mounters.insert("gvfs", Box::new(gvfs::Gvfs::new()));
|
||||
}
|
||||
|
||||
Mounters::new(mounters)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue