1
0
Fork 0
forked from wry/wry

backend: implement output transactions

This commit is contained in:
Julian Orth 2025-07-10 11:17:34 +02:00
parent f8d03c25a9
commit 7ab99bb840
25 changed files with 2712 additions and 1460 deletions

View file

@ -60,6 +60,7 @@ impl ExtSessionLockManagerV1RequestHandler for ExtSessionLockManagerV1 {
client: self.client.clone(),
tracker: Default::default(),
did_lock,
awaiting_locked: Cell::new(true),
finished: Cell::new(false),
version: self.version,
});
@ -75,7 +76,7 @@ impl ExtSessionLockManagerV1RequestHandler for ExtSessionLockManagerV1 {
state.lock.lock.set(Some(new.clone()));
state.tree_changed();
state.damage(state.root.extents.get());
new.send_locked();
new.check_locked();
} else {
new.finish();
}

View file

@ -17,12 +17,26 @@ pub struct ExtSessionLockV1 {
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub did_lock: bool,
pub awaiting_locked: Cell<bool>,
pub finished: Cell<bool>,
pub version: Version,
}
impl ExtSessionLockV1 {
pub fn send_locked(&self) {
pub fn check_locked(&self) {
if !self.awaiting_locked.get() {
return;
}
for output in self.client.state.outputs.lock().values() {
if !output.connector.connector.effectively_locked() {
return;
}
}
self.send_locked();
self.awaiting_locked.set(false);
}
fn send_locked(&self) {
self.client.event(Locked { self_id: self.id })
}

View file

@ -7,9 +7,9 @@ use {
leaks::Tracker,
object::{Object, Version},
scale::Scale,
state::{ConnectorData, DrmDevData, OutputData},
state::{ConnectorData, DrmDevData, OutputData, State},
tree::{OutputNode, TearingMode, VrrMode},
utils::{gfx_api_ext::GfxApiExt, transform_ext::TransformExt},
utils::{errorfmt::ErrorFmt, gfx_api_ext::GfxApiExt, transform_ext::TransformExt},
wire::{JayRandrId, jay_randr::*},
},
jay_config::video::{
@ -23,6 +23,7 @@ use {
pub struct JayRandr {
pub id: JayRandrId,
pub client: Rc<Client>,
pub state: Rc<State>,
pub tracker: Tracker<Self>,
pub version: Version,
}
@ -39,6 +40,7 @@ impl JayRandr {
Self {
id,
client: client.clone(),
state: client.state.clone(),
tracker: Default::default(),
version,
}
@ -67,6 +69,7 @@ impl JayRandr {
}
fn send_connector(&self, data: &ConnectorData) {
let state = data.state.get();
self.client.event(Connector {
self_id: self.id,
id: data.connector.id().raw() as _,
@ -75,7 +78,7 @@ impl JayRandr {
.as_ref()
.map(|d| d.dev.id().raw() as _)
.unwrap_or_default(),
enabled: data.connector.enabled() as _,
enabled: state.enabled as _,
name: &data.name,
});
let Some(output) = self.client.state.outputs.get(&data.connector.id()) else {
@ -347,14 +350,19 @@ impl JayRandrRequestHandler for JayRandr {
}
fn set_mode(&self, req: SetMode, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let Some(c) = self.get_output(req.output) else {
let Some(c) = self.get_connector(req.output) else {
return Ok(());
};
c.connector.connector.set_mode(backend::Mode {
width: req.width,
height: req.height,
refresh_rate_millihz: req.refresh_rate_millihz,
let res = c.modify_state(&self.state, |s| {
s.mode = backend::Mode {
width: req.width,
height: req.height,
refresh_rate_millihz: req.refresh_rate_millihz,
};
});
if let Err(e) = res {
self.send_error(&format!("Could not modify connector mode: {}", ErrorFmt(e)));
}
Ok(())
}
@ -378,7 +386,10 @@ impl JayRandrRequestHandler for JayRandr {
let Some(c) = self.get_connector(req.output) else {
return Ok(());
};
c.connector.set_enabled(req.enabled != 0);
let res = c.modify_state(&self.state, |s| s.enabled = req.enabled != 0);
if let Err(e) = res {
self.send_error(&format!("Could not en/disable connector: {}", ErrorFmt(e)));
}
Ok(())
}
@ -391,7 +402,13 @@ impl JayRandrRequestHandler for JayRandr {
1 => Some(false),
_ => Some(true),
};
c.connector.set_non_desktop_override(non_desktop);
c.connector.before_non_desktop_override_update(non_desktop);
let res = c.modify_state(&self.state, |s| {
s.non_desktop_override = non_desktop;
});
if let Err(e) = res {
self.send_error(&format!("Could not change non-desktop override: {}", e));
}
Ok(())
}
@ -439,10 +456,13 @@ impl JayRandrRequestHandler for JayRandr {
let Some(&format) = named_formats().get(req.format) else {
return Err(JayRandrError::UnknownFormat(req.format.to_string()));
};
let Some(c) = self.get_output_node(req.output) else {
let Some(c) = self.get_connector(req.output) else {
return Ok(());
};
c.global.connector.connector.set_fb_format(format);
let res = c.modify_state(&self.state, |s| s.format = format);
if let Err(e) = res {
self.send_error(&format!("Could not modify connector format: {}", e));
}
Ok(())
}
@ -478,7 +498,16 @@ impl JayRandrRequestHandler for JayRandr {
let Some(c) = self.get_connector(req.output) else {
return Ok(());
};
c.connector.set_colors(cs, tf);
let res = c.modify_state(&self.state, |s| {
s.color_space = cs;
s.transfer_function = tf;
});
if let Err(e) = res {
self.send_error(&format!(
"Could not modify connector colors: {}",
ErrorFmt(e),
));
}
Ok(())
}

View file

@ -161,22 +161,20 @@ impl WlOutputGlobal {
state: &Rc<State>,
connector: &Rc<ConnectorData>,
modes: Vec<backend::Mode>,
mode: &backend::Mode,
width_mm: i32,
height_mm: i32,
output_id: &Rc<OutputId>,
persistent_state: &Rc<PersistentOutputState>,
transfer_functions: Vec<BackendTransferFunction>,
btf: BackendTransferFunction,
color_spaces: Vec<BackendColorSpace>,
bcs: BackendColorSpace,
primaries: Primaries,
luminance: Option<BackendLuminance>,
) -> Self {
let (x, y) = persistent_state.pos.get();
let scale = persistent_state.scale.get();
let connector_state = connector.state.get();
let (width, height) = calculate_logical_size(
(mode.width, mode.height),
(connector_state.mode.width, connector_state.mode.height),
persistent_state.transform.get(),
scale,
);
@ -186,8 +184,8 @@ impl WlOutputGlobal {
connector: connector.clone(),
pos: Cell::new(Rect::new_sized(x, y, width, height).unwrap()),
output_id: output_id.clone(),
mode: Cell::new(*mode),
refresh_nsec: Cell::new(mode.refresh_nsec()),
mode: Cell::new(connector_state.mode),
refresh_nsec: Cell::new(connector_state.mode.refresh_nsec()),
modes,
formats: CloneCell::new(Rc::new(vec![])),
format: Cell::new(XRGB8888),
@ -203,8 +201,8 @@ impl WlOutputGlobal {
persistent: persistent_state.clone(),
opt: Default::default(),
damage_matrix: Default::default(),
btf: Cell::new(btf),
bcs: Cell::new(bcs),
btf: Cell::new(connector_state.transfer_function),
bcs: Cell::new(connector_state.color_space),
color_description: CloneCell::new(state.color_manager.srgb_srgb().clone()),
linear_color_description: CloneCell::new(state.color_manager.srgb_linear().clone()),
color_description_listeners: Default::default(),