Skip to content

Commit c776160

Browse files
committed
battery: Align primary gpu detection with cosmic-comp
1 parent fec1ab4 commit c776160

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

cosmic-applet-battery/src/dgpu.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ use cosmic::{
1515
iced::{self, Subscription},
1616
iced_futures::stream,
1717
};
18-
use drm::control::Device as ControlDevice;
18+
use drm::control::{
19+
Device as ControlDevice,
20+
connector::{Info as ConnectorInfo, Interface},
21+
};
1922
use futures::{FutureExt, SinkExt};
2023
use tokio::{
2124
io::unix::AsyncFd,
@@ -57,6 +60,7 @@ impl Debug for GpuMonitor {
5760
struct Gpu {
5861
path: PathBuf,
5962
name: String,
63+
boot_vga: bool,
6064
primary: bool,
6165
enabled: bool,
6266
driver: Option<OsString>,
@@ -147,26 +151,32 @@ pub struct RunningApp {
147151
executable_name: String,
148152
}
149153

154+
fn connectors(path: &impl AsRef<Path>) -> Option<impl Iterator<Item = ConnectorInfo>> {
155+
struct Device(std::fs::File);
156+
impl AsFd for Device {
157+
fn as_fd(&self) -> std::os::unix::prelude::BorrowedFd<'_> {
158+
self.0.as_fd()
159+
}
160+
}
161+
impl drm::Device for Device {}
162+
impl ControlDevice for Device {}
163+
164+
let device = Device(std::fs::File::open(path).ok()?);
165+
let resources = device.resource_handles().ok()?;
166+
167+
Some(
168+
resources
169+
.connectors
170+
.into_iter()
171+
.filter_map(move |conn| device.get_connector(conn, false).ok()),
172+
)
173+
}
174+
150175
impl Gpu {
151176
async fn connected_outputs(&self) -> Option<Vec<Entry>> {
152177
let path = self.path.clone();
153178
spawn_blocking(move || {
154-
struct Device(std::fs::File);
155-
impl AsFd for Device {
156-
fn as_fd(&self) -> std::os::unix::prelude::BorrowedFd<'_> {
157-
self.0.as_fd()
158-
}
159-
}
160-
impl drm::Device for Device {}
161-
impl ControlDevice for Device {}
162-
163-
let device = Device(std::fs::File::open(path).ok()?);
164-
let resources = device.resource_handles().ok()?;
165-
166-
let outputs = resources
167-
.connectors
168-
.into_iter()
169-
.filter_map(|conn| device.get_connector(conn, false).ok())
179+
let outputs = connectors(&path)?
170180
.filter(|info| info.state() == drm::control::connector::State::Connected)
171181
.map(|info| Entry {
172182
name: format!(
@@ -178,6 +188,7 @@ impl Gpu {
178188
secondary: String::new(),
179189
})
180190
.collect();
191+
181192
// TODO read and parse edid with libdisplay-info and display output manufacture/model
182193

183194
Some(outputs)
@@ -309,7 +320,7 @@ fn all_gpus<S: AsRef<str>>(seat: S) -> io::Result<Vec<Gpu>> {
309320
let mut enumerator = udev::Enumerator::new()?;
310321
enumerator.match_subsystem("drm")?;
311322
enumerator.match_sysname("card[0-9]*")?;
312-
Ok(enumerator
323+
let mut gpus = enumerator
313324
.scan_devices()?
314325
.filter(|device| {
315326
device
@@ -370,13 +381,34 @@ fn all_gpus<S: AsRef<str>>(seat: S) -> io::Result<Vec<Gpu>> {
370381
Some(Gpu {
371382
path,
372383
name,
373-
primary: boot_vga,
384+
boot_vga,
385+
primary: false,
374386
enabled: false,
375387
driver,
376388
interval,
377389
})
378390
})
379-
.collect())
391+
.collect::<Vec<_>>();
392+
393+
if let Some(primary_idx) = gpus
394+
.iter()
395+
.position(|gpu| {
396+
connectors(&gpu.path).is_some_and(|mut conns| {
397+
conns.any(|info| {
398+
let i = info.interface();
399+
i == Interface::EmbeddedDisplayPort
400+
|| i == Interface::LVDS
401+
|| i == Interface::DSI
402+
})
403+
})
404+
})
405+
.or_else(|| gpus.iter().position(|gpu| gpu.boot_vga))
406+
.or_else(|| (gpus.len() == 1).then_some(0))
407+
{
408+
gpus[primary_idx].primary = true;
409+
}
410+
411+
Ok(gpus)
380412
}
381413

382414
pub fn dgpu_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
@@ -481,6 +513,7 @@ async fn start_listening(
481513
monitor.gpus.push(Gpu {
482514
path: path.to_path_buf(),
483515
name,
516+
boot_vga: false,
484517
primary: false,
485518
enabled: false,
486519
driver,

0 commit comments

Comments
 (0)