mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-10-28 14:14:23 +00:00
refactor: extract surface dimensions and scaling mode
This commit is contained in:
parent
f5338750e6
commit
0cc906c546
3 changed files with 122 additions and 59 deletions
|
|
@ -4,6 +4,7 @@ mod globals;
|
|||
mod macros;
|
||||
mod state;
|
||||
mod surface;
|
||||
mod surface_dimensions;
|
||||
mod system;
|
||||
|
||||
pub use system::WindowingSystem;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,18 @@ use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1:
|
|||
use wayland_protocols::wp::viewporter::client::wp_viewport::WpViewport;
|
||||
use crate::rendering::femtovg_window::FemtoVGWindow;
|
||||
use crate::errors::{LayerShikaError, Result};
|
||||
use crate::windowing::surface_dimensions::SurfaceDimensions;
|
||||
|
||||
pub mod builder;
|
||||
pub mod dispatches;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ScalingMode {
|
||||
FractionalWithViewport,
|
||||
FractionalOnly,
|
||||
Integer,
|
||||
}
|
||||
|
||||
pub struct WindowState {
|
||||
component_instance: ComponentInstance,
|
||||
surface: Rc<WlSurface>,
|
||||
|
|
@ -77,78 +85,93 @@ impl WindowState {
|
|||
})
|
||||
}
|
||||
|
||||
const fn determine_scaling_mode(&self) -> ScalingMode {
|
||||
if self.fractional_scale.is_some() && self.viewport.is_some() {
|
||||
ScalingMode::FractionalWithViewport
|
||||
} else if self.fractional_scale.is_some() {
|
||||
ScalingMode::FractionalOnly
|
||||
} else {
|
||||
ScalingMode::Integer
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn configure_slint_window(&self, dimensions: &SurfaceDimensions, mode: &ScalingMode) {
|
||||
match mode {
|
||||
ScalingMode::FractionalWithViewport => {
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||
dimensions.logical_width as f32,
|
||||
dimensions.logical_height as f32,
|
||||
)));
|
||||
self.window.set_scale_factor(self.scale_factor);
|
||||
}
|
||||
ScalingMode::FractionalOnly => {
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||
dimensions.logical_width as f32,
|
||||
dimensions.logical_height as f32,
|
||||
)));
|
||||
self.window.set_scale_factor(dimensions.buffer_scale as f32);
|
||||
}
|
||||
ScalingMode::Integer => {
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Physical(dimensions.physical_size()));
|
||||
self.window.set_scale_factor(self.scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
fn configure_wayland_surface(&self, dimensions: &SurfaceDimensions, mode: &ScalingMode) {
|
||||
match mode {
|
||||
ScalingMode::FractionalWithViewport => {
|
||||
self.surface.set_buffer_scale(1);
|
||||
if let Some(viewport) = &self.viewport {
|
||||
viewport.set_destination(
|
||||
dimensions.logical_width as i32,
|
||||
dimensions.logical_height as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
ScalingMode::FractionalOnly | ScalingMode::Integer => {
|
||||
self.surface.set_buffer_scale(dimensions.buffer_scale);
|
||||
}
|
||||
}
|
||||
|
||||
self.layer_surface
|
||||
.set_size(dimensions.logical_width, dimensions.logical_height);
|
||||
self.layer_surface.set_exclusive_zone(self.exclusive_zone);
|
||||
self.surface.commit();
|
||||
}
|
||||
|
||||
pub fn update_size(&mut self, width: u32, height: u32) {
|
||||
if width == 0 || height == 0 {
|
||||
info!("Skipping update_size with zero dimension: {width}x{height}");
|
||||
return;
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let physical_width = (width as f32 * self.scale_factor).round() as u32;
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let physical_height = (height as f32 * self.scale_factor).round() as u32;
|
||||
|
||||
let new_physical_size = PhysicalSize::new(physical_width, physical_height);
|
||||
let new_logical_size = PhysicalSize::new(width, height);
|
||||
let dimensions = SurfaceDimensions::calculate(width, height, self.scale_factor);
|
||||
let scaling_mode = self.determine_scaling_mode();
|
||||
|
||||
info!(
|
||||
"Updating window size: buffer {}x{}, physical {}x{}, scale {}, has_viewport: {}",
|
||||
width,
|
||||
height,
|
||||
physical_width,
|
||||
physical_height,
|
||||
"Updating window size: logical {}x{}, physical {}x{}, scale {}, buffer_scale {}, mode {:?}",
|
||||
dimensions.logical_width,
|
||||
dimensions.logical_height,
|
||||
dimensions.physical_width,
|
||||
dimensions.physical_height,
|
||||
self.scale_factor,
|
||||
self.viewport.is_some()
|
||||
dimensions.buffer_scale,
|
||||
scaling_mode
|
||||
);
|
||||
|
||||
if self.fractional_scale.is_some() && self.viewport.is_some() {
|
||||
self.surface.set_buffer_scale(1);
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||
width as f32,
|
||||
height as f32,
|
||||
)));
|
||||
self.window.set_scale_factor(self.scale_factor);
|
||||
|
||||
if let Some(viewport) = &self.viewport {
|
||||
viewport.set_destination(width as i32, height as i32);
|
||||
}
|
||||
} else if self.fractional_scale.is_some() {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let buffer_scale = self.scale_factor.round() as i32;
|
||||
self.surface.set_buffer_scale(buffer_scale);
|
||||
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||
width as f32,
|
||||
height as f32,
|
||||
)));
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
self.window.set_scale_factor(buffer_scale as f32);
|
||||
} else {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let buffer_scale = self.scale_factor.round() as i32;
|
||||
self.surface.set_buffer_scale(buffer_scale);
|
||||
|
||||
self.window
|
||||
.set_size(slint::WindowSize::Physical(new_physical_size));
|
||||
self.window.set_scale_factor(self.scale_factor);
|
||||
}
|
||||
self.configure_slint_window(&dimensions, &scaling_mode);
|
||||
self.configure_wayland_surface(&dimensions, &scaling_mode);
|
||||
|
||||
info!("Window physical size: {:?}", self.window.size());
|
||||
|
||||
self.layer_surface.set_size(width, height);
|
||||
self.layer_surface.set_exclusive_zone(self.exclusive_zone);
|
||||
self.surface.commit();
|
||||
|
||||
self.size = new_physical_size;
|
||||
self.logical_size = new_logical_size;
|
||||
self.size = dimensions.physical_size();
|
||||
self.logical_size = dimensions.logical_size();
|
||||
self.window.request_redraw();
|
||||
}
|
||||
|
||||
|
|
@ -159,8 +182,8 @@ impl WindowState {
|
|||
} else {
|
||||
let scale_factor = self.scale_factor;
|
||||
LogicalPosition::new(
|
||||
physical_x as f32 / scale_factor,
|
||||
physical_y as f32 / scale_factor,
|
||||
(physical_x / f64::from(scale_factor)) as f32,
|
||||
(physical_y / f64::from(scale_factor)) as f32,
|
||||
)
|
||||
};
|
||||
self.current_pointer_position = logical_position;
|
||||
|
|
@ -202,8 +225,8 @@ impl WindowState {
|
|||
&self.component_instance
|
||||
}
|
||||
|
||||
pub fn update_scale_factor(&mut self, scale_120ths: u32) {
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn update_scale_factor(&mut self, scale_120ths: u32) {
|
||||
let new_scale_factor = scale_120ths as f32 / 120.0;
|
||||
info!(
|
||||
"Updating scale factor from {} to {} ({}x)",
|
||||
|
|
|
|||
39
src/windowing/surface_dimensions.rs
Normal file
39
src/windowing/surface_dimensions.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
use slint::PhysicalSize;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SurfaceDimensions {
|
||||
pub logical_width: u32,
|
||||
pub logical_height: u32,
|
||||
pub physical_width: u32,
|
||||
pub physical_height: u32,
|
||||
pub buffer_scale: i32,
|
||||
}
|
||||
|
||||
impl SurfaceDimensions {
|
||||
#[allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_precision_loss
|
||||
)]
|
||||
pub fn calculate(logical_width: u32, logical_height: u32, scale_factor: f32) -> Self {
|
||||
let physical_width = (logical_width as f32 * scale_factor).round() as u32;
|
||||
let physical_height = (logical_height as f32 * scale_factor).round() as u32;
|
||||
let buffer_scale = scale_factor.round() as i32;
|
||||
|
||||
Self {
|
||||
logical_width,
|
||||
logical_height,
|
||||
physical_width,
|
||||
physical_height,
|
||||
buffer_scale,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn logical_size(&self) -> PhysicalSize {
|
||||
PhysicalSize::new(self.logical_width, self.logical_height)
|
||||
}
|
||||
|
||||
pub const fn physical_size(&self) -> PhysicalSize {
|
||||
PhysicalSize::new(self.physical_width, self.physical_height)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue