Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/process_data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub enum Containerization {
None,
Flatpak,
Snap,
AppImage,
}

/// Data that could be transferred us>ing `resources-processes`, separated from
Expand All @@ -187,6 +188,7 @@ pub struct ProcessData {
pub write_bytes: Option<u64>,
pub timestamp: u64,
pub gpu_usage_stats: BTreeMap<GpuIdentifier, GpuUsageStats>,
pub appimage_path: Option<String>,
}

impl ProcessData {
Expand Down Expand Up @@ -368,10 +370,20 @@ impl ProcessData {
.ok()
.and_then(Self::sanitize_cgroup);

let environ = std::fs::read_to_string(proc_path.join("environ"))?
.split('\0')
.filter_map(|e| e.split_once('='))
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>();

let appimage_path = environ.get("APPIMAGE").map(|p| p.to_owned());

let containerization = if commandline.starts_with("/snap/") {
Containerization::Snap
} else if proc_path.join("root").join(".flatpak-info").exists() {
Containerization::Flatpak
} else if appimage_path.is_some() {
Containerization::AppImage
} else {
Containerization::None
};
Expand Down Expand Up @@ -417,6 +429,7 @@ impl ProcessData {
write_bytes,
timestamp,
gpu_usage_stats,
appimage_path,
})
}

Expand Down
1 change: 1 addition & 0 deletions src/ui/pages/applications/application_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ impl ApplicationEntry {
Containerization::None => i18n("No"),
Containerization::Flatpak => i18n("Yes (Flatpak)"),
Containerization::Snap => i18n("Yes (Snap)"),
Containerization::AppImage => i18n("Yes (AppImage)"),
};

let this: Self = glib::Object::builder()
Expand Down
1 change: 1 addition & 0 deletions src/ui/pages/processes/process_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ impl ProcessEntry {
Containerization::None => i18n("No"),
Containerization::Flatpak => i18n("Yes (Flatpak)"),
Containerization::Snap => i18n("Yes (Snap)"),
Containerization::AppImage => i18n("Yes (AppImage)"),
};

let this: Self = glib::Object::builder()
Expand Down
27 changes: 26 additions & 1 deletion src/utils/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ impl App {
let id = desktop_entry
.get("X-Flatpak") // is there a X-Flatpak section?
.or_else(|| desktop_entry.get("X-SnapInstanceName")) // if not, maybe there is a X-SnapInstanceName
.or_else(|| desktop_entry.get("X-AppImage-Identifier")) // or maybe a X-AppImageIdentifier
.map(str::to_string)
.or_else(|| {
// if not, presume that the ID is in the file name
Expand All @@ -256,7 +257,9 @@ impl App {
bail!("{id} is blocklisted (reason: {reason})")
}

let exec = desktop_entry.get("Exec");
let exec = desktop_entry
.get("X-ExecLocation") // appimaged adds this entry that points to the original AppImage path
.or(desktop_entry.get("Exec"));
let is_flatpak = exec.is_some_and(|exec| exec.starts_with("/usr/bin/flatpak run"));
let commandline = exec
.and_then(|exec| {
Expand Down Expand Up @@ -327,6 +330,7 @@ impl App {
.map(str::to_string);

let is_snap = desktop_entry.get("X-SnapInstanceName").is_some();
let is_appimage = desktop_entry.get("X-AppImage-Identifier").is_some();

let containerization = if is_flatpak {
debug!(
Expand All @@ -344,6 +348,14 @@ impl App {
executable_name.as_ref().unwrap_or(&"<None>".into()),
);
Containerization::Snap
} else if is_appimage {
debug!(
"Found AppImage app \"{display_name}\" (ID: {id:?}) at {} with commandline `{}` (detected executable name: {})",
file_path.to_string_lossy(),
commandline.as_ref().unwrap_or(&"<None>".into()),
executable_name.as_ref().unwrap_or(&"<None>".into()),
);
Containerization::AppImage
} else {
debug!(
"Found native app \"{display_name}\" (ID: {id:?}) at {} with commandline `{}` (detected executable name: {})",
Expand Down Expand Up @@ -628,6 +640,19 @@ impl AppsContext {

fn app_associated_with_process(&self, process: &Process) -> Option<String> {
// TODO: tidy this up
// ↓ look for whether we can associate this process with an AppImage
if let Some(appimage_path) = &process.data.appimage_path {
if let Some(parent) = self.apps.values().find(|app| {
app.containerization == Containerization::AppImage
&& app
.commandline
.as_ref()
.is_some_and(|exe_name| exe_name == appimage_path)
}) {
return parent.id.clone();
}
}

// ↓ look for whether we can find an ID in the cgroup
if DESKTOP_ENVIRONMENT_CGROUPS.contains(&process.data.cgroup.as_deref().unwrap_or_default())
{
Expand Down