From 28943911fa0adeb85080c4044845f3f7dbcab2f4 Mon Sep 17 00:00:00 2001 From: ShootingStarDragons Date: Mon, 7 Oct 2024 22:20:27 +0900 Subject: [PATCH] chore: viewport support demo --- iced_layershell/src/actions.rs | 1 + iced_layershell/src/application.rs | 10 +++++- iced_layershell/src/application/state.rs | 46 ++++++++++++++++-------- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/iced_layershell/src/actions.rs b/iced_layershell/src/actions.rs index 80698a8..e501114 100644 --- a/iced_layershell/src/actions.rs +++ b/iced_layershell/src/actions.rs @@ -13,6 +13,7 @@ pub(crate) enum LayerShellActions { RedrawAll, RedrawWindow(LayerId), // maybe one day it is useful, but now useless NewMenu((IcedNewPopupSettings, INFO)), + ViewPortDestionSingle { width: i32, height: i32 }, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] diff --git a/iced_layershell/src/application.rs b/iced_layershell/src/application.rs index 4c0695d..56ca22b 100644 --- a/iced_layershell/src/application.rs +++ b/iced_layershell/src/application.rs @@ -308,6 +308,9 @@ where LayerShellActions::RedrawWindow(index) => { ev.append_return_data(ReturnData::RedrawIndexRequest(index)); } + LayerShellActions::ViewPortDestionSingle { width, height } => { + ev.main_window().try_set_viewport_destination(width, height); + } _ => {} } def_returndata @@ -382,6 +385,11 @@ async fn run_instance( ); debug.layout_finished(); + custom_actions.push(LayerShellActions::ViewPortDestionSingle { + width: logical_size.width.ceil() as i32, + height: logical_size.height.ceil() as i32, + }); + let physical_size = state.physical_size(); compositor.configure_surface( &mut surface, @@ -468,7 +476,7 @@ async fn run_instance( } } IcedLayerEvent::Window(event) => { - state.update(&event); + state.update(&event, &mut custom_actions); if let Some(event) = conversion::window_event(&event, state.scale_factor(), state.modifiers()) diff --git a/iced_layershell/src/application/state.rs b/iced_layershell/src/application/state.rs index 62983d3..7cfa465 100644 --- a/iced_layershell/src/application/state.rs +++ b/iced_layershell/src/application/state.rs @@ -1,3 +1,4 @@ +use crate::actions::LayerShellActions; use crate::application::Application; use crate::{Appearance, DefaultStyle}; use iced_core::{mouse as IcedMouse, Color, Point, Size}; @@ -12,6 +13,7 @@ where { application_scale_factor: f64, wayland_scale_factor: f64, + real_window_size: Size, viewport: Viewport, viewport_version: usize, theme: A::Theme, @@ -25,17 +27,18 @@ where A::Theme: DefaultStyle, { pub fn new(application: &A, window: &layershellev::WindowStateSimple) -> Self { - let scale_factor = application.scale_factor(); + let application_scale_factor = application.scale_factor(); let theme = application.theme(); let appearance = application.style(&theme); - let wayland_scale_factor = 1.; let (width, height) = window.main_window().get_size(); - let viewport = { - Viewport::with_physical_size(iced_core::Size::new(width, height), wayland_scale_factor) - }; + let real_window_size = Size::new(width, height); + let wayland_scale_factor = 1.; + + let viewport = { Viewport::with_physical_size(real_window_size, wayland_scale_factor) }; Self { - application_scale_factor: scale_factor, + application_scale_factor, + real_window_size, wayland_scale_factor, viewport, viewport_version: 0, @@ -59,14 +62,23 @@ where } 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::Size::new(width, height), + self.adjusted_physical_size(), self.current_wayland_scale() * self.application_scale_factor, ); 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 } @@ -101,7 +113,7 @@ where .unwrap_or(IcedMouse::Cursor::Unavailable) } - pub fn update(&mut self, event: &WindowEvent) { + pub fn update(&mut self, event: &WindowEvent, actions: &mut Vec>) { match event { WindowEvent::CursorLeft | WindowEvent::TouchUp { .. } => { self.mouse_position = None; @@ -119,12 +131,18 @@ where scale_float, scale_u32: _, } => { - let size = self.physical_size(); - self.viewport = - Viewport::with_physical_size(size, self.application_scale_factor * scale_float); + 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(); + actions.push(LayerShellActions::ViewPortDestionSingle { + width: logical_size.width.ceil() as i32, + height: logical_size.height.ceil() as i32, + }); } _ => {} } @@ -133,12 +151,12 @@ where pub fn synchronize(&mut self, application: &A) { let new_scale_factor = application.scale_factor(); 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.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);