aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tty.rs')
-rw-r--r--src/backend/tty.rs36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs
index 54fc97c1..cb04c717 100644
--- a/src/backend/tty.rs
+++ b/src/backend/tty.rs
@@ -57,6 +57,7 @@ use wayland_protocols::wp::linux_dmabuf::zv1::server::zwp_linux_dmabuf_feedback_
use wayland_protocols::wp::presentation_time::server::wp_presentation_feedback;
use super::{IpcOutputMap, RenderResult};
+use crate::backend::OutputId;
use crate::frame_clock::FrameClock;
use crate::niri::{Niri, RedrawState, State};
use crate::render_helpers::debug::draw_damage;
@@ -118,6 +119,7 @@ pub struct OutputDevice {
render_node: DrmNode,
drm_scanner: DrmScanner,
surfaces: HashMap<crtc::Handle, Surface>,
+ output_ids: HashMap<crtc::Handle, OutputId>,
// SAFETY: drop after all the objects used with them are dropped.
// See https://github.com/Smithay/smithay/issues/1102.
drm: DrmDevice,
@@ -575,6 +577,7 @@ impl Tty {
gbm,
drm_scanner: DrmScanner::new(),
surfaces: HashMap::new(),
+ output_ids: HashMap::new(),
drm_lease_state,
active_leases: Vec::new(),
non_desktop_connectors: HashSet::new(),
@@ -599,6 +602,7 @@ impl Tty {
return;
};
+ let mut removed = Vec::new();
for event in device.drm_scanner.scan_connectors(&device.drm) {
match event {
DrmScanEvent::Connected {
@@ -611,11 +615,27 @@ impl Tty {
}
DrmScanEvent::Disconnected {
crtc: Some(crtc), ..
- } => self.connector_disconnected(niri, node, crtc),
+ } => {
+ self.connector_disconnected(niri, node, crtc);
+ removed.push(crtc);
+ }
_ => (),
}
}
+ // FIXME: this is better done in connector_disconnected(), but currently we call that to
+ // turn off outputs temporarily, too. So we can't do this there.
+ let Some(device) = self.devices.get_mut(&node) else {
+ error!("device disappeared");
+ return;
+ };
+
+ for crtc in removed {
+ if device.output_ids.remove(&crtc).is_none() {
+ error!("output ID missing for disconnected crtc: {crtc:?}");
+ }
+ }
+
self.refresh_ipc_outputs(niri);
}
@@ -724,6 +744,10 @@ impl Tty {
return Ok(());
}
+ // This should be unique per CRTC connection, however currently we can call
+ // connector_connected() multiple times for turning the output off and on.
+ device.output_ids.entry(crtc).or_insert_with(OutputId::next);
+
let config = self
.config
.borrow()
@@ -1464,7 +1488,7 @@ impl Tty {
for (node, device) in &self.devices {
for (connector, crtc) in device.drm_scanner.crtcs() {
- let connector_name = format!(
+ let name = format!(
"{}-{}",
connector.interface().as_str(),
connector.interface_id(),
@@ -1527,7 +1551,7 @@ impl Tty {
.map(logical_output);
let ipc_output = niri_ipc::Output {
- name: connector_name.clone(),
+ name,
make,
model,
physical_size,
@@ -1538,7 +1562,11 @@ impl Tty {
logical,
};
- ipc_outputs.insert(connector_name, ipc_output);
+ let id = device.output_ids.get(&crtc).copied().unwrap_or_else(|| {
+ error!("output ID missing for crtc: {crtc:?}");
+ OutputId::next()
+ });
+ ipc_outputs.insert(id, ipc_output);
}
}