output: Store position as u32 and offset bad configs

This commit is contained in:
Victoria Brekenfeld 2024-06-26 13:05:25 +02:00 committed by Victoria Brekenfeld
parent 9cd553e128
commit 26ccb653b7
5 changed files with 66 additions and 18 deletions

View file

@ -22,7 +22,7 @@ use smithay::{
rustix::fs::OFlags,
wayland_server::{protocol::wl_buffer::WlBuffer, DisplayHandle, Weak},
},
utils::{DevPath, DeviceFd, Transform},
utils::{DevPath, DeviceFd, Point, Transform},
wayland::drm_lease::{DrmLease, DrmLeaseState},
};
use tracing::{error, info, warn};
@ -222,7 +222,7 @@ impl State {
let connectors = device.enumerate_surfaces()?.added; // There are no removed outputs on newly added devices
let mut wl_outputs = Vec::new();
let mut w = self.common.shell.read().unwrap().global_space().size.w;
let mut w = self.common.shell.read().unwrap().global_space().size.w as u32;
{
for (conn, maybe_crtc) in connectors {
@ -237,7 +237,7 @@ impl State {
) {
Ok((output, should_expose)) => {
if should_expose {
w += output.config().mode_size().w;
w += output.config().mode_size().w as u32;
wl_outputs.push(output.clone());
}
device.outputs.insert(conn, output);
@ -286,7 +286,7 @@ impl State {
if let Some(device) = backend.drm_devices.get_mut(&drm_node) {
let changes = device.enumerate_surfaces()?;
let mut w = self.common.shell.read().unwrap().global_space().size.w;
let mut w = self.common.shell.read().unwrap().global_space().size.w as u32;
for conn in changes.removed {
// contains conns with updated crtcs, just drop the surface and re-create
if let Some(pos) = device
@ -306,7 +306,11 @@ impl State {
{
let surface = device.surfaces.remove(&crtc).unwrap();
// TODO: move up later outputs?
w -= surface.output.current_mode().map(|m| m.size.w).unwrap_or(0);
w -= surface
.output
.current_mode()
.map(|m| m.size.w as u32)
.unwrap_or(0);
}
if !changes.added.iter().any(|(c, _)| c == &conn) {
@ -331,7 +335,7 @@ impl State {
) {
Ok((output, should_expose)) => {
if should_expose {
w += output.config().mode_size().w;
w += output.config().mode_size().w as u32;
outputs_added.push(output.clone());
}
@ -472,7 +476,7 @@ impl Device {
primary_node: Option<&DrmNode>,
conn: connector::Handle,
maybe_crtc: Option<crtc::Handle>,
position: (i32, i32),
position: (u32, u32),
evlh: &LoopHandle<'static, State>,
shell: Arc<RwLock<Shell>>,
startup_done: Arc<AtomicBool>,
@ -608,7 +612,7 @@ fn populate_modes(
drm: &mut DrmDevice,
output: &Output,
conn: connector::Handle,
position: (i32, i32),
position: (u32, u32),
) -> Result<()> {
let conn_info = drm.get_connector(conn, false)?;
let max_bpc = drm_helpers::get_max_bpc(drm, conn)?.map(|(_val, range)| range.end.min(16));
@ -638,7 +642,7 @@ fn populate_modes(
// TODO: Readout property for monitor rotation
Some(Transform::Normal),
None,
Some(position.into()),
Some(Point::from((position.0 as i32, position.1 as i32))),
);
let mut output_config = output

View file

@ -642,7 +642,7 @@ impl KmsState {
}
// add new ones
let mut w = shell.read().unwrap().global_space().size.w;
let mut w = shell.read().unwrap().global_space().size.w as u32;
if !test_only {
for (conn, crtc) in new_pairings {
let (output, _) = device.connector_added(
@ -655,7 +655,7 @@ impl KmsState {
startup_done.clone(),
)?;
if output.mirroring().is_none() {
w += output.config().mode_size().w;
w += output.config().mode_size().w as u32;
}
all_outputs.push(output);
}

View file

@ -136,7 +136,7 @@ pub struct OutputConfig {
pub scale: f64,
#[serde(with = "TransformDef")]
pub transform: Transform,
pub position: (i32, i32),
pub position: (u32, u32),
#[serde(default = "default_enabled")]
pub enabled: OutputState,
#[serde(default, skip_serializing_if = "Option::is_none")]

View file

@ -57,7 +57,7 @@ use smithay::{
Client, DisplayHandle, Resource,
},
},
utils::{Clock, IsAlive, Monotonic},
utils::{Clock, IsAlive, Monotonic, Point},
wayland::{
alpha_modifier::AlphaModifierState,
compositor::{CompositorClientState, CompositorState, SurfaceData},
@ -306,8 +306,11 @@ impl BackendData {
Some(final_config.transform.into()).filter(|x| *x != output.current_transform());
let scale = Some(final_config.scale)
.filter(|x| *x != output.current_scale().fractional_scale());
let location =
Some(final_config.position.into()).filter(|x| *x != output.current_location());
let location = Some(Point::from((
final_config.position.0 as i32,
final_config.position.1 as i32,
)))
.filter(|x| *x != output.current_location());
output.change_current_state(mode, transform, scale.map(Scale::Fractional), location);
output.set_adaptive_sync(final_config.vrr);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use smithay::output::Output;
use smithay::{output::Output, utils::Point};
use tracing::{error, warn};
use crate::{
@ -31,7 +31,7 @@ impl State {
fn output_configuration(
&mut self,
test_only: bool,
conf: Vec<(Output, OutputConfiguration)>,
mut conf: Vec<(Output, OutputConfiguration)>,
) -> bool {
if conf
.iter()
@ -40,6 +40,47 @@ impl State {
return false; // we don't allow the user to accidentally disable all their outputs
}
// sanitize negative positions
{
let (offset_x, offset_y) = conf.iter().fold((0, 0), |mut offset, (_, conf)| {
if let OutputConfiguration::Enabled {
position: Some(position),
..
} = conf
{
if position.x.is_negative() {
offset.0 = offset.0.max(position.x.abs());
}
if position.y.is_negative() {
offset.1 = offset.1.max(position.y.abs());
}
}
offset
});
if offset_x > 0 || offset_y > 0 {
for (output, conf) in conf.iter_mut() {
if let OutputConfiguration::Enabled {
ref mut position, ..
} = conf
{
let current_config = output
.user_data()
.get::<RefCell<OutputConfig>>()
.unwrap()
.borrow();
*position = Some(
position.unwrap_or(Point::from((
current_config.position.0 as i32,
current_config.position.1 as i32,
))) + Point::from((offset_x, offset_y)),
);
}
}
}
}
let mut backups = Vec::new();
for (output, conf) in &conf {
{
@ -76,7 +117,7 @@ impl State {
current_config.transform = *transform;
}
if let Some(position) = position {
current_config.position = (*position).into();
current_config.position = (position.x as u32, position.y as u32);
}
if let Some(vrr) = adaptive_sync {
current_config.vrr = *vrr;