metal: send non-desktop outputs to the frontend
This commit is contained in:
parent
fa3d870935
commit
24d08918c4
11 changed files with 184 additions and 62 deletions
|
|
@ -59,6 +59,7 @@ pub struct MonitorInfo {
|
||||||
pub initial_mode: Mode,
|
pub initial_mode: Mode,
|
||||||
pub width_mm: i32,
|
pub width_mm: i32,
|
||||||
pub height_mm: i32,
|
pub height_mm: i32,
|
||||||
|
pub non_desktop: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -409,9 +409,7 @@ impl MetalConnector {
|
||||||
|
|
||||||
fn connected(&self) -> bool {
|
fn connected(&self) -> bool {
|
||||||
let dd = self.display.borrow_mut();
|
let dd = self.display.borrow_mut();
|
||||||
self.enabled.get()
|
self.enabled.get() && dd.connection == ConnectorStatus::Connected
|
||||||
&& dd.connection == ConnectorStatus::Connected
|
|
||||||
&& self.primary_plane.is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schedule_present(&self) {
|
pub fn schedule_present(&self) {
|
||||||
|
|
@ -909,6 +907,9 @@ 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 {
|
||||||
|
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 {
|
||||||
log::warn!("Connector does not support mode {:?}", be_mode);
|
log::warn!("Connector does not support mode {:?}", be_mode);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1561,6 +1562,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,
|
||||||
}));
|
}));
|
||||||
connector.connect_sent.set(true);
|
connector.connect_sent.set(true);
|
||||||
connector.send_hardware_cursor();
|
connector.send_hardware_cursor();
|
||||||
|
|
@ -2457,6 +2459,9 @@ impl MetalBackend {
|
||||||
if !connector.connect_sent.get() {
|
if !connector.connect_sent.get() {
|
||||||
self.send_connected(connector, &dd);
|
self.send_connected(connector, &dd);
|
||||||
}
|
}
|
||||||
|
if connector.primary_plane.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if log_mode {
|
if log_mode {
|
||||||
log::info!(
|
log::info!(
|
||||||
"Initialized connector {}-{} with mode {:?}",
|
"Initialized connector {}-{} with mode {:?}",
|
||||||
|
|
|
||||||
|
|
@ -574,6 +574,7 @@ impl XBackend {
|
||||||
},
|
},
|
||||||
width_mm: output.width.get(),
|
width_mm: output.width.get(),
|
||||||
height_mm: output.height.get(),
|
height_mm: output.height.get(),
|
||||||
|
non_desktop: false,
|
||||||
}));
|
}));
|
||||||
output.changed();
|
output.changed();
|
||||||
self.present(output).await;
|
self.present(output).await;
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,7 @@ struct Output {
|
||||||
pub height_mm: i32,
|
pub height_mm: i32,
|
||||||
pub current_mode: Option<Mode>,
|
pub current_mode: Option<Mode>,
|
||||||
pub modes: Vec<Mode>,
|
pub modes: Vec<Mode>,
|
||||||
|
pub non_desktop: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
@ -479,12 +480,16 @@ impl Randr {
|
||||||
println!(" product: {}", o.product);
|
println!(" product: {}", o.product);
|
||||||
println!(" manufacturer: {}", o.manufacturer);
|
println!(" manufacturer: {}", o.manufacturer);
|
||||||
println!(" serial number: {}", o.serial_number);
|
println!(" serial number: {}", o.serial_number);
|
||||||
println!(" position: {} x {}", o.x, o.y);
|
|
||||||
println!(" logical size: {} x {}", o.width, o.height);
|
|
||||||
println!(
|
println!(
|
||||||
" physical size: {}mm x {}mm",
|
" physical size: {}mm x {}mm",
|
||||||
o.width_mm, o.height_mm
|
o.width_mm, o.height_mm
|
||||||
);
|
);
|
||||||
|
if o.non_desktop {
|
||||||
|
println!(" non-desktop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
println!(" position: {} x {}", o.x, o.y);
|
||||||
|
println!(" logical size: {} x {}", o.width, o.height);
|
||||||
if let Some(mode) = &o.current_mode {
|
if let Some(mode) = &o.current_mode {
|
||||||
print!(" mode: ");
|
print!(" mode: ");
|
||||||
self.print_mode(mode, false);
|
self.print_mode(mode, false);
|
||||||
|
|
@ -570,6 +575,27 @@ impl Randr {
|
||||||
height_mm: msg.height_mm,
|
height_mm: msg.height_mm,
|
||||||
modes: Default::default(),
|
modes: Default::default(),
|
||||||
current_mode: None,
|
current_mode: None,
|
||||||
|
non_desktop: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
jay_randr::NonDesktopOutput::handle(tc, randr, data.clone(), |data, msg| {
|
||||||
|
let mut data = data.borrow_mut();
|
||||||
|
let c = data.connectors.last_mut().unwrap();
|
||||||
|
c.output = Some(Output {
|
||||||
|
scale: 1.0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
transform: Transform::None,
|
||||||
|
manufacturer: msg.manufacturer.to_string(),
|
||||||
|
product: msg.product.to_string(),
|
||||||
|
serial_number: msg.serial_number.to_string(),
|
||||||
|
width_mm: msg.width_mm,
|
||||||
|
height_mm: msg.height_mm,
|
||||||
|
modes: Default::default(),
|
||||||
|
current_mode: None,
|
||||||
|
non_desktop: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
jay_randr::Mode::handle(tc, randr, data.clone(), |data, msg| {
|
jay_randr::Mode::handle(tc, randr, data.clone(), |data, msg| {
|
||||||
|
|
|
||||||
|
|
@ -514,6 +514,14 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_output_node(&self, connector: Connector) -> Result<Rc<OutputNode>, CphError> {
|
||||||
|
let data = self.get_output(connector)?;
|
||||||
|
match data.node.clone() {
|
||||||
|
Some(d) => Ok(d),
|
||||||
|
_ => Err(CphError::OutputIsNotDesktop(connector)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_drm_device(&self, dev: DrmDevice) -> Result<Rc<DrmDevData>, CphError> {
|
fn get_drm_device(&self, dev: DrmDevice) -> Result<Rc<DrmDevData>, CphError> {
|
||||||
match self.state.drm_devs.get(&DrmDeviceId::from_raw(dev.0 as _)) {
|
match self.state.drm_devs.get(&DrmDeviceId::from_raw(dev.0 as _)) {
|
||||||
Some(dev) => Ok(dev),
|
Some(dev) => Ok(dev),
|
||||||
|
|
@ -783,7 +791,7 @@ impl ConfigProxyHandler {
|
||||||
workspace: WorkspaceSource,
|
workspace: WorkspaceSource,
|
||||||
connector: Connector,
|
connector: Connector,
|
||||||
) -> Result<(), CphError> {
|
) -> Result<(), CphError> {
|
||||||
let output = self.get_output(connector)?;
|
let output = self.get_output_node(connector)?;
|
||||||
let ws = match workspace {
|
let ws = match workspace {
|
||||||
WorkspaceSource::Explicit(ws) => {
|
WorkspaceSource::Explicit(ws) => {
|
||||||
let name = self.get_workspace(ws)?;
|
let name = self.get_workspace(ws)?;
|
||||||
|
|
@ -797,10 +805,10 @@ impl ConfigProxyHandler {
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if ws.is_dummy || output.node.is_dummy {
|
if ws.is_dummy || output.is_dummy {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if ws.output.get().id == output.node.id {
|
if ws.output.get().id == output.id {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let link = match &*ws.output_link.borrow() {
|
let link = match &*ws.output_link.borrow() {
|
||||||
|
|
@ -811,8 +819,8 @@ impl ConfigProxyHandler {
|
||||||
make_visible_if_empty: true,
|
make_visible_if_empty: true,
|
||||||
source_is_destroyed: false,
|
source_is_destroyed: false,
|
||||||
};
|
};
|
||||||
move_ws_to_output(&link, &output.node, config);
|
move_ws_to_output(&link, &output, config);
|
||||||
ws.desired_output.set(output.node.global.output_id.clone());
|
ws.desired_output.set(output.global.output_id.clone());
|
||||||
self.state.tree_changed();
|
self.state.tree_changed();
|
||||||
self.state.damage();
|
self.state.damage();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -856,8 +864,8 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connector_mode(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_mode(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
let mode = connector.node.global.mode.get();
|
let mode = connector.global.mode.get();
|
||||||
self.respond(Response::ConnectorMode {
|
self.respond(Response::ConnectorMode {
|
||||||
width: mode.width,
|
width: mode.width,
|
||||||
height: mode.height,
|
height: mode.height,
|
||||||
|
|
@ -881,10 +889,9 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connector_modes(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_modes(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
self.respond(Response::ConnectorModes {
|
self.respond(Response::ConnectorModes {
|
||||||
modes: connector
|
modes: connector
|
||||||
.node
|
|
||||||
.global
|
.global
|
||||||
.modes
|
.modes
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -964,8 +971,8 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connector_size(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_size(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
let pos = connector.node.global.pos.get();
|
let pos = connector.global.pos.get();
|
||||||
self.respond(Response::ConnectorSize {
|
self.respond(Response::ConnectorSize {
|
||||||
width: pos.width(),
|
width: pos.width(),
|
||||||
height: pos.height(),
|
height: pos.height(),
|
||||||
|
|
@ -974,9 +981,9 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
self.respond(Response::ConnectorGetScale {
|
self.respond(Response::ConnectorGetScale {
|
||||||
scale: connector.node.global.persistent.scale.get().to_f64(),
|
scale: connector.global.persistent.scale.get().to_f64(),
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -989,8 +996,8 @@ impl ConfigProxyHandler {
|
||||||
return Err(CphError::ScaleTooLarge(scale));
|
return Err(CphError::ScaleTooLarge(scale));
|
||||||
}
|
}
|
||||||
let scale = Scale::from_f64(scale);
|
let scale = Scale::from_f64(scale);
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
connector.node.set_preferred_scale(scale);
|
connector.set_preferred_scale(scale);
|
||||||
self.state.damage();
|
self.state.damage();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -1000,8 +1007,8 @@ impl ConfigProxyHandler {
|
||||||
connector: Connector,
|
connector: Connector,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
) -> Result<(), CphError> {
|
) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
connector.node.update_transform(transform);
|
connector.update_transform(transform);
|
||||||
self.state.damage();
|
self.state.damage();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -1012,15 +1019,15 @@ impl ConfigProxyHandler {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
) -> Result<(), CphError> {
|
) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
if x < 0 || y < 0 || x > MAX_EXTENTS || y > MAX_EXTENTS {
|
if x < 0 || y < 0 || x > MAX_EXTENTS || y > MAX_EXTENTS {
|
||||||
return Err(CphError::InvalidConnectorPosition(x, y));
|
return Err(CphError::InvalidConnectorPosition(x, y));
|
||||||
}
|
}
|
||||||
let old_pos = connector.node.global.pos.get();
|
let old_pos = connector.global.pos.get();
|
||||||
connector.node.set_position(x, y);
|
connector.set_position(x, y);
|
||||||
let seats = self.state.globals.seats.lock();
|
let seats = self.state.globals.seats.lock();
|
||||||
for seat in seats.values() {
|
for seat in seats.values() {
|
||||||
if seat.get_output().id == connector.node.id {
|
if seat.get_output().id == connector.id {
|
||||||
let seat_pos = seat.position();
|
let seat_pos = seat.position();
|
||||||
seat.set_position(
|
seat.set_position(
|
||||||
seat_pos.0.round_down() + x - old_pos.x1(),
|
seat_pos.0.round_down() + x - old_pos.x1(),
|
||||||
|
|
@ -1032,8 +1039,8 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connector_get_position(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_get_position(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output_node(connector)?;
|
||||||
let (x, y) = connector.node.global.pos.get().position();
|
let (x, y) = connector.global.pos.get().position();
|
||||||
self.respond(Response::ConnectorGetPosition { x, y });
|
self.respond(Response::ConnectorGetPosition { x, y });
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -1813,6 +1820,8 @@ enum CphError {
|
||||||
TimerDoesNotExist(JayTimer),
|
TimerDoesNotExist(JayTimer),
|
||||||
#[error("Connector {0:?} does not exist or is not connected")]
|
#[error("Connector {0:?} does not exist or is not connected")]
|
||||||
OutputDoesNotExist(Connector),
|
OutputDoesNotExist(Connector),
|
||||||
|
#[error("Output {0:?} is not a desktop output")]
|
||||||
|
OutputIsNotDesktop(Connector),
|
||||||
#[error("{0}x{1} is not a valid connector position")]
|
#[error("{0}x{1} is not a valid connector position")]
|
||||||
InvalidConnectorPosition(i32, i32),
|
InvalidConnectorPosition(i32, i32),
|
||||||
#[error("Keymap {0:?} does not exist")]
|
#[error("Keymap {0:?} does not exist")]
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use {
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
state::{ConnectorData, DrmDevData, OutputData},
|
state::{ConnectorData, DrmDevData, OutputData},
|
||||||
|
tree::OutputNode,
|
||||||
utils::{gfx_api_ext::GfxApiExt, transform_ext::TransformExt},
|
utils::{gfx_api_ext::GfxApiExt, transform_ext::TransformExt},
|
||||||
wire::{jay_randr::*, JayRandrId},
|
wire::{jay_randr::*, JayRandrId},
|
||||||
},
|
},
|
||||||
|
|
@ -64,33 +65,47 @@ impl JayRandr {
|
||||||
enabled: data.connector.enabled() as _,
|
enabled: data.connector.enabled() as _,
|
||||||
name: &data.name,
|
name: &data.name,
|
||||||
});
|
});
|
||||||
if let Some(output) = self.client.state.outputs.get(&data.connector.id()) {
|
let Some(output) = self.client.state.outputs.get(&data.connector.id()) else {
|
||||||
let global = &output.node.global;
|
return;
|
||||||
let pos = global.pos.get();
|
};
|
||||||
self.client.event(Output {
|
let global = match output.node.as_ref().map(|n| &n.global) {
|
||||||
self_id: self.id,
|
Some(g) => g,
|
||||||
scale: global.persistent.scale.get().to_wl(),
|
_ => {
|
||||||
width: pos.width(),
|
self.client.event(NonDesktopOutput {
|
||||||
height: pos.height(),
|
|
||||||
x: pos.x1(),
|
|
||||||
y: pos.y1(),
|
|
||||||
transform: global.persistent.transform.get().to_wl(),
|
|
||||||
manufacturer: &output.monitor_info.manufacturer,
|
|
||||||
product: &output.monitor_info.product,
|
|
||||||
serial_number: &output.monitor_info.serial_number,
|
|
||||||
width_mm: global.width_mm,
|
|
||||||
height_mm: global.height_mm,
|
|
||||||
});
|
|
||||||
let current_mode = global.mode.get();
|
|
||||||
for mode in &global.modes {
|
|
||||||
self.client.event(Mode {
|
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
width: mode.width,
|
manufacturer: &output.monitor_info.manufacturer,
|
||||||
height: mode.height,
|
product: &output.monitor_info.product,
|
||||||
refresh_rate_millihz: mode.refresh_rate_millihz,
|
serial_number: &output.monitor_info.serial_number,
|
||||||
current: (mode == ¤t_mode) as _,
|
width_mm: output.monitor_info.width_mm,
|
||||||
|
height_mm: output.monitor_info.height_mm,
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
let pos = global.pos.get();
|
||||||
|
self.client.event(Output {
|
||||||
|
self_id: self.id,
|
||||||
|
scale: global.persistent.scale.get().to_wl(),
|
||||||
|
width: pos.width(),
|
||||||
|
height: pos.height(),
|
||||||
|
x: pos.x1(),
|
||||||
|
y: pos.y1(),
|
||||||
|
transform: global.persistent.transform.get().to_wl(),
|
||||||
|
manufacturer: &output.monitor_info.manufacturer,
|
||||||
|
product: &output.monitor_info.product,
|
||||||
|
serial_number: &output.monitor_info.serial_number,
|
||||||
|
width_mm: global.width_mm,
|
||||||
|
height_mm: global.height_mm,
|
||||||
|
});
|
||||||
|
let current_mode = global.mode.get();
|
||||||
|
for mode in &global.modes {
|
||||||
|
self.client.event(Mode {
|
||||||
|
self_id: self.id,
|
||||||
|
width: mode.width,
|
||||||
|
height: mode.height,
|
||||||
|
refresh_rate_millihz: mode.refresh_rate_millihz,
|
||||||
|
current: (mode == ¤t_mode) as _,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,6 +159,18 @@ impl JayRandr {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_output_node(&self, name: &str) -> Option<Rc<OutputNode>> {
|
||||||
|
let output = self.get_output(name)?;
|
||||||
|
match output.node.clone() {
|
||||||
|
Some(n) => return Some(n),
|
||||||
|
_ => self.send_error(&format!(
|
||||||
|
"Display connected to {} is not a desktop display",
|
||||||
|
output.connector.name
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JayRandrRequestHandler for JayRandr {
|
impl JayRandrRequestHandler for JayRandr {
|
||||||
|
|
@ -203,22 +230,22 @@ impl JayRandrRequestHandler for JayRandr {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_transform(&self, req: SetTransform, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn set_transform(&self, req: SetTransform, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let Some(c) = self.get_output(req.output) else {
|
let Some(c) = self.get_output_node(req.output) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let Some(transform) = Transform::from_wl(req.transform) else {
|
let Some(transform) = Transform::from_wl(req.transform) else {
|
||||||
self.send_error(&format!("Unknown transform {}", req.transform));
|
self.send_error(&format!("Unknown transform {}", req.transform));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
c.node.update_transform(transform);
|
c.update_transform(transform);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_scale(&self, req: SetScale, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn set_scale(&self, req: SetScale, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let Some(c) = self.get_output(req.output) else {
|
let Some(c) = self.get_output_node(req.output) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
c.node.set_preferred_scale(Scale::from_wl(req.scale));
|
c.set_preferred_scale(Scale::from_wl(req.scale));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +262,7 @@ impl JayRandrRequestHandler for JayRandr {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_position(&self, req: SetPosition, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn set_position(&self, req: SetPosition, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let Some(c) = self.get_output(req.output) else {
|
let Some(c) = self.get_output_node(req.output) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
if req.x < 0 || req.y < 0 {
|
if req.x < 0 || req.y < 0 {
|
||||||
|
|
@ -246,7 +273,7 @@ impl JayRandrRequestHandler for JayRandr {
|
||||||
self.send_error(&format!("x and y cannot be greater than {MAX_EXTENTS}"));
|
self.send_error(&format!("x and y cannot be greater than {MAX_EXTENTS}"));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
c.node.set_position(req.x, req.y);
|
c.set_position(req.x, req.y);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ impl TestBackend {
|
||||||
initial_mode: mode,
|
initial_mode: mode,
|
||||||
width_mm: 80,
|
width_mm: 80,
|
||||||
height_mm: 60,
|
height_mm: 60,
|
||||||
|
non_desktop: false,
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
},
|
},
|
||||||
width_mm: 0,
|
width_mm: 0,
|
||||||
height_mm: 0,
|
height_mm: 0,
|
||||||
|
non_desktop: false,
|
||||||
};
|
};
|
||||||
run.backend
|
run.backend
|
||||||
.state
|
.state
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ pub struct ConnectorData {
|
||||||
pub struct OutputData {
|
pub struct OutputData {
|
||||||
pub connector: Rc<ConnectorData>,
|
pub connector: Rc<ConnectorData>,
|
||||||
pub monitor_info: MonitorInfo,
|
pub monitor_info: MonitorInfo,
|
||||||
pub node: Rc<OutputNode>,
|
pub node: Option<Rc<OutputNode>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmDevData {
|
pub struct DrmDevData {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
|
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
|
||||||
|
globals::GlobalName,
|
||||||
ifs::wl_output::{OutputId, PersistentOutputState, WlOutputGlobal},
|
ifs::wl_output::{OutputId, PersistentOutputState, WlOutputGlobal},
|
||||||
state::{ConnectorData, OutputData, State},
|
state::{ConnectorData, OutputData, State},
|
||||||
tree::{move_ws_to_output, OutputNode, OutputRenderData, WsMoveConfig},
|
tree::{move_ws_to_output, OutputNode, OutputRenderData, WsMoveConfig},
|
||||||
|
|
@ -70,6 +71,9 @@ impl ConnectorHandler {
|
||||||
}
|
}
|
||||||
self.data.async_event.triggered().await;
|
self.data.async_event.triggered().await;
|
||||||
}
|
}
|
||||||
|
if let Some(dev) = &self.data.drm_dev {
|
||||||
|
dev.connectors.remove(&self.id);
|
||||||
|
}
|
||||||
if let Some(config) = self.state.config.get() {
|
if let Some(config) = self.state.config.get() {
|
||||||
config.del_connector(self.id);
|
config.del_connector(self.id);
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +91,21 @@ impl ConnectorHandler {
|
||||||
model: info.product.clone(),
|
model: info.product.clone(),
|
||||||
serial_number: info.serial_number.clone(),
|
serial_number: info.serial_number.clone(),
|
||||||
});
|
});
|
||||||
|
if info.non_desktop {
|
||||||
|
self.handle_non_desktop_connected(info).await;
|
||||||
|
} else {
|
||||||
|
self.handle_desktop_connected(info, name, output_id).await;
|
||||||
|
}
|
||||||
|
self.data.connected.set(false);
|
||||||
|
log::info!("Connector {} disconnected", self.data.connector.kernel_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_desktop_connected(
|
||||||
|
&self,
|
||||||
|
info: MonitorInfo,
|
||||||
|
name: GlobalName,
|
||||||
|
output_id: Rc<OutputId>,
|
||||||
|
) {
|
||||||
let desired_state = match self.state.persistent_output_states.get(&output_id) {
|
let desired_state = match self.state.persistent_output_states.get(&output_id) {
|
||||||
Some(ds) => ds,
|
Some(ds) => ds,
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -155,7 +174,7 @@ impl ConnectorHandler {
|
||||||
let output_data = Rc::new(OutputData {
|
let output_data = Rc::new(OutputData {
|
||||||
connector: self.data.clone(),
|
connector: self.data.clone(),
|
||||||
monitor_info: info,
|
monitor_info: info,
|
||||||
node: on.clone(),
|
node: Some(on.clone()),
|
||||||
});
|
});
|
||||||
self.state.outputs.set(self.id, output_data);
|
self.state.outputs.set(self.id, output_data);
|
||||||
on.schedule_update_render_data();
|
on.schedule_update_render_data();
|
||||||
|
|
@ -224,7 +243,6 @@ impl ConnectorHandler {
|
||||||
}
|
}
|
||||||
self.data.async_event.triggered().await;
|
self.data.async_event.triggered().await;
|
||||||
}
|
}
|
||||||
log::info!("Connector {} disconnected", self.data.connector.kernel_id());
|
|
||||||
if let Some(config) = self.state.config.get() {
|
if let Some(config) = self.state.config.get() {
|
||||||
config.connector_disconnected(self.id);
|
config.connector_disconnected(self.id);
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +260,6 @@ impl ConnectorHandler {
|
||||||
global.destroyed.set(true);
|
global.destroyed.set(true);
|
||||||
self.state.root.outputs.remove(&self.id);
|
self.state.root.outputs.remove(&self.id);
|
||||||
self.state.root.update_extents();
|
self.state.root.update_extents();
|
||||||
self.data.connected.set(false);
|
|
||||||
self.state.outputs.remove(&self.id);
|
self.state.outputs.remove(&self.id);
|
||||||
on.lock_surface.take();
|
on.lock_surface.take();
|
||||||
{
|
{
|
||||||
|
|
@ -285,4 +302,30 @@ impl ConnectorHandler {
|
||||||
self.state.tree_changed();
|
self.state.tree_changed();
|
||||||
self.state.damage();
|
self.state.damage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_non_desktop_connected(&self, monitor_info: MonitorInfo) {
|
||||||
|
let output_data = Rc::new(OutputData {
|
||||||
|
connector: self.data.clone(),
|
||||||
|
monitor_info,
|
||||||
|
node: None,
|
||||||
|
});
|
||||||
|
self.state.outputs.set(self.id, output_data);
|
||||||
|
if let Some(config) = self.state.config.get() {
|
||||||
|
config.connector_connected(self.id);
|
||||||
|
}
|
||||||
|
'outer: loop {
|
||||||
|
while let Some(event) = self.data.connector.event() {
|
||||||
|
match event {
|
||||||
|
ConnectorEvent::Disconnected => break 'outer,
|
||||||
|
ConnectorEvent::HardwareCursor(None) => {}
|
||||||
|
ev => unreachable!("received unexpected event {:?}", ev),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.data.async_event.triggered().await;
|
||||||
|
}
|
||||||
|
self.state.outputs.remove(&self.id);
|
||||||
|
if let Some(config) = self.state.config.get() {
|
||||||
|
config.connector_disconnected(self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,3 +99,11 @@ event mode {
|
||||||
event error {
|
event error {
|
||||||
msg: str,
|
msg: str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event non_desktop_output {
|
||||||
|
manufacturer: str,
|
||||||
|
product: str,
|
||||||
|
serial_number: str,
|
||||||
|
width_mm: i32,
|
||||||
|
height_mm: i32,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue