mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-10-29 02:24:22 +00:00
fix: fractional scaling on popup
This commit is contained in:
parent
4ea4171eb7
commit
b14cb51f86
5 changed files with 88 additions and 11 deletions
|
|
@ -72,6 +72,23 @@ impl PopupSurface {
|
|||
Rc::new(vp.get_viewport(&surface, params.queue_handle, ()))
|
||||
});
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
if let Some(ref vp) = viewport {
|
||||
let logical_width = (params.size.width as f32 / params.scale_factor) as i32;
|
||||
let logical_height = (params.size.height as f32 / params.scale_factor) as i32;
|
||||
info!(
|
||||
"Setting viewport destination to logical size: {}x{} (physical: {}x{}, scale: {})",
|
||||
logical_width,
|
||||
logical_height,
|
||||
params.size.width,
|
||||
params.size.height,
|
||||
params.scale_factor
|
||||
);
|
||||
vp.set_destination(logical_width, logical_height);
|
||||
}
|
||||
|
||||
surface.set_buffer_scale(1);
|
||||
surface.commit();
|
||||
|
||||
|
|
|
|||
|
|
@ -57,30 +57,44 @@ struct ActivePopup {
|
|||
pub struct PopupManager {
|
||||
context: PopupContext,
|
||||
popups: RefCell<Vec<ActivePopup>>,
|
||||
current_scale_factor: RefCell<f32>,
|
||||
}
|
||||
|
||||
impl PopupManager {
|
||||
pub const fn new(context: PopupContext) -> Self {
|
||||
pub const fn new(context: PopupContext, initial_scale_factor: f32) -> Self {
|
||||
Self {
|
||||
context,
|
||||
popups: RefCell::new(Vec::new()),
|
||||
current_scale_factor: RefCell::new(initial_scale_factor),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_scale_factor(&self, scale_factor: f32) {
|
||||
*self.current_scale_factor.borrow_mut() = scale_factor;
|
||||
}
|
||||
|
||||
pub fn create_popup(
|
||||
&self,
|
||||
queue_handle: &QueueHandle<WindowState>,
|
||||
parent_layer_surface: &ZwlrLayerSurfaceV1,
|
||||
last_pointer_serial: u32,
|
||||
scale_factor: f32,
|
||||
) -> Result<Rc<PopupWindow>> {
|
||||
let xdg_wm_base = self.context.xdg_wm_base.as_ref().ok_or_else(|| {
|
||||
LayerShikaError::WaylandProtocol("xdg-shell not available for popups".into())
|
||||
})?;
|
||||
|
||||
info!("Creating popup window");
|
||||
let scale_factor = *self.current_scale_factor.borrow();
|
||||
info!("Creating popup window with scale factor {scale_factor}");
|
||||
|
||||
let popup_size = PhysicalSize::new(360, 524);
|
||||
let logical_size = slint::LogicalSize::new(360.0, 524.0);
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let popup_size = PhysicalSize::new(
|
||||
(logical_size.width * scale_factor) as u32,
|
||||
(logical_size.height * scale_factor) as u32,
|
||||
);
|
||||
|
||||
info!("Popup logical size: {logical_size:?}, physical size: {popup_size:?}");
|
||||
|
||||
let popup_surface = PopupSurface::create(&super::popup::PopupSurfaceParams {
|
||||
compositor: &self.context.compositor,
|
||||
|
|
@ -107,8 +121,8 @@ impl PopupManager {
|
|||
.map_err(|e| LayerShikaError::FemtoVGRendererCreation(e.to_string()))?;
|
||||
|
||||
let popup_window = PopupWindow::new(renderer);
|
||||
popup_window.set_size(WindowSize::Physical(popup_size));
|
||||
popup_window.set_scale_factor(scale_factor);
|
||||
popup_window.set_size(WindowSize::Logical(logical_size));
|
||||
|
||||
info!("Popup window created successfully");
|
||||
|
||||
|
|
@ -151,6 +165,20 @@ impl PopupManager {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn find_popup_index_by_fractional_scale_id(
|
||||
&self,
|
||||
fractional_scale_id: &ObjectId,
|
||||
) -> Option<usize> {
|
||||
for (index, popup) in self.popups.borrow().iter().enumerate() {
|
||||
if let Some(ref fs) = popup.surface.fractional_scale {
|
||||
if fs.id() == *fractional_scale_id {
|
||||
return Some(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_popup_window(&self, index: usize) -> Option<Rc<PopupWindow>> {
|
||||
self.popups
|
||||
.borrow()
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ impl Dispatch<WlPointer, ()> for WindowState {
|
|||
impl Dispatch<WpFractionalScaleV1, ()> for WindowState {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
_proxy: &WpFractionalScaleV1,
|
||||
proxy: &WpFractionalScaleV1,
|
||||
event: wp_fractional_scale_v1::Event,
|
||||
_data: &(),
|
||||
_conn: &Connection,
|
||||
|
|
@ -228,7 +228,7 @@ impl Dispatch<WpFractionalScaleV1, ()> for WindowState {
|
|||
#[allow(clippy::cast_precision_loss)]
|
||||
let scale_float = scale as f32 / 120.0;
|
||||
info!("Fractional scale received: {scale_float} ({scale}x)");
|
||||
state.update_scale_factor(scale);
|
||||
state.update_scale_for_fractional_scale_object(proxy, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use slint::platform::{WindowAdapter, WindowEvent};
|
|||
use slint_interpreter::ComponentInstance;
|
||||
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||
use wayland_client::{protocol::{wl_output::WlOutput, wl_surface::WlSurface}, Proxy};
|
||||
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
|
||||
use crate::rendering::femtovg_window::FemtoVGWindow;
|
||||
use crate::errors::{LayerShikaError, Result};
|
||||
use crate::windowing::surface_dimensions::SurfaceDimensions;
|
||||
|
|
@ -269,6 +270,10 @@ impl WindowState {
|
|||
);
|
||||
self.scale_factor = new_scale_factor;
|
||||
|
||||
if let Some(popup_manager) = &self.popup_manager {
|
||||
popup_manager.update_scale_factor(new_scale_factor);
|
||||
}
|
||||
|
||||
let current_logical_size = self.logical_size;
|
||||
if current_logical_size.width > 0 && current_logical_size.height > 0 {
|
||||
self.update_size(current_logical_size.width, current_logical_size.height);
|
||||
|
|
@ -324,4 +329,33 @@ impl WindowState {
|
|||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn update_scale_for_fractional_scale_object(
|
||||
&mut self,
|
||||
fractional_scale_proxy: &WpFractionalScaleV1,
|
||||
scale_120ths: u32,
|
||||
) {
|
||||
let fractional_scale_id = fractional_scale_proxy.id();
|
||||
|
||||
if let Some(ref main_fractional_scale) = self.fractional_scale {
|
||||
if (**main_fractional_scale.inner()).id() == fractional_scale_id {
|
||||
self.update_scale_factor(scale_120ths);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(popup_manager) = &self.popup_manager {
|
||||
if let Some(popup_index) =
|
||||
popup_manager.find_popup_index_by_fractional_scale_id(&fractional_scale_id)
|
||||
{
|
||||
if let Some(popup_window) = popup_manager.get_popup_window(popup_index) {
|
||||
let new_scale_factor = scale_120ths as f32 / 120.0;
|
||||
info!("Updating popup scale factor to {new_scale_factor} ({scale_120ths}x)");
|
||||
popup_window.set_scale_factor(new_scale_factor);
|
||||
popup_window.request_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ impl WindowingSystem {
|
|||
Rc::clone(&connection),
|
||||
);
|
||||
|
||||
let popup_manager = Rc::new(PopupManager::new(popup_context));
|
||||
let popup_manager = Rc::new(PopupManager::new(popup_context, state.scale_factor()));
|
||||
|
||||
Self::setup_popup_creator(&popup_manager, &platform, &state, &event_queue);
|
||||
|
||||
|
|
@ -156,14 +156,12 @@ impl WindowingSystem {
|
|||
let popup_manager_clone = Rc::clone(popup_manager);
|
||||
let layer_surface = state.layer_surface();
|
||||
let queue_handle = event_queue.handle();
|
||||
let scale_factor = state.scale_factor();
|
||||
let last_serial = state.last_pointer_serial();
|
||||
|
||||
platform.set_popup_creator(move || {
|
||||
info!("Popup creator called! Creating popup window...");
|
||||
|
||||
let result = popup_manager_clone
|
||||
.create_popup(&queue_handle, &layer_surface, last_serial, scale_factor)
|
||||
.create_popup(&queue_handle, &layer_surface, 0)
|
||||
.map(|w| w as Rc<dyn WindowAdapter>)
|
||||
.map_err(|e| PlatformError::Other(format!("Failed to create popup: {e}")));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue