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

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;
}
}
}