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 macros;
|
||||||
mod state;
|
mod state;
|
||||||
mod surface;
|
mod surface;
|
||||||
|
mod surface_dimensions;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
pub use system::WindowingSystem;
|
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 wayland_protocols::wp::viewporter::client::wp_viewport::WpViewport;
|
||||||
use crate::rendering::femtovg_window::FemtoVGWindow;
|
use crate::rendering::femtovg_window::FemtoVGWindow;
|
||||||
use crate::errors::{LayerShikaError, Result};
|
use crate::errors::{LayerShikaError, Result};
|
||||||
|
use crate::windowing::surface_dimensions::SurfaceDimensions;
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub mod dispatches;
|
pub mod dispatches;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum ScalingMode {
|
||||||
|
FractionalWithViewport,
|
||||||
|
FractionalOnly,
|
||||||
|
Integer,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
component_instance: ComponentInstance,
|
component_instance: ComponentInstance,
|
||||||
surface: Rc<WlSurface>,
|
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)]
|
#[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)]
|
#[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) {
|
pub fn update_size(&mut self, width: u32, height: u32) {
|
||||||
if width == 0 || height == 0 {
|
if width == 0 || height == 0 {
|
||||||
info!("Skipping update_size with zero dimension: {width}x{height}");
|
info!("Skipping update_size with zero dimension: {width}x{height}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
let dimensions = SurfaceDimensions::calculate(width, height, self.scale_factor);
|
||||||
#[allow(clippy::cast_sign_loss)]
|
let scaling_mode = self.determine_scaling_mode();
|
||||||
#[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);
|
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Updating window size: buffer {}x{}, physical {}x{}, scale {}, has_viewport: {}",
|
"Updating window size: logical {}x{}, physical {}x{}, scale {}, buffer_scale {}, mode {:?}",
|
||||||
width,
|
dimensions.logical_width,
|
||||||
height,
|
dimensions.logical_height,
|
||||||
physical_width,
|
dimensions.physical_width,
|
||||||
physical_height,
|
dimensions.physical_height,
|
||||||
self.scale_factor,
|
self.scale_factor,
|
||||||
self.viewport.is_some()
|
dimensions.buffer_scale,
|
||||||
|
scaling_mode
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.fractional_scale.is_some() && self.viewport.is_some() {
|
self.configure_slint_window(&dimensions, &scaling_mode);
|
||||||
self.surface.set_buffer_scale(1);
|
self.configure_wayland_surface(&dimensions, &scaling_mode);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
info!("Window physical size: {:?}", self.window.size());
|
info!("Window physical size: {:?}", self.window.size());
|
||||||
|
|
||||||
self.layer_surface.set_size(width, height);
|
self.size = dimensions.physical_size();
|
||||||
self.layer_surface.set_exclusive_zone(self.exclusive_zone);
|
self.logical_size = dimensions.logical_size();
|
||||||
self.surface.commit();
|
|
||||||
|
|
||||||
self.size = new_physical_size;
|
|
||||||
self.logical_size = new_logical_size;
|
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,8 +182,8 @@ impl WindowState {
|
||||||
} else {
|
} else {
|
||||||
let scale_factor = self.scale_factor;
|
let scale_factor = self.scale_factor;
|
||||||
LogicalPosition::new(
|
LogicalPosition::new(
|
||||||
physical_x as f32 / scale_factor,
|
(physical_x / f64::from(scale_factor)) as f32,
|
||||||
physical_y as f32 / scale_factor,
|
(physical_y / f64::from(scale_factor)) as f32,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
self.current_pointer_position = logical_position;
|
self.current_pointer_position = logical_position;
|
||||||
|
|
@ -202,8 +225,8 @@ impl WindowState {
|
||||||
&self.component_instance
|
&self.component_instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
pub fn update_scale_factor(&mut self, scale_120ths: u32) {
|
pub fn update_scale_factor(&mut self, scale_120ths: u32) {
|
||||||
#[allow(clippy::cast_precision_loss)]
|
|
||||||
let new_scale_factor = scale_120ths as f32 / 120.0;
|
let new_scale_factor = scale_120ths as f32 / 120.0;
|
||||||
info!(
|
info!(
|
||||||
"Updating scale factor from {} to {} ({}x)",
|
"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