mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 07:05:56 +00:00
fix: ceil integer scale for better text rendering on fractional scaling
This commit is contained in:
parent
c430938bf1
commit
3eea09b2f6
4 changed files with 121 additions and 22 deletions
|
|
@ -10,6 +10,46 @@ pub enum RenderState {
|
|||
Dirty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct FractionalScaleConfig {
|
||||
pub render_scale: f32,
|
||||
pub render_physical_size: PhysicalSize,
|
||||
pub logical_width: f32,
|
||||
pub logical_height: f32,
|
||||
}
|
||||
|
||||
impl FractionalScaleConfig {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
#[must_use]
|
||||
pub fn new(logical_width: f32, logical_height: f32, scale_factor: f32) -> Self {
|
||||
let render_scale = Self::render_scale(scale_factor);
|
||||
Self {
|
||||
render_scale,
|
||||
render_physical_size: PhysicalSize::new(
|
||||
(logical_width * render_scale) as u32,
|
||||
(logical_height * render_scale) as u32,
|
||||
),
|
||||
logical_width,
|
||||
logical_height,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn render_scale(scale_factor: f32) -> f32 {
|
||||
scale_factor.ceil()
|
||||
}
|
||||
|
||||
pub fn apply_to<W: RenderableWindow + ?Sized>(&self, window: &W) {
|
||||
window.set_scale_factor(self.render_scale);
|
||||
window.set_size_with_exact_logical(
|
||||
self.render_physical_size,
|
||||
self.logical_width,
|
||||
self.logical_height,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RenderableWindow: WindowAdapter {
|
||||
fn render_frame_if_dirty(&self) -> Result<()>;
|
||||
fn set_scale_factor(&self, scale_factor: f32);
|
||||
|
|
@ -31,4 +71,16 @@ pub trait RenderableWindow: WindowAdapter {
|
|||
size: size.to_logical(self.scale_factor()),
|
||||
});
|
||||
}
|
||||
|
||||
fn set_size_with_exact_logical(
|
||||
&self,
|
||||
physical: slint::PhysicalSize,
|
||||
logical_width: f32,
|
||||
logical_height: f32,
|
||||
) {
|
||||
self.size_cell().set(physical);
|
||||
self.window().dispatch_event(WindowEvent::Resized {
|
||||
size: slint::LogicalSize::new(logical_width, logical_height),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::callbacks::{LockCallbackContext, LockCallbackExt, LockPropertyOperationExt};
|
||||
use crate::errors::Result;
|
||||
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
||||
use crate::rendering::femtovg::renderable_window::RenderableWindow;
|
||||
use crate::rendering::femtovg::renderable_window::{FractionalScaleConfig, RenderableWindow};
|
||||
use crate::rendering::slint_integration::platform::CustomSlintPlatform;
|
||||
use crate::wayland::session_lock::lock_surface::LockSurface;
|
||||
use crate::wayland::surfaces::component_state::ComponentState;
|
||||
|
|
@ -308,7 +308,22 @@ impl ActiveLockSurface {
|
|||
scale_factor: f32,
|
||||
) {
|
||||
match mode {
|
||||
LockScalingMode::FractionalWithViewport | LockScalingMode::FractionalOnly => {
|
||||
LockScalingMode::FractionalWithViewport => {
|
||||
let config = FractionalScaleConfig::new(
|
||||
dimensions.logical_width() as f32,
|
||||
dimensions.logical_height() as f32,
|
||||
scale_factor,
|
||||
);
|
||||
info!(
|
||||
"Lock FractionalWithViewport: render scale {} (from {}), physical {}x{}",
|
||||
config.render_scale,
|
||||
scale_factor,
|
||||
config.render_physical_size.width,
|
||||
config.render_physical_size.height
|
||||
);
|
||||
config.apply_to(self.window.as_ref());
|
||||
}
|
||||
LockScalingMode::FractionalOnly => {
|
||||
RenderableWindow::set_scale_factor(self.window.as_ref(), scale_factor);
|
||||
self.window.set_size(WindowSize::Logical(LogicalSize::new(
|
||||
dimensions.logical_width() as f32,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::errors::{LayerShikaError, Result};
|
||||
use crate::rendering::egl::context_factory::RenderContextFactory;
|
||||
use crate::rendering::femtovg::{popup_window::PopupWindow, renderable_window::RenderableWindow};
|
||||
use crate::rendering::femtovg::popup_window::PopupWindow;
|
||||
use crate::rendering::femtovg::renderable_window::{FractionalScaleConfig, RenderableWindow};
|
||||
use crate::wayland::surfaces::display_metrics::{DisplayMetrics, SharedDisplayMetrics};
|
||||
use layer_shika_domain::dimensions::LogicalSize as DomainLogicalSize;
|
||||
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
||||
|
|
@ -9,7 +10,7 @@ use layer_shika_domain::value_objects::popup_behavior::ConstraintAdjustment;
|
|||
use layer_shika_domain::value_objects::popup_config::PopupConfig;
|
||||
use layer_shika_domain::value_objects::popup_position::PopupPosition;
|
||||
use log::info;
|
||||
use slint::{platform::femtovg_renderer::FemtoVGRenderer, PhysicalSize, WindowSize};
|
||||
use slint::{platform::femtovg_renderer::FemtoVGRenderer, PhysicalSize};
|
||||
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
|
|
@ -200,8 +201,9 @@ impl PopupManager {
|
|||
pub fn update_scale_factor(&self, scale_factor: f32) {
|
||||
self.scale_factor.set(scale_factor);
|
||||
|
||||
let render_scale = FractionalScaleConfig::render_scale(scale_factor);
|
||||
for popup in self.state.borrow().popups.values() {
|
||||
popup.window.set_scale_factor(scale_factor);
|
||||
popup.window.set_scale_factor(render_scale);
|
||||
}
|
||||
self.mark_all_popups_dirty();
|
||||
}
|
||||
|
|
@ -322,11 +324,16 @@ impl PopupManager {
|
|||
|
||||
let popup_window = PopupWindow::new_with_callback(renderer, on_close);
|
||||
popup_window.set_popup_id(popup_id.to_handle());
|
||||
popup_window.set_scale_factor(scale_factor);
|
||||
popup_window.set_size(WindowSize::Logical(slint::LogicalSize::new(
|
||||
params.width,
|
||||
params.height,
|
||||
)));
|
||||
|
||||
let config = FractionalScaleConfig::new(params.width, params.height, scale_factor);
|
||||
info!(
|
||||
"Popup using render scale {} (from {}), render_physical {}x{}",
|
||||
config.render_scale,
|
||||
scale_factor,
|
||||
config.render_physical_size.width,
|
||||
config.render_physical_size.height
|
||||
);
|
||||
config.apply_to(popup_window.as_ref());
|
||||
|
||||
let mut state = self.state.borrow_mut();
|
||||
state.popups.insert(
|
||||
|
|
@ -489,7 +496,6 @@ impl PopupManager {
|
|||
ActiveWindow::None
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn update_scale_for_fractional_scale_object(
|
||||
&self,
|
||||
fractional_scale_proxy: &WpFractionalScaleV1,
|
||||
|
|
@ -500,8 +506,12 @@ impl PopupManager {
|
|||
if let Some(popup_key) = self.find_popup_key_by_fractional_scale_id(&fractional_scale_id) {
|
||||
if let Some(popup_surface) = self.get_popup_window(popup_key) {
|
||||
let new_scale_factor = DisplayMetrics::scale_factor_from_120ths(scale_120ths);
|
||||
info!("Updating popup scale factor to {new_scale_factor} ({scale_120ths}x)");
|
||||
popup_surface.set_scale_factor(new_scale_factor);
|
||||
let render_scale = FractionalScaleConfig::render_scale(new_scale_factor);
|
||||
info!(
|
||||
"Updating popup scale factor to {} (render scale {}, from {}x)",
|
||||
new_scale_factor, render_scale, scale_120ths
|
||||
);
|
||||
popup_surface.set_scale_factor(render_scale);
|
||||
popup_surface.request_redraw();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::errors::Result;
|
||||
use crate::rendering::femtovg::renderable_window::RenderableWindow;
|
||||
use crate::rendering::femtovg::renderable_window::{FractionalScaleConfig, RenderableWindow};
|
||||
use crate::wayland::managed_proxies::{
|
||||
ManagedWlSurface, ManagedZwlrLayerSurfaceV1, ManagedWpFractionalScaleV1, ManagedWpViewport,
|
||||
};
|
||||
|
|
@ -92,12 +92,19 @@ impl<W: RenderableWindow> SurfaceRenderer<W> {
|
|||
) {
|
||||
match mode {
|
||||
ScalingMode::FractionalWithViewport => {
|
||||
self.window.set_scale_factor(scale_factor);
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||
dimensions.logical_width() as f32,
|
||||
dimensions.logical_height() as f32,
|
||||
)));
|
||||
let config = FractionalScaleConfig::new(
|
||||
dimensions.logical_width() as f32,
|
||||
dimensions.logical_height() as f32,
|
||||
scale_factor,
|
||||
);
|
||||
info!(
|
||||
"FractionalWithViewport: render scale {} (from {}), physical {}x{}",
|
||||
config.render_scale,
|
||||
scale_factor,
|
||||
config.render_physical_size.width,
|
||||
config.render_physical_size.height
|
||||
);
|
||||
config.apply_to(self.window.as_ref());
|
||||
}
|
||||
ScalingMode::FractionalOnly => {
|
||||
self.window
|
||||
|
|
@ -154,15 +161,30 @@ impl<W: RenderableWindow> SurfaceRenderer<W> {
|
|||
self.apply_surface_dimensions(dimensions, scale_factor);
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn apply_surface_dimensions(&mut self, dimensions: SurfaceDimensions, scale_factor: f32) {
|
||||
let scaling_mode = self.determine_scaling_mode();
|
||||
|
||||
let render_physical_size = match scaling_mode {
|
||||
ScalingMode::FractionalWithViewport => {
|
||||
FractionalScaleConfig::new(
|
||||
dimensions.logical_width() as f32,
|
||||
dimensions.logical_height() as f32,
|
||||
scale_factor,
|
||||
)
|
||||
.render_physical_size
|
||||
}
|
||||
_ => dimensions.to_slint_physical_size(),
|
||||
};
|
||||
|
||||
info!(
|
||||
"Updating window size: logical {}x{}, physical {}x{}, scale {}, buffer_scale {}, mode {:?}",
|
||||
"Updating window size: logical {}x{}, physical {}x{}, render_physical {}x{}, scale {}, buffer_scale {}, mode {:?}",
|
||||
dimensions.logical_width(),
|
||||
dimensions.logical_height(),
|
||||
dimensions.physical_width(),
|
||||
dimensions.physical_height(),
|
||||
render_physical_size.width,
|
||||
render_physical_size.height,
|
||||
scale_factor,
|
||||
dimensions.buffer_scale(),
|
||||
scaling_mode
|
||||
|
|
@ -173,7 +195,7 @@ impl<W: RenderableWindow> SurfaceRenderer<W> {
|
|||
|
||||
info!("Window physical size: {:?}", self.window.size());
|
||||
|
||||
self.size = dimensions.to_slint_physical_size();
|
||||
self.size = render_physical_size;
|
||||
self.logical_size = dimensions.to_slint_logical_size();
|
||||
RenderableWindow::request_redraw(self.window.as_ref());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue