diff --git a/iced_layershell/src/application.rs b/iced_layershell/src/application.rs index 4c0695d..96dcd6d 100644 --- a/iced_layershell/src/application.rs +++ b/iced_layershell/src/application.rs @@ -470,9 +470,11 @@ async fn run_instance( IcedLayerEvent::Window(event) => { state.update(&event); - if let Some(event) = - conversion::window_event(&event, state.scale_factor(), state.modifiers()) - { + if let Some(event) = conversion::window_event( + &event, + state.application_scale_factor(), + state.modifiers(), + ) { events.push(event); } } diff --git a/iced_layershell/src/application/state.rs b/iced_layershell/src/application/state.rs index 7a081e5..22dd66d 100644 --- a/iced_layershell/src/application/state.rs +++ b/iced_layershell/src/application/state.rs @@ -47,7 +47,10 @@ where appearance, mouse_position: None, modifiers: ModifiersState::default(), - wpviewport: window.gen_main_wrapper().viewport.unwrap(), + wpviewport: window + .gen_main_wrapper() + .viewport + .expect("iced_layershell need viewport support to better render scale"), } } @@ -55,10 +58,6 @@ where self.modifiers } - pub fn scale_factor(&self) -> f64 { - self.viewport.scale_factor() - } - pub fn current_wayland_scale(&self) -> f64 { self.wayland_scale_factor } @@ -110,12 +109,14 @@ where pub fn theme(&self) -> &A::Theme { &self.theme } - + pub fn application_scale_factor(&self) -> f64 { + self.application_scale_factor + } pub fn cursor(&self) -> IcedMouse::Cursor { self.mouse_position .map(|point| Point { - x: point.x / self.scale_factor() as f32, - y: point.y / self.scale_factor() as f32, + x: point.x / self.application_scale_factor() as f32, + y: point.y / self.application_scale_factor() as f32, }) .map(IcedMouse::Cursor::Available) .unwrap_or(IcedMouse::Cursor::Unavailable) diff --git a/iced_layershell/src/multi_window.rs b/iced_layershell/src/multi_window.rs index 07621e4..58b32ce 100644 --- a/iced_layershell/src/multi_window.rs +++ b/iced_layershell/src/multi_window.rs @@ -589,7 +589,12 @@ async fn run_instance( window.mouse_interaction = new_mouse_interaction; } - compositor.configure_surface(&mut window.surface, width, height); + let physical_size = window.state.physical_size(); + compositor.configure_surface( + &mut window.surface, + physical_size.width, + physical_size.height, + ); runtime.broadcast(iced_futures::subscription::Event::Interaction { window: id, event: redraw_event.clone(), @@ -656,7 +661,7 @@ async fn run_instance( window.state.update(&event); if let Some(event) = conversion::window_event( &event, - window.state.scale_factor(), + window.state.application_scale_factor(), window.state.modifiers(), ) { events.push((Some(id), event)); diff --git a/iced_layershell/src/multi_window/state.rs b/iced_layershell/src/multi_window/state.rs index 4cef81e..97e1692 100644 --- a/iced_layershell/src/multi_window/state.rs +++ b/iced_layershell/src/multi_window/state.rs @@ -3,6 +3,8 @@ use crate::{Appearance, DefaultStyle}; use iced_core::{mouse as IcedMouse, Color, Point, Size}; use iced_graphics::Viewport; use layershellev::keyboard::ModifiersState; +use layershellev::reexport::wp_viewport::WpViewport; +use layershellev::WindowWrapper; use crate::event::WindowEvent; use iced::window; @@ -14,12 +16,14 @@ where id: window::Id, application_scale_factor: f64, wayland_scale_factor: f64, + real_window_size: Size, viewport: Viewport, viewport_version: usize, theme: A::Theme, appearance: Appearance, mouse_position: Option, modifiers: ModifiersState, + wpviewport: WpViewport, } impl State @@ -31,25 +35,32 @@ where application: &A, (width, height): (u32, u32), wayland_scale_factor: f64, + window: &WindowWrapper, ) -> Self { let application_scale_factor = application.scale_factor(id); let theme = application.theme(); let appearance = application.style(&theme); + let real_window_size = Size::new(width, height); let viewport = Viewport::with_physical_size( - iced_core::Size::new(width, height), + real_window_size, wayland_scale_factor * application_scale_factor, ); Self { id, application_scale_factor, wayland_scale_factor, + real_window_size, viewport, viewport_version: 0, theme, appearance, mouse_position: None, modifiers: ModifiersState::default(), + wpviewport: window + .viewport + .clone() + .expect("iced_layershell need viewport support to better render scale"), } } pub fn modifiers(&self) -> ModifiersState { @@ -59,15 +70,32 @@ where pub fn current_wayland_scale(&self) -> f64 { self.wayland_scale_factor } + pub fn update_view_port(&mut self, width: u32, height: u32, scale: f64) { + self.real_window_size = Size::new(width, height); self.wayland_scale_factor = scale; self.viewport = Viewport::with_physical_size( - iced_core::Size::new(width, height), + self.adjusted_physical_size(), self.current_wayland_scale() * self.application_scale_factor, ); + let logical_size = self.viewport.logical_size(); + + println!("viewport updated {:?}", self.adjusted_physical_size()); + self.wpviewport.set_destination( + logical_size.width.ceil() as i32, + logical_size.height.ceil() as i32, + ); self.viewport_version = self.viewport_version.wrapping_add(1); } + fn adjusted_physical_size(&self) -> Size { + let mut size = self.real_window_size; + let factor = self.wayland_scale_factor * self.application_scale_factor; + size.width = (size.width as f64 * factor).ceil() as u32; + size.height = (size.height as f64 * factor).ceil() as u32; + size + } + pub fn viewport(&self) -> &Viewport { &self.viewport } @@ -80,8 +108,8 @@ where self.viewport.logical_size() } - pub fn scale_factor(&self) -> f64 { - self.viewport.scale_factor() + pub fn application_scale_factor(&self) -> f64 { + self.application_scale_factor } pub fn text_color(&self) -> Color { @@ -103,8 +131,8 @@ where pub fn cursor(&self) -> IcedMouse::Cursor { self.mouse_position .map(|point| Point { - x: point.x / self.scale_factor() as f32, - y: point.y / self.scale_factor() as f32, + x: point.x / self.application_scale_factor() as f32, + y: point.y / self.application_scale_factor() as f32, }) .map(IcedMouse::Cursor::Available) .unwrap_or(IcedMouse::Cursor::Unavailable) @@ -128,13 +156,19 @@ where scale_float, scale_u32: _, } => { - let size = self.viewport.physical_size(); - - self.viewport = - Viewport::with_physical_size(size, scale_float * self.application_scale_factor); + self.wayland_scale_factor = *scale_float; + self.viewport = Viewport::with_physical_size( + self.adjusted_physical_size(), + self.application_scale_factor * scale_float, + ); self.viewport_version = self.viewport_version.wrapping_add(1); - self.wayland_scale_factor = *scale_float; + let logical_size = self.viewport.logical_size(); + + self.wpviewport.set_destination( + logical_size.width.ceil() as i32, + logical_size.height.ceil() as i32, + ); } _ => {} } @@ -143,12 +177,12 @@ where pub fn synchronize(&mut self, application: &A) { let new_scale_factor = application.scale_factor(self.id); if self.application_scale_factor != new_scale_factor { + self.application_scale_factor = new_scale_factor; self.viewport = Viewport::with_physical_size( - self.physical_size(), - self.wayland_scale_factor * new_scale_factor, + self.adjusted_physical_size(), + self.current_wayland_scale() * new_scale_factor, ); self.viewport_version = self.viewport_version.wrapping_add(1); - self.application_scale_factor = new_scale_factor; } self.theme = application.theme(); self.appearance = application.style(&self.theme); diff --git a/iced_layershell/src/multi_window/window_manager.rs b/iced_layershell/src/multi_window/window_manager.rs index 85cfec7..9ed31e1 100644 --- a/iced_layershell/src/multi_window/window_manager.rs +++ b/iced_layershell/src/multi_window/window_manager.rs @@ -80,7 +80,7 @@ where compositor: &mut C, ) -> &mut Window { let layerid = window.id(); - let state = State::new(id, application, size, fractal_scale); + let state = State::new(id, application, size, fractal_scale, &window); let physical_size = state.physical_size(); let surface = compositor.create_surface(window, physical_size.width, physical_size.height); let renderer = compositor.create_renderer();