1
0
Fork 0
forked from wry/wry

cli: allow overriding non-desktop setting

This commit is contained in:
Julian Orth 2024-04-25 18:39:29 +02:00
parent 24d08918c4
commit 1f18b46135
5 changed files with 84 additions and 7 deletions

View file

@ -91,6 +91,9 @@ pub trait Connector {
None None
} }
fn set_mode(&self, mode: Mode); fn set_mode(&self, mode: Mode);
fn set_non_desktop_override(&self, non_desktop: Option<bool>) {
let _ = non_desktop;
}
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -173,6 +173,7 @@ pub struct ConnectorDisplayData {
pub mode: Option<DrmModeInfo>, pub mode: Option<DrmModeInfo>,
pub refresh: u32, pub refresh: u32,
pub non_desktop: bool, pub non_desktop: bool,
pub non_desktop_effective: bool,
pub monitor_manufacturer: String, pub monitor_manufacturer: String,
pub monitor_name: String, pub monitor_name: String,
@ -209,6 +210,7 @@ pub struct MetalConnector {
pub next_buffer: NumCell<usize>, pub next_buffer: NumCell<usize>,
pub enabled: Cell<bool>, pub enabled: Cell<bool>,
pub non_desktop_override: Cell<Option<bool>>,
pub can_present: Cell<bool>, pub can_present: Cell<bool>,
pub has_damage: Cell<bool>, pub has_damage: Cell<bool>,
@ -907,7 +909,7 @@ impl Connector for MetalConnector {
fn set_mode(&self, be_mode: Mode) { fn set_mode(&self, be_mode: Mode) {
let mut dd = self.display.borrow_mut(); let mut dd = self.display.borrow_mut();
if dd.non_desktop { if dd.non_desktop_effective {
return; return;
} }
let Some(mode) = dd.modes.iter().find(|m| m.to_backend() == be_mode) else { let Some(mode) = dd.modes.iter().find(|m| m.to_backend() == be_mode) else {
@ -945,6 +947,25 @@ impl Connector for MetalConnector {
log::warn!("Could not restore the previous mode: {}", ErrorFmt(e)); log::warn!("Could not restore the previous mode: {}", ErrorFmt(e));
}; };
} }
fn set_non_desktop_override(&self, non_desktop: Option<bool>) {
if self.non_desktop_override.replace(non_desktop) == non_desktop {
return;
}
let mut dd = self.display.borrow_mut();
let non_desktop_effective = non_desktop.unwrap_or(dd.non_desktop);
if dd.non_desktop_effective == non_desktop_effective {
return;
}
dd.non_desktop_effective = non_desktop_effective;
drop(dd);
if let Some(dev) = self.backend.device_holder.drm_devices.get(&self.dev.devnum) {
if let Err(e) = self.backend.handle_drm_change_(&dev, true) {
dev.unprocessed_change.set(true);
log::error!("Could not override non-desktop setting: {}", ErrorFmt(e));
}
}
}
} }
pub struct MetalCrtc { pub struct MetalCrtc {
@ -1052,7 +1073,7 @@ fn create_connector(
connector: DrmConnector, connector: DrmConnector,
dev: &Rc<MetalDrmDevice>, dev: &Rc<MetalDrmDevice>,
) -> Result<(Rc<MetalConnector>, ConnectorFutures), DrmError> { ) -> Result<(Rc<MetalConnector>, ConnectorFutures), DrmError> {
let display = create_connector_display_data(connector, dev)?; let display = create_connector_display_data(connector, dev, None)?;
let slf = Rc::new(MetalConnector { let slf = Rc::new(MetalConnector {
id: connector, id: connector,
master: dev.master.clone(), master: dev.master.clone(),
@ -1063,6 +1084,7 @@ fn create_connector(
buffers: Default::default(), buffers: Default::default(),
next_buffer: Default::default(), next_buffer: Default::default(),
enabled: Cell::new(true), enabled: Cell::new(true),
non_desktop_override: Default::default(),
can_present: Cell::new(true), can_present: Cell::new(true),
has_damage: Cell::new(true), has_damage: Cell::new(true),
primary_plane: Default::default(), primary_plane: Default::default(),
@ -1100,6 +1122,7 @@ fn create_connector(
fn create_connector_display_data( fn create_connector_display_data(
connector: DrmConnector, connector: DrmConnector,
dev: &Rc<MetalDrmDevice>, dev: &Rc<MetalDrmDevice>,
non_desktop_override: Option<bool>,
) -> Result<ConnectorDisplayData, DrmError> { ) -> Result<ConnectorDisplayData, DrmError> {
let info = dev.master.get_connector_info(connector, true)?; let info = dev.master.get_connector_info(connector, true)?;
let mut crtcs = AHashMap::new(); let mut crtcs = AHashMap::new();
@ -1186,13 +1209,15 @@ fn create_connector_display_data(
} }
let props = collect_properties(&dev.master, connector)?; let props = collect_properties(&dev.master, connector)?;
let connector_type = ConnectorType::from_drm(info.connector_type); let connector_type = ConnectorType::from_drm(info.connector_type);
let non_desktop = props.get("non-desktop")?.value.get() != 0;
Ok(ConnectorDisplayData { Ok(ConnectorDisplayData {
crtc_id: props.get("CRTC_ID")?.map(|v| DrmCrtc(v as _)), crtc_id: props.get("CRTC_ID")?.map(|v| DrmCrtc(v as _)),
crtcs, crtcs,
modes: info.modes, modes: info.modes,
mode, mode,
refresh, refresh,
non_desktop: props.get("non-desktop")?.value.get() != 0, non_desktop,
non_desktop_effective: non_desktop_override.unwrap_or(non_desktop),
monitor_manufacturer: manufacturer, monitor_manufacturer: manufacturer,
monitor_name: name, monitor_name: name,
monitor_serial_number: serial_number, monitor_serial_number: serial_number,
@ -1486,7 +1511,8 @@ impl MetalBackend {
} }
let mut preserve = Preserve::default(); let mut preserve = Preserve::default();
for c in dev.connectors.lock().values() { for c in dev.connectors.lock().values() {
let mut dd = match create_connector_display_data(c.id, &dev.dev) { let dd = create_connector_display_data(c.id, &dev.dev, c.non_desktop_override.get());
let mut dd = match dd {
Ok(d) => d, Ok(d) => d,
Err(e) => { Err(e) => {
log::error!( log::error!(
@ -1509,6 +1535,7 @@ impl MetalBackend {
if !c.enabled.get() if !c.enabled.get()
|| old.connection != ConnectorStatus::Connected || old.connection != ConnectorStatus::Connected
|| !old.is_same_monitor(&dd) || !old.is_same_monitor(&dd)
|| c.primary_plane.is_none() != old.non_desktop_effective
{ {
c.on_change.send_event(ConnectorEvent::Disconnected); c.on_change.send_event(ConnectorEvent::Disconnected);
c.connect_sent.set(false); c.connect_sent.set(false);
@ -1562,7 +1589,7 @@ impl MetalBackend {
initial_mode: dd.mode.clone().unwrap().to_backend(), initial_mode: dd.mode.clone().unwrap().to_backend(),
width_mm: dd.mm_width as _, width_mm: dd.mm_width as _,
height_mm: dd.mm_height as _, height_mm: dd.mm_height as _,
non_desktop: dd.non_desktop, non_desktop: dd.non_desktop_effective,
})); }));
connector.connect_sent.set(true); connector.connect_sent.set(true);
connector.send_hardware_cursor(); connector.send_hardware_cursor();
@ -1857,6 +1884,8 @@ impl MetalBackend {
if preserve.connectors.contains(&connector.id) { if preserve.connectors.contains(&connector.id) {
continue; continue;
} }
connector.buffers.set(None);
connector.cursor_buffers.set(None);
connector.primary_plane.set(None); connector.primary_plane.set(None);
connector.cursor_plane.set(None); connector.cursor_plane.set(None);
connector.cursor_enabled.set(false); connector.cursor_enabled.set(false);
@ -2528,5 +2557,7 @@ fn modes_equal(a: &DrmModeInfo, b: &DrmModeInfo) -> bool {
} }
fn should_ignore(connector: &MetalConnector, dd: &ConnectorDisplayData) -> bool { fn should_ignore(connector: &MetalConnector, dd: &ConnectorDisplayData) -> bool {
!connector.enabled.get() || dd.connection != ConnectorStatus::Connected || dd.non_desktop !connector.enabled.get()
|| dd.connection != ConnectorStatus::Connected
|| dd.non_desktop_effective
} }

View file

@ -6,7 +6,7 @@ use {
utils::transform_ext::TransformExt, utils::transform_ext::TransformExt,
wire::{jay_compositor, jay_randr, JayRandrId}, wire::{jay_compositor, jay_randr, JayRandrId},
}, },
clap::{Args, Subcommand}, clap::{Args, Subcommand, ValueEnum},
isnt::std_1::vec::IsntVecExt, isnt::std_1::vec::IsntVecExt,
jay_config::video::Transform, jay_config::video::Transform,
std::{ std::{
@ -115,6 +115,21 @@ pub enum OutputCommand {
Enable, Enable,
/// Disable the output. /// Disable the output.
Disable, Disable,
/// Override the display's non-desktop setting.
NonDesktop(NonDesktopArgs),
}
#[derive(ValueEnum, Debug, Clone)]
pub enum NonDesktopType {
Default,
False,
True,
}
#[derive(Args, Debug, Clone)]
pub struct NonDesktopArgs {
/// Whether this output is a non-desktop output.
pub setting: NonDesktopType,
} }
#[derive(Args, Debug, Clone)] #[derive(Args, Debug, Clone)]
@ -374,6 +389,16 @@ impl Randr {
enabled: enable as _, enabled: enable as _,
}); });
} }
OutputCommand::NonDesktop(a) => {
self.handle_error(randr, move |msg| {
eprintln!("Could not change the non-desktop setting: {}", msg);
});
tc.send(jay_randr::SetNonDesktop {
self_id: randr,
output: &args.output,
non_desktop: a.setting as _,
});
}
} }
tc.round_trip().await; tc.round_trip().await;
} }

View file

@ -284,6 +284,19 @@ impl JayRandrRequestHandler for JayRandr {
c.connector.set_enabled(req.enabled != 0); c.connector.set_enabled(req.enabled != 0);
Ok(()) Ok(())
} }
fn set_non_desktop(&self, req: SetNonDesktop<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let Some(c) = self.get_connector(req.output) else {
return Ok(());
};
let non_desktop = match req.non_desktop {
0 => None,
1 => Some(false),
_ => Some(true),
};
c.connector.set_non_desktop_override(non_desktop);
Ok(())
}
} }
object_base! { object_base! {

View file

@ -50,6 +50,11 @@ request set_enabled {
enabled: u32, enabled: u32,
} }
request set_non_desktop {
output: str,
non_desktop: u32,
}
# events # events
event global { event global {