diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-27 09:46:18 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-27 09:46:18 +0400 |
| commit | e276c906bf4bea27dc8173815ff373d04c20caaf (patch) | |
| tree | 6843e6ab8244f296b89d54d53b2ebfd6e1a16592 /src/dbus | |
| parent | 571768af433b0fdc653f44b7dee0ad2dda6fe344 (diff) | |
| download | niri-e276c906bf4bea27dc8173815ff373d04c20caaf.tar.gz niri-e276c906bf4bea27dc8173815ff373d04c20caaf.tar.bz2 niri-e276c906bf4bea27dc8173815ff373d04c20caaf.zip | |
Expose more info in DisplayConfig impl
Needed for the new xdp-gnome.
Diffstat (limited to 'src/dbus')
| -rw-r--r-- | src/dbus/mod.rs | 4 | ||||
| -rw-r--r-- | src/dbus/mutter_display_config.rs | 102 | ||||
| -rw-r--r-- | src/dbus/mutter_screen_cast.rs | 22 |
3 files changed, 86 insertions, 42 deletions
diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index 6d8b81e6..7d63682d 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -47,7 +47,7 @@ impl DBusServers { } if is_session_instance || config.debug.dbus_interfaces_in_non_session_instances { - let display_config = DisplayConfig::new(backend.enabled_outputs()); + let display_config = DisplayConfig::new(backend.ipc_outputs()); dbus.conn_display_config = try_start(display_config); let screen_saver = ScreenSaver::new(niri.is_fdo_idle_inhibited.clone()); @@ -80,7 +80,7 @@ impl DBusServers { } }) .unwrap(); - let screen_cast = ScreenCast::new(backend.enabled_outputs(), to_niri); + let screen_cast = ScreenCast::new(backend.ipc_outputs(), to_niri); dbus.conn_screen_cast = try_start(screen_cast); } else { warn!("disabling screencast support because we couldn't start PipeWire"); diff --git a/src/dbus/mutter_display_config.rs b/src/dbus/mutter_display_config.rs index ea945653..2e29b923 100644 --- a/src/dbus/mutter_display_config.rs +++ b/src/dbus/mutter_display_config.rs @@ -2,15 +2,16 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use serde::Serialize; -use smithay::output::Output; +use smithay::utils::Transform; use zbus::fdo::RequestNameFlags; use zbus::zvariant::{self, OwnedValue, Type}; use zbus::{dbus_interface, fdo, SignalContext}; use super::Start; +use crate::backend::IpcOutputMap; pub struct DisplayConfig { - enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, + ipc_outputs: Arc<Mutex<IpcOutputMap>>, } #[derive(Serialize, Type)] @@ -53,12 +54,17 @@ impl DisplayConfig { HashMap<String, OwnedValue>, )> { // Construct the DBus response. - let mut monitors: Vec<Monitor> = self - .enabled_outputs + let mut monitors: Vec<(Monitor, LogicalMonitor)> = self + .ipc_outputs .lock() .unwrap() - .keys() - .map(|c| { + .iter() + // Take only enabled outputs. + .filter_map(|(c, (ipc, output))| { + ipc.current_mode?; + output.as_ref().map(move |output| (c, (ipc, output))) + }) + .map(|(c, (ipc, output))| { // Loosely matches the check in Mutter. let is_laptop_panel = matches!(c.get(..4), Some("eDP-" | "LVDS" | "DSI-")); @@ -78,38 +84,78 @@ impl DisplayConfig { OwnedValue::from(is_laptop_panel), ); - Monitor { + let mut modes: Vec<Mode> = ipc + .modes + .iter() + .map(|m| { + let niri_ipc::Mode { + width, + height, + refresh_rate, + } = *m; + let refresh = refresh_rate as f64 / 1000.; + + Mode { + id: format!("{width}x{height}@{refresh:.3}"), + width: i32::from(width), + height: i32::from(height), + refresh_rate: refresh, + preferred_scale: 1., + supported_scales: vec![1., 2., 3.], + properties: HashMap::new(), + } + }) + .collect(); + modes[ipc.current_mode.unwrap()] + .properties + .insert(String::from("is-current"), OwnedValue::from(true)); + + let monitor = Monitor { names: (c.clone(), String::new(), String::new(), serial), - modes: vec![], + modes, properties, - } + }; + + let loc = output.current_location(); + + let transform = match output.current_transform() { + Transform::Normal => 0, + Transform::_90 => 1, + Transform::_180 => 2, + Transform::_270 => 3, + Transform::Flipped => 4, + Transform::Flipped90 => 5, + Transform::Flipped180 => 6, + Transform::Flipped270 => 7, + }; + + let logical_monitor = LogicalMonitor { + x: loc.x, + y: loc.y, + scale: output.current_scale().fractional_scale(), + transform, + is_primary: false, + monitors: vec![monitor.names.clone()], + properties: HashMap::new(), + }; + + (monitor, logical_monitor) }) .collect(); // Sort the built-in monitor first, then by connector name. monitors.sort_unstable_by(|a, b| { - let a_is_builtin = a.properties.contains_key("display-name"); - let b_is_builtin = b.properties.contains_key("display-name"); + let a_is_builtin = a.0.properties.contains_key("display-name"); + let b_is_builtin = b.0.properties.contains_key("display-name"); a_is_builtin .cmp(&b_is_builtin) .reverse() - .then_with(|| a.names.0.cmp(&b.names.0)) + .then_with(|| a.0.names.0.cmp(&b.0.names.0)) }); - let logical_monitors = monitors - .iter() - .map(|m| LogicalMonitor { - x: 0, - y: 0, - scale: 1., - transform: 0, - is_primary: false, - monitors: vec![m.names.clone()], - properties: HashMap::new(), - }) - .collect(); - - Ok((0, monitors, logical_monitors, HashMap::new())) + let (monitors, logical_monitors) = monitors.into_iter().unzip(); + let properties = HashMap::from([(String::from("layout-mode"), OwnedValue::from(1u32))]); + Ok((0, monitors, logical_monitors, properties)) } #[dbus_interface(signal)] @@ -117,8 +163,8 @@ impl DisplayConfig { } impl DisplayConfig { - pub fn new(enabled_outputs: Arc<Mutex<HashMap<String, Output>>>) -> Self { - Self { enabled_outputs } + pub fn new(ipc_outputs: Arc<Mutex<IpcOutputMap>>) -> Self { + Self { ipc_outputs } } } diff --git a/src/dbus/mutter_screen_cast.rs b/src/dbus/mutter_screen_cast.rs index 151a1c89..d9c6c28e 100644 --- a/src/dbus/mutter_screen_cast.rs +++ b/src/dbus/mutter_screen_cast.rs @@ -10,11 +10,12 @@ use zbus::zvariant::{DeserializeDict, OwnedObjectPath, SerializeDict, Type, Valu use zbus::{dbus_interface, fdo, InterfaceRef, ObjectServer, SignalContext}; use super::Start; +use crate::backend::IpcOutputMap; use crate::utils::output_size; #[derive(Clone)] pub struct ScreenCast { - enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, + ipc_outputs: Arc<Mutex<IpcOutputMap>>, to_niri: calloop::channel::Sender<ScreenCastToNiri>, #[allow(clippy::type_complexity)] sessions: Arc<Mutex<Vec<(Session, InterfaceRef<Session>)>>>, @@ -23,7 +24,7 @@ pub struct ScreenCast { #[derive(Clone)] pub struct Session { id: usize, - enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, + ipc_outputs: Arc<Mutex<IpcOutputMap>>, to_niri: calloop::channel::Sender<ScreenCastToNiri>, #[allow(clippy::type_complexity)] streams: Arc<Mutex<Vec<(Stream, InterfaceRef<Stream>)>>>, @@ -92,11 +93,7 @@ impl ScreenCast { let path = format!("/org/gnome/Mutter/ScreenCast/Session/u{}", session_id); let path = OwnedObjectPath::try_from(path).unwrap(); - let session = Session::new( - session_id, - self.enabled_outputs.clone(), - self.to_niri.clone(), - ); + let session = Session::new(session_id, self.ipc_outputs.clone(), self.to_niri.clone()); match server.at(&path, session.clone()).await { Ok(true) => { let iface = server.interface(&path).await.unwrap(); @@ -163,7 +160,8 @@ impl Session { ) -> fdo::Result<OwnedObjectPath> { debug!(connector, ?properties, "record_monitor"); - let Some(output) = self.enabled_outputs.lock().unwrap().get(connector).cloned() else { + let Some((_, Some(output))) = self.ipc_outputs.lock().unwrap().get(connector).cloned() + else { return Err(fdo::Error::Failed("no such monitor".to_owned())); }; @@ -212,11 +210,11 @@ impl Stream { impl ScreenCast { pub fn new( - enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, + ipc_outputs: Arc<Mutex<IpcOutputMap>>, to_niri: calloop::channel::Sender<ScreenCastToNiri>, ) -> Self { Self { - enabled_outputs, + ipc_outputs, to_niri, sessions: Arc::new(Mutex::new(vec![])), } @@ -241,12 +239,12 @@ impl Start for ScreenCast { impl Session { pub fn new( id: usize, - enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, + ipc_outputs: Arc<Mutex<IpcOutputMap>>, to_niri: calloop::channel::Sender<ScreenCastToNiri>, ) -> Self { Self { id, - enabled_outputs, + ipc_outputs, streams: Arc::new(Mutex::new(vec![])), to_niri, } |
