From 997119c44338ad96a40b4a1d6e958f77062a37ef Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Wed, 29 May 2024 14:29:37 +0300 Subject: Enable fractional scaling --- resources/default-config.kdl | 2 +- src/handlers/mod.rs | 16 ++++++++++------ src/niri.rs | 15 ++++++++++----- src/utils/mod.rs | 10 ++++++---- wiki/Configuration:-Outputs.md | 4 ++-- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/resources/default-config.kdl b/resources/default-config.kdl index 800e72c4..ad612d2c 100644 --- a/resources/default-config.kdl +++ b/resources/default-config.kdl @@ -65,7 +65,7 @@ input { // Run `niri msg outputs` while inside a niri instance to list all outputs and their modes. mode "1920x1080@120.030" - // Scale is a floating-point number, but at the moment only integer values work. + // You can use integer or fractional scale, for example use 1.5 for 150% scale. scale 2.0 // Transform allows to rotate the output counter-clockwise, valid values are: diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 0a4ce334..3fccfae7 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -27,6 +27,7 @@ use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportN use smithay::wayland::drm_lease::{ DrmLease, DrmLeaseBuilder, DrmLeaseHandler, DrmLeaseRequest, DrmLeaseState, LeaseRejected, }; +use smithay::wayland::fractional_scale::FractionalScaleHandler; use smithay::wayland::idle_inhibit::IdleInhibitHandler; use smithay::wayland::idle_notify::{IdleNotifierHandler, IdleNotifierState}; use smithay::wayland::input_method::{InputMethodHandler, PopupSurface}; @@ -53,12 +54,12 @@ use smithay::wayland::xdg_activation::{ }; use smithay::{ delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf, - delegate_drm_lease, delegate_idle_inhibit, delegate_idle_notify, delegate_input_method_manager, - delegate_output, delegate_pointer_constraints, delegate_pointer_gestures, - delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat, - delegate_security_context, delegate_session_lock, delegate_tablet_manager, - delegate_text_input_manager, delegate_viewporter, delegate_virtual_keyboard_manager, - delegate_xdg_activation, + delegate_drm_lease, delegate_fractional_scale, delegate_idle_inhibit, delegate_idle_notify, + delegate_input_method_manager, delegate_output, delegate_pointer_constraints, + delegate_pointer_gestures, delegate_presentation, delegate_primary_selection, + delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock, + delegate_tablet_manager, delegate_text_input_manager, delegate_viewporter, + delegate_virtual_keyboard_manager, delegate_xdg_activation, }; use crate::niri::{ClientState, State}; @@ -539,3 +540,6 @@ impl XdgActivationHandler for State { } } delegate_xdg_activation!(State); + +impl FractionalScaleHandler for State {} +delegate_fractional_scale!(State); diff --git a/src/niri.rs b/src/niri.rs index e7bab37d..b4f3a23a 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -66,6 +66,7 @@ use smithay::wayland::compositor::{ }; use smithay::wayland::cursor_shape::CursorShapeManagerState; use smithay::wayland::dmabuf::DmabufState; +use smithay::wayland::fractional_scale::FractionalScaleManagerState; use smithay::wayland::idle_inhibit::IdleInhibitManagerState; use smithay::wayland::idle_notify::IdleNotifierState; use smithay::wayland::input_method::{InputMethodManagerState, InputMethodSeat}; @@ -200,6 +201,7 @@ pub struct Niri { pub shm_state: ShmState, pub output_manager_state: OutputManagerState, pub dmabuf_state: DmabufState, + pub fractional_scale_manager_state: FractionalScaleManagerState, pub seat_state: SeatState, pub tablet_state: TabletManagerState, pub text_input_state: TextInputManagerState, @@ -1051,7 +1053,7 @@ impl State { let resolution = output.current_mode().unwrap().size; guess_monitor_scale(size_mm, resolution) }); - let scale = scale.clamp(1., 10.).ceil() as i32; + let scale = scale.clamp(1., 10.); let mut transform = config .map(|c| ipc_transform_to_smithay(c.transform)) @@ -1061,13 +1063,13 @@ impl State { transform = Transform::Flipped180; } - if output.current_scale().integer_scale() != scale + if output.current_scale().fractional_scale() != scale || output.current_transform() != transform { output.change_current_state( None, Some(transform), - Some(output::Scale::Integer(scale)), + Some(output::Scale::Fractional(scale)), None, ); self.niri.ipc_outputs_changed = true; @@ -1325,6 +1327,8 @@ impl Niri { let output_manager_state = OutputManagerState::new_with_xdg_output::(&display_handle); let dmabuf_state = DmabufState::new(); + let fractional_scale_manager_state = + FractionalScaleManagerState::new::(&display_handle); let mut seat_state = SeatState::new(); let tablet_state = TabletManagerState::new::(&display_handle); let pointer_gestures_state = PointerGesturesState::new::(&display_handle); @@ -1513,6 +1517,7 @@ impl Niri { shm_state, output_manager_state, dmabuf_state, + fractional_scale_manager_state, seat_state, tablet_state, pointer_gestures_state, @@ -1731,7 +1736,7 @@ impl Niri { let resolution = output.current_mode().unwrap().size; guess_monitor_scale(size_mm, resolution) }); - let scale = scale.clamp(1., 10.).ceil() as i32; + let scale = scale.clamp(1., 10.); let mut transform = c .map(|c| ipc_transform_to_smithay(c.transform)) .unwrap_or(Transform::Normal); @@ -1745,7 +1750,7 @@ impl Niri { output.change_current_state( None, Some(transform), - Some(output::Scale::Integer(scale)), + Some(output::Scale::Fractional(scale)), None, ); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 807244fa..3c6a36e0 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -96,13 +96,15 @@ pub fn to_physical_precise_round(scale: f64, logical: impl Coordi } pub fn output_size(output: &Output) -> Size { - let output_scale = output.current_scale().integer_scale(); + let output_scale = output.current_scale().fractional_scale(); let output_transform = output.current_transform(); let output_mode = output.current_mode().unwrap(); - output_transform - .transform_size(output_mode.size) - .to_logical(output_scale) + // Like in LayerMap::arrange(). + // + // FIXME: return fractional logical size. + let logical_size = output_mode.size.to_f64().to_logical(output_scale); + output_transform.transform_size(logical_size.to_i32_round()) } pub fn logical_output(output: &Output) -> niri_ipc::LogicalOutput { diff --git a/wiki/Configuration:-Outputs.md b/wiki/Configuration:-Outputs.md index a13f0dd4..8a63a6bd 100644 --- a/wiki/Configuration:-Outputs.md +++ b/wiki/Configuration:-Outputs.md @@ -68,10 +68,10 @@ output "eDP-1" { Set the scale of the monitor. -This is a floating-point number to enable fractional scaling in the future, but at the moment only integer scale values will work. - Since: 0.1.6 If scale is unset, niri will guess an appropriate scale based on the physical dimensions and the resolution of the monitor. +Since: 0.1.7 You can use fractional scale values, for example `scale 1.5` for 150% scale. + ``` output "eDP-1" { scale 2.0 -- cgit