mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-11-17 23:14:23 +00:00
refactor: extract popup service
This commit is contained in:
parent
acece2dbf3
commit
6346c1ab96
6 changed files with 278 additions and 87 deletions
|
|
@ -269,30 +269,30 @@ impl Dispatch<XdgPopup, ()> for WindowState {
|
||||||
} => {
|
} => {
|
||||||
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
|
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
|
||||||
|
|
||||||
if let Some(popup_manager) = &state.popup_manager() {
|
if let Some(popup_service) = state.popup_service() {
|
||||||
let popup_id = xdg_popup.id();
|
let popup_id = xdg_popup.id();
|
||||||
if let Some(key) = popup_manager.find_popup_key_by_xdg_popup_id(&popup_id) {
|
if let Some(handle) = popup_service.find_by_xdg_popup(&popup_id) {
|
||||||
info!(
|
info!(
|
||||||
"Marking popup with key {key} as configured after XdgPopup::Configure"
|
"Marking popup with handle {handle:?} as configured after XdgPopup::Configure"
|
||||||
);
|
);
|
||||||
popup_manager.mark_popup_configured(key);
|
popup_service.mark_popup_configured(handle);
|
||||||
popup_manager.mark_all_popups_dirty();
|
popup_service.manager().mark_all_popups_dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xdg_popup::Event::PopupDone => {
|
xdg_popup::Event::PopupDone => {
|
||||||
info!("XdgPopup dismissed by compositor");
|
info!("XdgPopup dismissed by compositor");
|
||||||
let popup_id = xdg_popup.id();
|
let popup_id = xdg_popup.id();
|
||||||
let popup_key = state
|
let popup_handle = state
|
||||||
.popup_manager()
|
.popup_service()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|pm| pm.find_popup_key_by_xdg_popup_id(&popup_id));
|
.and_then(|ps| ps.find_by_xdg_popup(&popup_id));
|
||||||
|
|
||||||
if let Some(key) = popup_key {
|
if let Some(handle) = popup_handle {
|
||||||
info!("Destroying popup with key {key}");
|
info!("Destroying popup with handle {handle:?}");
|
||||||
state.clear_active_window_if_popup(key);
|
state.clear_active_window_if_popup(handle.key());
|
||||||
if let Some(popup_manager) = &state.popup_manager() {
|
if let Some(popup_service) = state.popup_service() {
|
||||||
popup_manager.destroy_popup(key);
|
let _result = popup_service.close(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -317,9 +317,9 @@ impl Dispatch<XdgSurface, ()> for WindowState {
|
||||||
info!("XdgSurface Configure received, sending ack with serial {serial}");
|
info!("XdgSurface Configure received, sending ack with serial {serial}");
|
||||||
xdg_surface.ack_configure(serial);
|
xdg_surface.ack_configure(serial);
|
||||||
|
|
||||||
if let Some(popup_manager) = &state.popup_manager() {
|
if let Some(popup_service) = state.popup_service() {
|
||||||
info!("Marking all popups as dirty after Configure");
|
info!("Marking all popups as dirty after Configure");
|
||||||
popup_manager.mark_all_popups_dirty();
|
popup_service.manager().mark_all_popups_dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@ pub mod connection;
|
||||||
pub mod event_handling;
|
pub mod event_handling;
|
||||||
pub mod globals;
|
pub mod globals;
|
||||||
pub mod managed_proxies;
|
pub mod managed_proxies;
|
||||||
|
pub mod services;
|
||||||
pub mod shell_adapter;
|
pub mod shell_adapter;
|
||||||
pub mod surfaces;
|
pub mod surfaces;
|
||||||
|
|
|
||||||
1
adapters/src/wayland/services/mod.rs
Normal file
1
adapters/src/wayland/services/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod popup_service;
|
||||||
196
adapters/src/wayland/services/popup_service.rs
Normal file
196
adapters/src/wayland/services/popup_service.rs
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
use crate::errors::Result;
|
||||||
|
use crate::rendering::femtovg::popup_window::PopupWindow;
|
||||||
|
use layer_shika_domain::value_objects::popup_request::{PopupHandle, PopupRequest};
|
||||||
|
use log::info;
|
||||||
|
use slint::PhysicalSize;
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use wayland_client::{backend::ObjectId, protocol::wl_surface::WlSurface, Proxy};
|
||||||
|
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
|
||||||
|
|
||||||
|
use super::super::surfaces::popup_manager::PopupManager;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum ActiveWindow {
|
||||||
|
Main,
|
||||||
|
Popup(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PopupService {
|
||||||
|
manager: Rc<PopupManager>,
|
||||||
|
active_window: RefCell<Option<ActiveWindow>>,
|
||||||
|
scale_factor: Cell<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PopupService {
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(manager: Rc<PopupManager>) -> Self {
|
||||||
|
let scale_factor = manager.scale_factor();
|
||||||
|
Self {
|
||||||
|
manager,
|
||||||
|
active_window: RefCell::new(None),
|
||||||
|
scale_factor: Cell::new(scale_factor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show(&self, request: PopupRequest, width: f32, height: f32) {
|
||||||
|
self.manager.set_pending_popup(request, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close(&self, handle: PopupHandle) -> Result<()> {
|
||||||
|
let key = handle.key();
|
||||||
|
self.clear_active_window_if_popup(key);
|
||||||
|
self.manager.destroy_popup(key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close_current(&self) {
|
||||||
|
if let Some(key) = self.manager.current_popup_key() {
|
||||||
|
self.clear_active_window_if_popup(key);
|
||||||
|
}
|
||||||
|
self.manager.close_current_popup();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_by_surface(&self, surface_id: &ObjectId) -> Option<PopupHandle> {
|
||||||
|
self.manager
|
||||||
|
.find_popup_key_by_surface_id(surface_id)
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_by_fractional_scale(&self, fractional_scale_id: &ObjectId) -> Option<PopupHandle> {
|
||||||
|
self.manager
|
||||||
|
.find_popup_key_by_fractional_scale_id(fractional_scale_id)
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_by_xdg_popup(&self, xdg_popup_id: &ObjectId) -> Option<PopupHandle> {
|
||||||
|
self.manager
|
||||||
|
.find_popup_key_by_xdg_popup_id(xdg_popup_id)
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn find_by_xdg_surface(&self, xdg_surface_id: &ObjectId) -> Option<PopupHandle> {
|
||||||
|
self.manager
|
||||||
|
.find_popup_key_by_xdg_surface_id(xdg_surface_id)
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_popup_window(&self, handle: PopupHandle) -> Option<Rc<PopupWindow>> {
|
||||||
|
self.manager.get_popup_window(handle.key())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_scale_factor(&self, scale_factor: f32) {
|
||||||
|
self.scale_factor.set(scale_factor);
|
||||||
|
self.manager.update_scale_factor(scale_factor);
|
||||||
|
self.manager.mark_all_popups_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_output_size(&self, output_size: PhysicalSize) {
|
||||||
|
self.manager.update_output_size(output_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn scale_factor(&self) -> f32 {
|
||||||
|
self.scale_factor.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_window_for_surface(&self, surface: &WlSurface, main_surface_id: &ObjectId) {
|
||||||
|
let surface_id = surface.id();
|
||||||
|
|
||||||
|
if *main_surface_id == surface_id {
|
||||||
|
*self.active_window.borrow_mut() = Some(ActiveWindow::Main);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(popup_key) = self.manager.find_popup_key_by_surface_id(&surface_id) {
|
||||||
|
*self.active_window.borrow_mut() = Some(ActiveWindow::Popup(popup_key));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*self.active_window.borrow_mut() = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn active_window(&self) -> Option<ActiveWindow> {
|
||||||
|
*self.active_window.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_active_window(&self) {
|
||||||
|
*self.active_window.borrow_mut() = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_active_window_if_popup(&self, popup_key: usize) {
|
||||||
|
if *self.active_window.borrow() == Some(ActiveWindow::Popup(popup_key)) {
|
||||||
|
*self.active_window.borrow_mut() = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
pub fn update_scale_for_fractional_scale_object(
|
||||||
|
&self,
|
||||||
|
fractional_scale_proxy: &WpFractionalScaleV1,
|
||||||
|
scale_120ths: u32,
|
||||||
|
) {
|
||||||
|
let fractional_scale_id = fractional_scale_proxy.id();
|
||||||
|
|
||||||
|
if let Some(popup_key) =
|
||||||
|
self.manager
|
||||||
|
.find_popup_key_by_fractional_scale_id(&fractional_scale_id)
|
||||||
|
{
|
||||||
|
if let Some(popup_window) = self.manager.get_popup_window(popup_key) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_popups(&self) -> Result<()> {
|
||||||
|
self.manager.render_popups()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mark_popup_configured(&self, handle: PopupHandle) {
|
||||||
|
self.manager.mark_popup_configured(handle.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_popup_viewport(
|
||||||
|
&self,
|
||||||
|
handle: PopupHandle,
|
||||||
|
logical_width: i32,
|
||||||
|
logical_height: i32,
|
||||||
|
) {
|
||||||
|
self.manager
|
||||||
|
.update_popup_viewport(handle.key(), logical_width, logical_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_popup_info(&self, handle: PopupHandle) -> Option<(PopupRequest, u32)> {
|
||||||
|
self.manager.get_popup_info(handle.key())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn manager(&self) -> &Rc<PopupManager> {
|
||||||
|
&self.manager
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn has_xdg_shell(&self) -> bool {
|
||||||
|
self.manager.has_xdg_shell()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn current_popup_key(&self) -> Option<usize> {
|
||||||
|
self.manager.current_popup_key()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn take_pending_popup(&self) -> Option<(PopupRequest, f32, f32)> {
|
||||||
|
self.manager.take_pending_popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::wayland::{
|
use crate::wayland::{
|
||||||
config::{LayerSurfaceParams, WaylandWindowConfig},
|
config::{LayerSurfaceParams, WaylandWindowConfig},
|
||||||
globals::context::GlobalContext,
|
globals::context::GlobalContext,
|
||||||
|
services::popup_service::PopupService,
|
||||||
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
|
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
|
||||||
surfaces::popup_manager::{CreatePopupParams, PopupContext, PopupManager},
|
surfaces::popup_manager::{CreatePopupParams, PopupContext, PopupManager},
|
||||||
surfaces::{
|
surfaces::{
|
||||||
|
|
@ -38,7 +39,7 @@ pub struct WaylandWindowingSystem {
|
||||||
connection: Rc<Connection>,
|
connection: Rc<Connection>,
|
||||||
event_queue: EventQueue<WindowState>,
|
event_queue: EventQueue<WindowState>,
|
||||||
event_loop: EventLoop<'static, WindowState>,
|
event_loop: EventLoop<'static, WindowState>,
|
||||||
popup_manager: Rc<PopupManager>,
|
popup_service: Rc<PopupService>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WaylandWindowingSystem {
|
impl WaylandWindowingSystem {
|
||||||
|
|
@ -60,10 +61,11 @@ impl WaylandWindowingSystem {
|
||||||
);
|
);
|
||||||
|
|
||||||
let popup_manager = Rc::new(PopupManager::new(popup_context, state.scale_factor()));
|
let popup_manager = Rc::new(PopupManager::new(popup_context, state.scale_factor()));
|
||||||
|
let popup_service = Rc::new(PopupService::new(popup_manager));
|
||||||
let shared_serial = Rc::new(SharedPointerSerial::new());
|
let shared_serial = Rc::new(SharedPointerSerial::new());
|
||||||
|
|
||||||
Self::setup_popup_creator(
|
Self::setup_popup_creator(
|
||||||
&popup_manager,
|
&popup_service,
|
||||||
&platform,
|
&platform,
|
||||||
&state,
|
&state,
|
||||||
&event_queue,
|
&event_queue,
|
||||||
|
|
@ -75,12 +77,12 @@ impl WaylandWindowingSystem {
|
||||||
connection,
|
connection,
|
||||||
event_queue,
|
event_queue,
|
||||||
event_loop,
|
event_loop,
|
||||||
popup_manager,
|
popup_service,
|
||||||
})
|
})
|
||||||
.map(|mut system| {
|
.map(|mut system| {
|
||||||
system
|
system
|
||||||
.state
|
.state
|
||||||
.set_popup_manager(Rc::clone(&system.popup_manager));
|
.set_popup_service(Rc::clone(&system.popup_service));
|
||||||
system.state.set_shared_pointer_serial(shared_serial);
|
system.state.set_shared_pointer_serial(shared_serial);
|
||||||
system
|
system
|
||||||
})
|
})
|
||||||
|
|
@ -156,20 +158,20 @@ impl WaylandWindowingSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_popup_creator(
|
fn setup_popup_creator(
|
||||||
popup_manager: &Rc<PopupManager>,
|
popup_service: &Rc<PopupService>,
|
||||||
platform: &Rc<CustomSlintPlatform>,
|
platform: &Rc<CustomSlintPlatform>,
|
||||||
state: &WindowState,
|
state: &WindowState,
|
||||||
event_queue: &EventQueue<WindowState>,
|
event_queue: &EventQueue<WindowState>,
|
||||||
shared_serial: &Rc<SharedPointerSerial>,
|
shared_serial: &Rc<SharedPointerSerial>,
|
||||||
) {
|
) {
|
||||||
if !popup_manager.has_xdg_shell() {
|
if !popup_service.has_xdg_shell() {
|
||||||
info!("xdg-shell not available, popups will not be supported");
|
info!("xdg-shell not available, popups will not be supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Setting up popup creator with xdg-shell support");
|
info!("Setting up popup creator with xdg-shell support");
|
||||||
|
|
||||||
let popup_manager_clone = Rc::clone(popup_manager);
|
let popup_service_clone = Rc::clone(popup_service);
|
||||||
let layer_surface = state.layer_surface();
|
let layer_surface = state.layer_surface();
|
||||||
let queue_handle = event_queue.handle();
|
let queue_handle = event_queue.handle();
|
||||||
let serial_holder = Rc::clone(shared_serial);
|
let serial_holder = Rc::clone(shared_serial);
|
||||||
|
|
@ -179,7 +181,7 @@ impl WaylandWindowingSystem {
|
||||||
|
|
||||||
let serial = serial_holder.get();
|
let serial = serial_holder.get();
|
||||||
|
|
||||||
let (params, request) = if let Some((request, width, height)) = popup_manager_clone.take_pending_popup() {
|
let (params, request) = if let Some((request, width, height)) = popup_service_clone.take_pending_popup() {
|
||||||
log::info!(
|
log::info!(
|
||||||
"Using popup request: component='{}', position=({}, {}), size={}x{}, mode={:?}",
|
"Using popup request: component='{}', position=({}, {}), size={}x{}, mode={:?}",
|
||||||
request.component,
|
request.component,
|
||||||
|
|
@ -206,7 +208,8 @@ impl WaylandWindowingSystem {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
let popup_window = popup_manager_clone
|
let popup_window = popup_service_clone
|
||||||
|
.manager()
|
||||||
.create_popup(
|
.create_popup(
|
||||||
&queue_handle,
|
&queue_handle,
|
||||||
&layer_surface,
|
&layer_surface,
|
||||||
|
|
@ -276,12 +279,12 @@ impl WaylandWindowingSystem {
|
||||||
|
|
||||||
let event_queue = &mut self.event_queue;
|
let event_queue = &mut self.event_queue;
|
||||||
let connection = &self.connection;
|
let connection = &self.connection;
|
||||||
let popup_manager = Rc::clone(&self.popup_manager);
|
let popup_service = Rc::clone(&self.popup_service);
|
||||||
|
|
||||||
self.event_loop
|
self.event_loop
|
||||||
.run(None, &mut self.state, move |shared_data| {
|
.run(None, &mut self.state, move |shared_data| {
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
Self::process_events(connection, event_queue, shared_data, &popup_manager)
|
Self::process_events(connection, event_queue, shared_data, &popup_service)
|
||||||
{
|
{
|
||||||
error!("Error processing events: {e}");
|
error!("Error processing events: {e}");
|
||||||
}
|
}
|
||||||
|
|
@ -311,7 +314,7 @@ impl WaylandWindowingSystem {
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
event_queue: &mut EventQueue<WindowState>,
|
event_queue: &mut EventQueue<WindowState>,
|
||||||
shared_data: &mut WindowState,
|
shared_data: &mut WindowState,
|
||||||
popup_manager: &PopupManager,
|
popup_service: &PopupService,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(guard) = event_queue.prepare_read() {
|
if let Some(guard) = event_queue.prepare_read() {
|
||||||
guard
|
guard
|
||||||
|
|
@ -330,7 +333,7 @@ impl WaylandWindowingSystem {
|
||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup_manager
|
popup_service
|
||||||
.render_popups()
|
.render_popups()
|
||||||
.map_err(|e| RenderingError::Operation {
|
.map_err(|e| RenderingError::Operation {
|
||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,14 @@ use crate::wayland::managed_proxies::{
|
||||||
ManagedWlPointer, ManagedWlSurface, ManagedZwlrLayerSurfaceV1,
|
ManagedWlPointer, ManagedWlSurface, ManagedZwlrLayerSurfaceV1,
|
||||||
ManagedWpFractionalScaleV1, ManagedWpViewport,
|
ManagedWpFractionalScaleV1, ManagedWpViewport,
|
||||||
};
|
};
|
||||||
|
use crate::wayland::services::popup_service::{ActiveWindow, PopupService};
|
||||||
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
||||||
use crate::errors::{LayerShikaError, Result};
|
use crate::errors::{LayerShikaError, Result};
|
||||||
use core::result::Result as CoreResult;
|
use core::result::Result as CoreResult;
|
||||||
use layer_shika_domain::errors::DomainError;
|
use layer_shika_domain::errors::DomainError;
|
||||||
use layer_shika_domain::ports::windowing::RuntimeStatePort;
|
use layer_shika_domain::ports::windowing::RuntimeStatePort;
|
||||||
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
||||||
|
use layer_shika_domain::value_objects::popup_request::PopupHandle;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use slint::{LogicalPosition, PhysicalSize, ComponentHandle};
|
use slint::{LogicalPosition, PhysicalSize, ComponentHandle};
|
||||||
use slint::platform::{WindowAdapter, WindowEvent};
|
use slint::platform::{WindowAdapter, WindowEvent};
|
||||||
|
|
@ -54,12 +56,6 @@ enum ScalingMode {
|
||||||
Integer,
|
Integer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
enum ActiveWindow {
|
|
||||||
Main,
|
|
||||||
Popup(usize),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
component_instance: ComponentInstance,
|
component_instance: ComponentInstance,
|
||||||
compilation_result: Option<Rc<CompilationResult>>,
|
compilation_result: Option<Rc<CompilationResult>>,
|
||||||
|
|
@ -72,7 +68,7 @@ pub struct WindowState {
|
||||||
window: Rc<FemtoVGWindow>,
|
window: Rc<FemtoVGWindow>,
|
||||||
height: u32,
|
height: u32,
|
||||||
exclusive_zone: i32,
|
exclusive_zone: i32,
|
||||||
popup_manager: Option<Rc<PopupManager>>,
|
popup_service: Option<Rc<PopupService>>,
|
||||||
size: PhysicalSize,
|
size: PhysicalSize,
|
||||||
logical_size: PhysicalSize,
|
logical_size: PhysicalSize,
|
||||||
output_size: PhysicalSize,
|
output_size: PhysicalSize,
|
||||||
|
|
@ -80,7 +76,6 @@ pub struct WindowState {
|
||||||
last_pointer_serial: u32,
|
last_pointer_serial: u32,
|
||||||
shared_pointer_serial: Option<Rc<SharedPointerSerial>>,
|
shared_pointer_serial: Option<Rc<SharedPointerSerial>>,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
active_window: Option<ActiveWindow>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowState {
|
impl WindowState {
|
||||||
|
|
@ -150,7 +145,7 @@ impl WindowState {
|
||||||
window,
|
window,
|
||||||
height: builder.height,
|
height: builder.height,
|
||||||
exclusive_zone: builder.exclusive_zone,
|
exclusive_zone: builder.exclusive_zone,
|
||||||
popup_manager: None,
|
popup_service: None,
|
||||||
size: builder.size.unwrap_or_default(),
|
size: builder.size.unwrap_or_default(),
|
||||||
logical_size: PhysicalSize::default(),
|
logical_size: PhysicalSize::default(),
|
||||||
output_size: builder.output_size.unwrap_or_default(),
|
output_size: builder.output_size.unwrap_or_default(),
|
||||||
|
|
@ -158,7 +153,6 @@ impl WindowState {
|
||||||
last_pointer_serial: 0,
|
last_pointer_serial: 0,
|
||||||
shared_pointer_serial: None,
|
shared_pointer_serial: None,
|
||||||
scale_factor: builder.scale_factor,
|
scale_factor: builder.scale_factor,
|
||||||
active_window: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +178,8 @@ impl WindowState {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
ScalingMode::FractionalOnly => {
|
ScalingMode::FractionalOnly => {
|
||||||
self.window.set_scale_factor(dimensions.buffer_scale() as f32);
|
self.window
|
||||||
|
.set_scale_factor(dimensions.buffer_scale() as f32);
|
||||||
self.window
|
self.window
|
||||||
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
.set_size(slint::WindowSize::Logical(slint::LogicalSize::new(
|
||||||
dimensions.logical_width() as f32,
|
dimensions.logical_width() as f32,
|
||||||
|
|
@ -193,8 +188,9 @@ impl WindowState {
|
||||||
}
|
}
|
||||||
ScalingMode::Integer => {
|
ScalingMode::Integer => {
|
||||||
self.window.set_scale_factor(self.scale_factor);
|
self.window.set_scale_factor(self.scale_factor);
|
||||||
self.window
|
self.window.set_size(slint::WindowSize::Physical(
|
||||||
.set_size(slint::WindowSize::Physical(dimensions.to_slint_physical_size()));
|
dimensions.to_slint_physical_size(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -295,8 +291,8 @@ impl WindowState {
|
||||||
|
|
||||||
pub fn set_output_size(&mut self, output_size: PhysicalSize) {
|
pub fn set_output_size(&mut self, output_size: PhysicalSize) {
|
||||||
self.output_size = output_size;
|
self.output_size = output_size;
|
||||||
if let Some(popup_manager) = &self.popup_manager {
|
if let Some(popup_service) = &self.popup_service {
|
||||||
popup_manager.update_output_size(output_size);
|
popup_service.update_output_size(output_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -327,8 +323,8 @@ impl WindowState {
|
||||||
);
|
);
|
||||||
self.scale_factor = new_scale_factor;
|
self.scale_factor = new_scale_factor;
|
||||||
|
|
||||||
if let Some(popup_manager) = &self.popup_manager {
|
if let Some(popup_service) = &self.popup_service {
|
||||||
popup_manager.update_scale_factor(new_scale_factor);
|
popup_service.update_scale_factor(new_scale_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_logical_size = self.logical_size;
|
let current_logical_size = self.logical_size;
|
||||||
|
|
@ -356,41 +352,35 @@ impl WindowState {
|
||||||
self.shared_pointer_serial = Some(shared_serial);
|
self.shared_pointer_serial = Some(shared_serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_popup_service(&mut self, popup_service: Rc<PopupService>) {
|
||||||
|
self.popup_service = Some(popup_service);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_popup_manager(&mut self, popup_manager: Rc<PopupManager>) {
|
pub fn set_popup_manager(&mut self, popup_manager: Rc<PopupManager>) {
|
||||||
self.popup_manager = Some(popup_manager);
|
self.popup_service = Some(Rc::new(PopupService::new(popup_manager)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_window_for_surface(&mut self, surface: &WlSurface) {
|
pub fn find_window_for_surface(&mut self, surface: &WlSurface) {
|
||||||
let surface_id = surface.id();
|
if let Some(popup_service) = &self.popup_service {
|
||||||
|
popup_service.find_window_for_surface(surface, &(**self.surface.inner()).id());
|
||||||
if (**self.surface.inner()).id() == surface_id {
|
|
||||||
self.active_window = Some(ActiveWindow::Main);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(popup_manager) = &self.popup_manager {
|
|
||||||
if let Some(popup_key) = popup_manager.find_popup_key_by_surface_id(&surface_id) {
|
|
||||||
self.active_window = Some(ActiveWindow::Popup(popup_key));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.active_window = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_to_active_window(&self, event: WindowEvent) {
|
pub fn dispatch_to_active_window(&self, event: WindowEvent) {
|
||||||
match self.active_window {
|
if let Some(popup_service) = &self.popup_service {
|
||||||
Some(ActiveWindow::Main) => {
|
match popup_service.active_window() {
|
||||||
self.window.window().dispatch_event(event);
|
Some(ActiveWindow::Main) => {
|
||||||
}
|
self.window.window().dispatch_event(event);
|
||||||
Some(ActiveWindow::Popup(index)) => {
|
}
|
||||||
if let Some(popup_manager) = &self.popup_manager {
|
Some(ActiveWindow::Popup(index)) => {
|
||||||
if let Some(popup_window) = popup_manager.get_popup_window(index) {
|
if let Some(popup_window) =
|
||||||
|
popup_service.get_popup_window(PopupHandle::new(index))
|
||||||
|
{
|
||||||
popup_window.dispatch_event(event);
|
popup_window.dispatch_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,32 +399,32 @@ impl WindowState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(popup_manager) = &self.popup_manager {
|
if let Some(popup_service) = &self.popup_service {
|
||||||
if let Some(popup_key) =
|
popup_service
|
||||||
popup_manager.find_popup_key_by_fractional_scale_id(&fractional_scale_id)
|
.update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths);
|
||||||
{
|
|
||||||
if let Some(popup_window) = popup_manager.get_popup_window(popup_key) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_active_window(&mut self) {
|
pub fn clear_active_window(&mut self) {
|
||||||
self.active_window = None;
|
if let Some(popup_service) = &self.popup_service {
|
||||||
}
|
popup_service.clear_active_window();
|
||||||
|
|
||||||
pub fn clear_active_window_if_popup(&mut self, popup_key: usize) {
|
|
||||||
if self.active_window == Some(ActiveWindow::Popup(popup_key)) {
|
|
||||||
self.active_window = None;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn popup_manager(&self) -> &Option<Rc<PopupManager>> {
|
pub fn clear_active_window_if_popup(&mut self, popup_key: usize) {
|
||||||
&self.popup_manager
|
if let Some(popup_service) = &self.popup_service {
|
||||||
|
popup_service.clear_active_window_if_popup(popup_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn popup_service(&self) -> &Option<Rc<PopupService>> {
|
||||||
|
&self.popup_service
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn popup_manager(&self) -> Option<Rc<PopupManager>> {
|
||||||
|
self.popup_service
|
||||||
|
.as_ref()
|
||||||
|
.map(|service| Rc::clone(service.manager()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue