diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-09-21 13:48:32 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-09-21 13:48:50 +0400 |
| commit | 109668fa30bf65e56a2723ff29bcadc3e9a6e4ca (patch) | |
| tree | d95fbf3bdb3c2c14683a34d8bb7203b7dae4820d /src | |
| parent | cfa73c153cc6ae2f1c21dcbbc8e755b265babbd2 (diff) | |
| download | niri-109668fa30bf65e56a2723ff29bcadc3e9a6e4ca.tar.gz niri-109668fa30bf65e56a2723ff29bcadc3e9a6e4ca.tar.bz2 niri-109668fa30bf65e56a2723ff29bcadc3e9a6e4ca.zip | |
Add output configuration & integer scaling support
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/tty.rs | 16 | ||||
| -rw-r--r-- | src/backend/winit.rs | 14 | ||||
| -rw-r--r-- | src/config.rs | 27 | ||||
| -rw-r--r-- | src/layout.rs | 23 | ||||
| -rw-r--r-- | src/niri.rs | 37 |
5 files changed, 93 insertions, 24 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 9f126507..bce16ff0 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -21,7 +21,7 @@ use smithay::backend::session::libseat::LibSeatSession; use smithay::backend::session::{Event as SessionEvent, Session}; use smithay::backend::udev::{self, UdevBackend, UdevEvent}; use smithay::desktop::utils::OutputPresentationFeedback; -use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpixel}; +use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpixel, Scale}; use smithay::reexports::calloop::{Dispatcher, LoopHandle, RegistrationToken}; use smithay::reexports::drm::control::{ connector, crtc, Mode as DrmMode, ModeFlags, ModeTypeFlags, @@ -500,6 +500,15 @@ impl Tty { ); debug!("connecting connector: {output_name}"); + let config = self + .config + .borrow() + .outputs + .iter() + .find(|o| o.name == output_name) + .cloned() + .unwrap_or_default(); + let device = self.output_device.as_mut().unwrap(); let mut mode = connector.modes().get(0); @@ -534,6 +543,9 @@ impl Tty { .map(|info| (info.manufacturer, info.model)) .unwrap_or_else(|| ("Unknown".into(), "Unknown".into())); + let scale = config.scale.clamp(0.1, 10.); + let scale = scale.max(1.).round() as i32; + let output = Output::new( output_name.clone(), PhysicalProperties { @@ -544,7 +556,7 @@ impl Tty { }, ); let wl_mode = Mode::from(*mode); - output.change_current_state(Some(wl_mode), None, None, Some((0, 0).into())); + output.change_current_state(Some(wl_mode), None, Some(Scale::Integer(scale)), None); output.set_preferred(wl_mode); output.user_data().insert_if_missing(|| TtyOutputState { diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 9f591e71..99cfe7db 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -8,7 +8,7 @@ use smithay::backend::renderer::damage::OutputDamageTracker; use smithay::backend::renderer::gles::GlesRenderer; use smithay::backend::renderer::{DebugFlags, Renderer}; use smithay::backend::winit::{self, WinitError, WinitEvent, WinitGraphicsBackend}; -use smithay::output::{Mode, Output, PhysicalProperties, Subpixel}; +use smithay::output::{Mode, Output, PhysicalProperties, Scale, Subpixel}; use smithay::reexports::calloop::timer::{TimeoutAction, Timer}; use smithay::reexports::calloop::LoopHandle; use smithay::reexports::wayland_protocols::wp::presentation_time::server::wp_presentation_feedback; @@ -38,6 +38,16 @@ impl Winit { .with_title("niri"); let (backend, mut winit_event_loop) = winit::init_from_builder(builder).unwrap(); + let output_config = config + .borrow() + .outputs + .iter() + .find(|o| o.name == "winit") + .cloned() + .unwrap_or_default(); + let scale = output_config.scale.clamp(0.1, 10.); + let scale = scale.max(1.).round() as i32; + let mode = Mode { size: backend.window_size().physical_size, refresh: 60_000, @@ -55,8 +65,8 @@ impl Winit { output.change_current_state( Some(mode), Some(Transform::Flipped180), + Some(Scale::Integer(scale)), None, - Some((0, 0).into()), ); output.set_preferred(mode); diff --git a/src/config.rs b/src/config.rs index 50ea2451..88773fd3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,6 +11,8 @@ use smithay::input::keyboard::Keysym; pub struct Config { #[knuffel(child, default)] pub input: Input, + #[knuffel(children(name = "output"))] + pub outputs: Vec<Output>, #[knuffel(child, default)] pub binds: Binds, #[knuffel(child, default)] @@ -62,6 +64,23 @@ pub struct Touchpad { pub accel_speed: f64, } +#[derive(knuffel::Decode, Debug, Clone, PartialEq)] +pub struct Output { + #[knuffel(argument)] + pub name: String, + #[knuffel(child, unwrap(argument), default = 1.)] + pub scale: f64, +} + +impl Default for Output { + fn default() -> Self { + Self { + name: String::new(), + scale: 1., + } + } +} + #[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)] pub struct Binds(#[knuffel(children)] pub Vec<Bind>); @@ -263,6 +282,10 @@ mod tests { } } + output "eDP-1" { + scale 2.0 + } + binds { Mod+T { spawn "alacritty"; } Mod+Q { close-window; } @@ -293,6 +316,10 @@ mod tests { accel_speed: 0.2, }, }, + outputs: vec![Output { + name: "eDP-1".to_owned(), + scale: 2., + }], binds: Binds(vec![ Bind { key: Key { diff --git a/src/layout.rs b/src/layout.rs index f7f00b46..2c0ef30f 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -1231,6 +1231,7 @@ impl Monitor<Window> { &self, renderer: &mut GlesRenderer, ) -> Vec<MonitorRenderElement<GlesRenderer>> { + let output_scale = Scale::from(self.output.current_scale().fractional_scale()); let output_transform = self.output.current_transform(); let output_mode = self.output.current_mode().unwrap(); let output_size = output_transform.transform_size(output_mode.size); @@ -1251,7 +1252,7 @@ impl Monitor<Window> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - 1., + output_scale, Rectangle::from_loc_and_size((0, 0), output_size), )?, (0, -offset), @@ -1262,7 +1263,7 @@ impl Monitor<Window> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - 1., + output_scale, Rectangle::from_loc_and_size((0, 0), output_size), )?, (0, -offset + output_size.h), @@ -1279,7 +1280,7 @@ impl Monitor<Window> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - 1., + output_scale, Rectangle::from_loc_and_size((0, 0), output_size), )?, (0, 0), @@ -1823,6 +1824,14 @@ impl Workspace<Window> { return vec![]; } + // FIXME: workspaces should probably cache their last used scale so they can be correctly + // rendered even with no outputs connected. + let output_scale = self + .output + .as_ref() + .map(|o| Scale::from(o.current_scale().fractional_scale())) + .unwrap_or(Scale::from(1.)); + let mut rv = vec![]; let view_pos = self.view_pos(); @@ -1840,8 +1849,8 @@ impl Workspace<Window> { } rv.extend(active_win.render_elements( renderer, - win_pos.to_physical(1), - Scale::from(1.), + win_pos.to_physical_precise_round(output_scale), + output_scale, 1., )); @@ -1862,8 +1871,8 @@ impl Workspace<Window> { rv.extend(win.render_elements( renderer, - win_pos.to_physical(1), - Scale::from(1.), + win_pos.to_physical_precise_round(output_scale), + output_scale, 1., )); } diff --git a/src/niri.rs b/src/niri.rs index 100c388a..0ae5e096 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -799,6 +799,7 @@ impl Niri { renderer: &mut GlesRenderer, output: &Output, ) -> Vec<OutputRenderElements<GlesRenderer>> { + let output_scale = Scale::from(output.current_scale().fractional_scale()); let output_pos = self.global_space.output_geometry(output).unwrap().loc; let pointer_pos = self.seat.get_pointer().unwrap().current_location() - output_pos.to_f64(); @@ -825,7 +826,7 @@ impl Niri { } else { default_hotspot }; - let pointer_pos = (pointer_pos - hotspot.to_f64()).to_physical_precise_round(1.); + let pointer_pos = (pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale); let mut pointer_elements = match &self.cursor_image { CursorImageStatus::Hidden => vec![], @@ -843,7 +844,7 @@ impl Niri { renderer, surface, pointer_pos, - 1., + output_scale, 1., Kind::Cursor, ), @@ -854,7 +855,7 @@ impl Niri { renderer, dnd_icon, pointer_pos, - 1., + output_scale, 1., Kind::Unspecified, )); @@ -871,6 +872,8 @@ impl Niri { ) -> Vec<OutputRenderElements<GlesRenderer>> { let _span = tracy_client::span!("Niri::render"); + let output_scale = Scale::from(output.current_scale().fractional_scale()); + // Get monitor elements. let mon = self.monitor_set.monitor_for_output(output).unwrap(); let monitor_elements = mon.render_elements(renderer); @@ -901,8 +904,8 @@ impl Niri { surface .render_elements( renderer, - loc.to_physical_precise_round(1.), - Scale::from(1.), + loc.to_physical_precise_round(output_scale), + output_scale, 1., ) .into_iter() @@ -926,8 +929,8 @@ impl Niri { surface .render_elements( renderer, - loc.to_physical_precise_round(1.), - Scale::from(1.), + loc.to_physical_precise_round(output_scale), + output_scale, 1., ) .into_iter() @@ -1084,6 +1087,7 @@ impl Niri { let _span = tracy_client::span!("Niri::send_for_screen_cast"); let size = output.current_mode().unwrap().size; + let scale = Scale::from(output.current_scale().fractional_scale()); for cast in &mut self.casts { if !cast.is_active.get() { @@ -1119,7 +1123,7 @@ impl Niri { let dmabuf = cast.dmabufs.borrow()[&fd].clone(); // FIXME: Hidden / embedded / metadata cursor - render_to_dmabuf(backend.renderer(), dmabuf, size, elements).unwrap(); + render_to_dmabuf(backend.renderer(), dmabuf, size, scale, elements).unwrap(); let maxsize = data.as_raw().maxsize; let chunk = data.chunk_mut(); @@ -1139,8 +1143,9 @@ impl Niri { let _span = tracy_client::span!("Niri::screenshot"); let size = output.current_mode().unwrap().size; + let scale = Scale::from(output.current_scale().fractional_scale()); let elements = self.render(renderer, output, true); - let pixels = render_to_vec(renderer, size, &elements)?; + let pixels = render_to_vec(renderer, size, scale, &elements)?; let path = make_screenshot_path().context("error making screenshot path")?; debug!("saving screenshot to {path:?}"); @@ -1174,6 +1179,7 @@ impl Niri { let outputs: Vec<_> = self.global_space.outputs().cloned().collect(); for output in outputs { let geom = self.global_space.output_geometry(&output).unwrap(); + // FIXME: this does not work when outputs can have non-1 scale. let geom = geom.to_physical(1); size.w = max(size.w, geom.loc.x + geom.size.w); @@ -1185,7 +1191,8 @@ impl Niri { })); } - let pixels = render_to_vec(renderer, size, &elements)?; + // FIXME: scale. + let pixels = render_to_vec(renderer, size, Scale::from(1.), &elements)?; let path = make_screenshot_path().context("error making screenshot path")?; debug!("saving screenshot to {path:?}"); @@ -1232,6 +1239,7 @@ impl ClientData for ClientState { fn render_and_download( renderer: &mut GlesRenderer, size: Size<i32, Physical>, + scale: Scale<f64>, elements: &[impl RenderElement<GlesRenderer>], ) -> anyhow::Result<GlesMapping> { let _span = tracy_client::span!("render_and_download"); @@ -1255,7 +1263,7 @@ fn render_and_download( for element in elements.iter().rev() { let src = element.src(); - let dst = element.geometry(Scale::from(1.)); + let dst = element.geometry(scale); element .draw(&mut frame, src, dst, &[output_rect]) .context("error drawing element")?; @@ -1273,11 +1281,13 @@ fn render_and_download( fn render_to_vec( renderer: &mut GlesRenderer, size: Size<i32, Physical>, + scale: Scale<f64>, elements: &[impl RenderElement<GlesRenderer>], ) -> anyhow::Result<Vec<u8>> { let _span = tracy_client::span!("render_to_vec"); - let mapping = render_and_download(renderer, size, elements).context("error rendering")?; + let mapping = + render_and_download(renderer, size, scale, elements).context("error rendering")?; let copy = renderer .map_texture(&mapping) .context("error mapping texture")?; @@ -1288,6 +1298,7 @@ fn render_to_dmabuf( renderer: &mut GlesRenderer, dmabuf: Dmabuf, size: Size<i32, Physical>, + scale: Scale<f64>, elements: &[OutputRenderElements<GlesRenderer>], ) -> anyhow::Result<()> { let _span = tracy_client::span!("render_to_dmabuf"); @@ -1305,7 +1316,7 @@ fn render_to_dmabuf( for element in elements.iter().rev() { let src = element.src(); - let dst = element.geometry(Scale::from(1.)); + let dst = element.geometry(scale); element .draw(&mut frame, src, dst, &[output_rect]) .context("error drawing element")?; |
