fix: Show context for graphics only if switchable graphics found

This commit is contained in:
Michael Aaron Murphy 2022-03-04 12:00:54 +01:00 committed by Michael Murphy
parent 21f699e483
commit eb6028f8fc
4 changed files with 81 additions and 16 deletions

17
Cargo.lock generated
View file

@ -1184,6 +1184,12 @@ dependencies = [
"libc",
]
[[package]]
name = "numtoa"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f"
[[package]]
name = "objc"
version = "0.2.7"
@ -1398,6 +1404,7 @@ dependencies = [
name = "pop-launcher-plugins"
version = "1.1.0"
dependencies = [
"anyhow",
"async-pidfd",
"fork",
"freedesktop-desktop-entry",
@ -1416,6 +1423,7 @@ dependencies = [
"slab",
"smol",
"strsim",
"sysfs-class",
"tracing",
"tracing-subscriber",
"url",
@ -1846,6 +1854,15 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "sysfs-class"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1bbcf869732c45a77898f7f61ed6d411dfc37613517e444842f58d428856d1"
dependencies = [
"numtoa",
]
[[package]]
name = "system-deps"
version = "6.0.2"

View file

@ -32,3 +32,5 @@ zvariant = "3.1.2"
ward = "2.1.0"
isahc = "1.6.0"
url = "2.2.2"
sysfs-class = "0.1.3"
anyhow = "1.0.55"

View file

@ -0,0 +1,43 @@
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use anyhow::Context;
use sysfs_class::{PciDevice, SysClass};
/// Checks if the system has switchable graphics.
///
/// A system is considered switchable if multiple graphics card devices are found.
pub fn is_switchable() -> bool {
let main = || -> anyhow::Result<bool> {
let devices = PciDevice::all().context("cannot get PCI devices")?;
let mut amd_graphics = 0;
let mut intel_graphics = 0;
let mut nvidia_graphics = 0;
for dev in devices {
let c = dev.class().context("cannot get class of device")?;
if let 0x03 = (c >> 16) & 0xFF {
match dev.vendor().context("cannot get vendor of device")? {
0x1002 => amd_graphics += 1,
0x10DE => nvidia_graphics += 1,
0x8086 => intel_graphics += 1,
_ => (),
}
}
}
let switchable = (nvidia_graphics > 0 && (intel_graphics > 0 || amd_graphics > 0))
|| (intel_graphics > 0 && amd_graphics > 0);
Ok(switchable)
};
match main() {
Ok(value) => value,
Err(why) => {
tracing::error!("{}", why);
false
}
}
}

View file

@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
// Copyright © 2021 System76
mod graphics;
use crate::*;
use freedesktop_desktop_entry::{default_paths, DesktopEntry, Iter as DesktopIter, PathSource};
use futures_lite::{AsyncWrite, StreamExt};
@ -20,7 +22,6 @@ struct Item {
path: PathBuf,
prefers_non_default_gpu: bool,
src: PathSource,
terminal_command: bool,
}
impl Hash for Item {
@ -162,7 +163,6 @@ impl<W: AsyncWrite + Unpin> App<W> {
icon: entry.icon().map(|x| x.to_owned()),
exec: exec.to_owned(),
path: path.clone(),
terminal_command: entry.terminal(),
prefers_non_default_gpu: entry.prefers_non_default_gpu(),
src,
};
@ -212,22 +212,25 @@ impl<W: AsyncWrite + Unpin> App<W> {
async fn context(&mut self, id: u32) {
if let Some(entry) = self.entries.get(id as usize) {
let option = ContextOption {
id: 0,
name: (if entry.prefers_non_default_gpu {
"Launch Using Integrated Graphics Card"
} else {
"Launch Using Discrete Graphics Card"
})
.to_owned(),
};
let mut options = Vec::new();
let response = PluginResponse::Context {
id,
options: vec![option],
};
if graphics::is_switchable() {
options.push(ContextOption {
id: 0,
name: (if entry.prefers_non_default_gpu {
"Launch Using Integrated Graphics Card"
} else {
"Launch Using Discrete Graphics Card"
})
.to_owned(),
});
}
send(&mut self.tx, response).await;
if !options.is_empty() {
let response = PluginResponse::Context { id, options };
send(&mut self.tx, response).await;
}
}
}