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
}
fn set_mode(&self, mode: Mode);
fn set_non_desktop_override(&self, non_desktop: Option<bool>) {
let _ = non_desktop;
}
}
#[derive(Debug)]

View file

@ -173,6 +173,7 @@ pub struct ConnectorDisplayData {
pub mode: Option<DrmModeInfo>,
pub refresh: u32,
pub non_desktop: bool,
pub non_desktop_effective: bool,
pub monitor_manufacturer: String,
pub monitor_name: String,
@ -209,6 +210,7 @@ pub struct MetalConnector {
pub next_buffer: NumCell<usize>,
pub enabled: Cell<bool>,
pub non_desktop_override: Cell<Option<bool>>,
pub can_present: Cell<bool>,
pub has_damage: Cell<bool>,
@ -907,7 +909,7 @@ impl Connector for MetalConnector {
fn set_mode(&self, be_mode: Mode) {
let mut dd = self.display.borrow_mut();
if dd.non_desktop {
if dd.non_desktop_effective {
return;
}
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));
};
}
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 {
@ -1052,7 +1073,7 @@ fn create_connector(
connector: DrmConnector,
dev: &Rc<MetalDrmDevice>,
) -> 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 {
id: connector,
master: dev.master.clone(),
@ -1063,6 +1084,7 @@ fn create_connector(
buffers: Default::default(),
next_buffer: Default::default(),
enabled: Cell::new(true),
non_desktop_override: Default::default(),
can_present: Cell::new(true),
has_damage: Cell::new(true),
primary_plane: Default::default(),
@ -1100,6 +1122,7 @@ fn create_connector(
fn create_connector_display_data(
connector: DrmConnector,
dev: &Rc<MetalDrmDevice>,
non_desktop_override: Option<bool>,
) -> Result<ConnectorDisplayData, DrmError> {
let info = dev.master.get_connector_info(connector, true)?;
let mut crtcs = AHashMap::new();
@ -1186,13 +1209,15 @@ fn create_connector_display_data(
}
let props = collect_properties(&dev.master, connector)?;
let connector_type = ConnectorType::from_drm(info.connector_type);
let non_desktop = props.get("non-desktop")?.value.get() != 0;
Ok(ConnectorDisplayData {
crtc_id: props.get("CRTC_ID")?.map(|v| DrmCrtc(v as _)),
crtcs,
modes: info.modes,
mode,
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_name: name,
monitor_serial_number: serial_number,
@ -1486,7 +1511,8 @@ impl MetalBackend {
}
let mut preserve = Preserve::default();
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,
Err(e) => {
log::error!(
@ -1509,6 +1535,7 @@ impl MetalBackend {
if !c.enabled.get()
|| old.connection != ConnectorStatus::Connected
|| !old.is_same_monitor(&dd)
|| c.primary_plane.is_none() != old.non_desktop_effective
{
c.on_change.send_event(ConnectorEvent::Disconnected);
c.connect_sent.set(false);
@ -1562,7 +1589,7 @@ impl MetalBackend {
initial_mode: dd.mode.clone().unwrap().to_backend(),
width_mm: dd.mm_width as _,
height_mm: dd.mm_height as _,
non_desktop: dd.non_desktop,
non_desktop: dd.non_desktop_effective,
}));
connector.connect_sent.set(true);
connector.send_hardware_cursor();
@ -1857,6 +1884,8 @@ impl MetalBackend {
if preserve.connectors.contains(&connector.id) {
continue;
}
connector.buffers.set(None);
connector.cursor_buffers.set(None);
connector.primary_plane.set(None);
connector.cursor_plane.set(None);
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 {
!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,
wire::{jay_compositor, jay_randr, JayRandrId},
},
clap::{Args, Subcommand},
clap::{Args, Subcommand, ValueEnum},
isnt::std_1::vec::IsntVecExt,
jay_config::video::Transform,
std::{
@ -115,6 +115,21 @@ pub enum OutputCommand {
Enable,
/// Disable the output.
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)]
@ -374,6 +389,16 @@ impl Randr {
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;
}

View file

@ -284,6 +284,19 @@ impl JayRandrRequestHandler for JayRandr {
c.connector.set_enabled(req.enabled != 0);
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! {

View file

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