refactor: consolidate popup managing

This commit is contained in:
drendog 2025-11-13 09:32:13 +01:00
parent ee3204a618
commit 6fb26f15d3
Signed by: dwenya
GPG key ID: 8DD77074645332D0
11 changed files with 141 additions and 352 deletions

View file

@ -269,14 +269,14 @@ impl Dispatch<XdgPopup, ()> for WindowState {
} => {
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
if let Some(popup_service) = state.popup_service() {
if let Some(popup_manager) = state.popup_manager() {
let popup_id = xdg_popup.id();
if let Some(handle) = popup_service.find_by_xdg_popup(&popup_id) {
if let Some(handle) = popup_manager.find_by_xdg_popup(&popup_id) {
info!(
"Marking popup with handle {handle:?} as configured after XdgPopup::Configure"
);
popup_service.mark_popup_configured(handle);
popup_service.manager().mark_all_popups_dirty();
popup_manager.mark_popup_configured(handle.key());
popup_manager.mark_all_popups_dirty();
}
}
}
@ -284,14 +284,14 @@ impl Dispatch<XdgPopup, ()> for WindowState {
info!("XdgPopup dismissed by compositor");
let popup_id = xdg_popup.id();
let popup_handle = state
.popup_service()
.popup_manager()
.as_ref()
.and_then(|ps| ps.find_by_xdg_popup(&popup_id));
.and_then(|pm| pm.find_by_xdg_popup(&popup_id));
if let Some(handle) = popup_handle {
info!("Destroying popup with handle {handle:?}");
if let Some(popup_service) = state.popup_service() {
let _result = popup_service.close(handle);
if let Some(popup_manager) = state.popup_manager() {
let _result = popup_manager.close(handle);
}
}
}
@ -316,9 +316,9 @@ impl Dispatch<XdgSurface, ()> for WindowState {
info!("XdgSurface Configure received, sending ack with serial {serial}");
xdg_surface.ack_configure(serial);
if let Some(popup_service) = state.popup_service() {
if let Some(popup_manager) = state.popup_manager() {
info!("Marking all popups as dirty after Configure");
popup_service.manager().mark_all_popups_dirty();
popup_manager.mark_all_popups_dirty();
}
}
}

View file

@ -3,6 +3,5 @@ pub mod connection;
pub mod event_handling;
pub mod globals;
pub mod managed_proxies;
pub mod services;
pub mod shell_adapter;
pub mod surfaces;

View file

@ -1 +0,0 @@
pub mod popup_service;

View file

@ -1,180 +0,0 @@
use crate::errors::Result;
use crate::rendering::femtovg::popup_window::PopupWindow;
use crate::wayland::surfaces::popup_manager::PopupId;
use layer_shika_domain::value_objects::popup_request::{PopupHandle, PopupRequest};
use log::info;
use slint::PhysicalSize;
use std::cell::Cell;
use std::rc::Rc;
use wayland_client::{Proxy, backend::ObjectId, protocol::wl_surface::WlSurface};
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),
None,
}
pub struct PopupService {
manager: Rc<PopupManager>,
scale_factor: Cell<f32>,
}
impl PopupService {
#[must_use]
pub fn new(manager: Rc<PopupManager>) -> Self {
let scale_factor = manager.scale_factor();
Self {
manager,
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 id = PopupId::from_key(handle.key());
self.manager.destroy_popup(id);
Ok(())
}
pub fn close_current(&self) {
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()
}
#[must_use]
pub fn get_active_window(
&self,
surface: &WlSurface,
main_surface_id: &ObjectId,
) -> ActiveWindow {
let surface_id = surface.id();
if *main_surface_id == surface_id {
return ActiveWindow::Main;
}
if let Some(popup_key) = self.manager.find_popup_key_by_surface_id(&surface_id) {
return ActiveWindow::Popup(popup_key);
}
ActiveWindow::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()
}
}

View file

@ -1,7 +1,6 @@
use crate::wayland::{
config::{LayerSurfaceParams, WaylandWindowConfig},
globals::context::GlobalContext,
services::popup_service::PopupService,
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
surfaces::popup_manager::{CreatePopupParams, PopupContext, PopupManager},
surfaces::{
@ -39,7 +38,7 @@ pub struct WaylandWindowingSystem {
connection: Rc<Connection>,
event_queue: EventQueue<WindowState>,
event_loop: EventLoop<'static, WindowState>,
popup_service: Rc<PopupService>,
popup_manager: Rc<PopupManager>,
}
impl WaylandWindowingSystem {
@ -64,11 +63,10 @@ impl WaylandWindowingSystem {
popup_context,
Rc::clone(state.display_metrics()),
));
let popup_service = Rc::new(PopupService::new(popup_manager));
let shared_serial = Rc::new(SharedPointerSerial::new());
Self::setup_popup_creator(
&popup_service,
&popup_manager,
&platform,
&state,
&event_queue,
@ -80,12 +78,12 @@ impl WaylandWindowingSystem {
connection,
event_queue,
event_loop,
popup_service,
popup_manager,
})
.map(|mut system| {
system
.state
.set_popup_service(Rc::clone(&system.popup_service));
.set_popup_manager(Rc::clone(&system.popup_manager));
system.state.set_shared_pointer_serial(shared_serial);
system
})
@ -161,20 +159,20 @@ impl WaylandWindowingSystem {
}
fn setup_popup_creator(
popup_service: &Rc<PopupService>,
popup_manager: &Rc<PopupManager>,
platform: &Rc<CustomSlintPlatform>,
state: &WindowState,
event_queue: &EventQueue<WindowState>,
shared_serial: &Rc<SharedPointerSerial>,
) {
if !popup_service.has_xdg_shell() {
if !popup_manager.has_xdg_shell() {
info!("xdg-shell not available, popups will not be supported");
return;
}
info!("Setting up popup creator with xdg-shell support");
let popup_service_clone = Rc::clone(popup_service);
let popup_manager_clone = Rc::clone(popup_manager);
let layer_surface = state.layer_surface();
let queue_handle = event_queue.handle();
let serial_holder = Rc::clone(shared_serial);
@ -185,7 +183,7 @@ impl WaylandWindowingSystem {
let serial = serial_holder.get();
let (params, request) = if let Some((request, width, height)) =
popup_service_clone.take_pending_popup()
popup_manager_clone.take_pending_popup()
{
log::info!(
"Using popup request: component='{}', position=({}, {}), size={}x{}, mode={:?}",
@ -214,8 +212,7 @@ impl WaylandWindowingSystem {
));
};
let popup_window = popup_service_clone
.manager()
let popup_window = popup_manager_clone
.create_popup(&queue_handle, &layer_surface, params, request)
.map_err(|e| PlatformError::Other(format!("Failed to create popup: {e}")))?;
@ -280,12 +277,12 @@ impl WaylandWindowingSystem {
let event_queue = &mut self.event_queue;
let connection = &self.connection;
let popup_service = Rc::clone(&self.popup_service);
let popup_manager = Rc::clone(&self.popup_manager);
self.event_loop
.run(None, &mut self.state, move |shared_data| {
if let Err(e) =
Self::process_events(connection, event_queue, shared_data, &popup_service)
Self::process_events(connection, event_queue, shared_data, &popup_manager)
{
error!("Error processing events: {e}");
}
@ -315,7 +312,7 @@ impl WaylandWindowingSystem {
connection: &Connection,
event_queue: &mut EventQueue<WindowState>,
shared_data: &mut WindowState,
popup_service: &PopupService,
popup_manager: &PopupManager,
) -> Result<()> {
if let Some(guard) = event_queue.prepare_read() {
guard
@ -334,7 +331,7 @@ impl WaylandWindowingSystem {
message: e.to_string(),
})?;
popup_service
popup_manager
.render_popups()
.map_err(|e| RenderingError::Operation {
message: e.to_string(),

View file

@ -1,10 +1,8 @@
use crate::rendering::femtovg::main_window::FemtoVGWindow;
use crate::wayland::services::popup_service::{ActiveWindow, PopupService};
use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics;
use crate::wayland::surfaces::event_bus::EventBus;
use crate::wayland::surfaces::popup_manager::PopupManager;
use crate::wayland::surfaces::popup_manager::{ActiveWindow, PopupManager};
use crate::wayland::surfaces::window_events::{ScaleSource, WindowStateEvent};
use layer_shika_domain::value_objects::popup_request::PopupHandle;
use slint::platform::{WindowAdapter, WindowEvent};
use slint::{LogicalPosition, PhysicalSize};
use std::cell::Cell;
@ -41,7 +39,7 @@ impl SharedPointerSerial {
pub struct EventContext {
main_window: Rc<FemtoVGWindow>,
main_surface_id: ObjectId,
popup_service: Option<Rc<PopupService>>,
popup_manager: Option<Rc<PopupManager>>,
event_bus: EventBus,
display_metrics: SharedDisplayMetrics,
current_pointer_position: LogicalPosition,
@ -59,7 +57,7 @@ impl EventContext {
Self {
main_window,
main_surface_id,
popup_service: None,
popup_manager: None,
event_bus: EventBus::new(),
display_metrics,
current_pointer_position: LogicalPosition::new(0.0, 0.0),
@ -76,20 +74,14 @@ impl EventContext {
&self.event_bus
}
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>) {
self.popup_manager = Some(popup_manager);
self.event_bus
.publish(&WindowStateEvent::PopupConfigurationChanged);
}
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()))
pub const fn popup_manager(&self) -> &Option<Rc<PopupManager>> {
&self.popup_manager
}
#[must_use]
@ -108,8 +100,8 @@ impl EventContext {
.borrow_mut()
.update_scale_factor(scale_120ths);
if let Some(popup_service) = &self.popup_service {
popup_service.update_scale_factor(new_scale_factor);
if let Some(popup_manager) = &self.popup_manager {
popup_manager.update_scale_factor(new_scale_factor);
}
self.event_bus
@ -166,15 +158,13 @@ impl EventContext {
}
pub fn dispatch_to_active_window(&self, event: WindowEvent, surface: &WlSurface) {
if let Some(popup_service) = &self.popup_service {
match popup_service.get_active_window(surface, &self.main_surface_id) {
if let Some(popup_manager) = &self.popup_manager {
match popup_manager.get_active_window(surface, &self.main_surface_id) {
ActiveWindow::Main => {
self.main_window.window().dispatch_event(event);
}
ActiveWindow::Popup(index) => {
if let Some(popup_window) =
popup_service.get_popup_window(PopupHandle::new(index))
{
if let Some(popup_window) = popup_manager.get_popup_window(index) {
popup_window.dispatch_event(event);
}
}
@ -184,8 +174,8 @@ impl EventContext {
}
pub fn update_output_size(&self, output_size: PhysicalSize) {
if let Some(popup_service) = &self.popup_service {
popup_service.update_output_size(output_size);
if let Some(popup_manager) = &self.popup_manager {
popup_manager.update_output_size(output_size);
}
self.event_bus
@ -197,8 +187,8 @@ impl EventContext {
fractional_scale_proxy: &WpFractionalScaleV1,
scale_120ths: u32,
) {
if let Some(popup_service) = &self.popup_service {
popup_service
if let Some(popup_manager) = &self.popup_manager {
popup_manager
.update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths);
}
}

View file

@ -1,13 +1,12 @@
use crate::rendering::femtovg::main_window::FemtoVGWindow;
use crate::wayland::services::popup_service::{ActiveWindow, PopupService};
use layer_shika_domain::value_objects::popup_request::PopupHandle;
use crate::wayland::surfaces::popup_manager::{ActiveWindow, PopupManager};
use slint::platform::{WindowAdapter, WindowEvent};
use std::rc::Rc;
use wayland_client::{backend::ObjectId, protocol::wl_surface::WlSurface};
pub struct EventRouter {
main_window: Rc<FemtoVGWindow>,
popup_service: Option<Rc<PopupService>>,
popup_manager: Option<Rc<PopupManager>>,
main_surface_id: ObjectId,
}
@ -16,25 +15,23 @@ impl EventRouter {
pub const fn new(main_window: Rc<FemtoVGWindow>, main_surface_id: ObjectId) -> Self {
Self {
main_window,
popup_service: None,
popup_manager: None,
main_surface_id,
}
}
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>) {
self.popup_manager = Some(popup_manager);
}
pub fn dispatch_to_active_window(&self, event: WindowEvent, surface: &WlSurface) {
if let Some(popup_service) = &self.popup_service {
match popup_service.get_active_window(surface, &self.main_surface_id) {
if let Some(popup_manager) = &self.popup_manager {
match popup_manager.get_active_window(surface, &self.main_surface_id) {
ActiveWindow::Main => {
self.main_window.window().dispatch_event(event);
}
ActiveWindow::Popup(index) => {
if let Some(popup_window) =
popup_service.get_popup_window(PopupHandle::new(index))
{
if let Some(popup_window) = popup_manager.get_popup_window(index) {
popup_window.dispatch_event(event);
}
}

View file

@ -6,7 +6,6 @@ pub mod event_context;
pub mod event_router;
pub mod layer_surface;
pub mod popup_manager;
pub mod popup_state;
pub mod popup_surface;
pub mod rendering_state;
pub mod surface_builder;

View file

@ -4,25 +4,33 @@ use crate::rendering::femtovg::popup_window::PopupWindow;
use crate::wayland::surfaces::display_metrics::{DisplayMetricsObserver, SharedDisplayMetrics};
use layer_shika_domain::value_objects::popup_config::PopupConfig;
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
use layer_shika_domain::value_objects::popup_request::PopupRequest;
use layer_shika_domain::value_objects::popup_request::{PopupHandle, PopupRequest};
use log::info;
use slint::{platform::femtovg_renderer::FemtoVGRenderer, PhysicalSize, WindowSize};
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
use std::cell::RefCell;
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::rc::Rc;
use wayland_client::{
backend::ObjectId,
protocol::{wl_compositor::WlCompositor, wl_display::WlDisplay, wl_seat::WlSeat},
protocol::{wl_compositor::WlCompositor, wl_display::WlDisplay, wl_seat::WlSeat, wl_surface::WlSurface},
Connection, Proxy, QueueHandle,
};
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1;
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
use wayland_protocols::wp::viewporter::client::wp_viewporter::WpViewporter;
use wayland_protocols::xdg::shell::client::xdg_wm_base::XdgWmBase;
use super::popup_surface::PopupSurface;
use super::surface_state::WindowState;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ActiveWindow {
Main,
Popup(usize),
None,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PopupId(pub(crate) usize);
@ -123,14 +131,17 @@ impl PopupManagerState {
pub struct PopupManager {
context: PopupContext,
state: RefCell<PopupManagerState>,
scale_factor: Cell<f32>,
}
impl PopupManager {
#[must_use]
pub fn new(context: PopupContext, display_metrics: SharedDisplayMetrics) -> Self {
let scale_factor = display_metrics.borrow().scale_factor();
Self {
context,
state: RefCell::new(PopupManagerState::new(display_metrics)),
scale_factor: Cell::new(scale_factor),
}
}
@ -153,7 +164,7 @@ impl PopupManager {
#[must_use]
pub fn scale_factor(&self) -> f32 {
self.state.borrow().display_metrics.borrow().scale_factor()
self.scale_factor.get()
}
#[must_use]
@ -163,6 +174,7 @@ impl PopupManager {
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn update_scale_factor(&self, scale_factor: f32) {
self.scale_factor.set(scale_factor);
let scale_120ths = (scale_factor * 120.0) as u32;
self.state
.borrow()
@ -173,6 +185,7 @@ impl PopupManager {
for popup in self.state.borrow().popups.values() {
popup.window.set_scale_factor(scale_factor);
}
self.mark_all_popups_dirty();
}
pub fn update_output_size(&self, output_size: PhysicalSize) {
@ -402,6 +415,77 @@ impl PopupManager {
popup.window.mark_configured();
}
}
pub fn show(&self, request: PopupRequest, width: f32, height: f32) {
self.set_pending_popup(request, width, height);
}
pub fn close(&self, handle: PopupHandle) -> Result<()> {
let id = PopupId::from_key(handle.key());
self.destroy_popup(id);
Ok(())
}
#[must_use]
pub fn find_by_surface(&self, surface_id: &ObjectId) -> Option<PopupHandle> {
self.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.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.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.find_popup_key_by_xdg_surface_id(xdg_surface_id)
.map(PopupHandle::new)
}
#[must_use]
pub fn get_active_window(
&self,
surface: &WlSurface,
main_surface_id: &ObjectId,
) -> ActiveWindow {
let surface_id = surface.id();
if *main_surface_id == surface_id {
return ActiveWindow::Main;
}
if let Some(popup_key) = self.find_popup_key_by_surface_id(&surface_id) {
return ActiveWindow::Popup(popup_key);
}
ActiveWindow::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.find_popup_key_by_fractional_scale_id(&fractional_scale_id) {
if let Some(popup_window) = self.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();
}
}
}
}
impl DisplayMetricsObserver for PopupManager {

View file

@ -1,80 +0,0 @@
use crate::wayland::services::popup_service::PopupService;
use crate::wayland::surfaces::event_bus::EventBus;
use crate::wayland::surfaces::popup_manager::PopupManager;
use crate::wayland::surfaces::window_events::WindowStateEvent;
use slint::PhysicalSize;
use std::rc::Rc;
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
pub struct PopupState {
popup_service: Option<Rc<PopupService>>,
event_bus: EventBus,
}
impl Default for PopupState {
fn default() -> Self {
Self::new()
}
}
impl PopupState {
#[must_use]
pub fn new() -> Self {
Self {
popup_service: None,
event_bus: EventBus::new(),
}
}
pub fn set_event_bus(&mut self, event_bus: EventBus) {
self.event_bus = event_bus;
}
pub fn set_popup_service(&mut self, popup_service: Rc<PopupService>) {
self.popup_service = Some(popup_service);
self.event_bus
.publish(&WindowStateEvent::PopupConfigurationChanged);
}
pub fn set_popup_manager(&mut self, popup_manager: Rc<PopupManager>) {
self.popup_service = Some(Rc::new(PopupService::new(popup_manager)));
self.event_bus
.publish(&WindowStateEvent::PopupConfigurationChanged);
}
pub fn update_output_size(&self, output_size: PhysicalSize) {
if let Some(popup_service) = &self.popup_service {
popup_service.update_output_size(output_size);
}
self.event_bus
.publish(&WindowStateEvent::OutputSizeChanged { output_size });
}
pub fn update_scale_factor(&self, scale_factor: f32) {
if let Some(popup_service) = &self.popup_service {
popup_service.update_scale_factor(scale_factor);
}
}
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()))
}
pub fn update_scale_for_fractional_scale_object(
&self,
fractional_scale_proxy: &WpFractionalScaleV1,
scale_120ths: u32,
) {
if let Some(popup_service) = &self.popup_service {
popup_service
.update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths);
}
}
}

View file

@ -11,13 +11,11 @@ use crate::wayland::managed_proxies::{
ManagedWlPointer, ManagedWlSurface, ManagedZwlrLayerSurfaceV1,
ManagedWpFractionalScaleV1, ManagedWpViewport,
};
use crate::wayland::services::popup_service::PopupService;
use crate::rendering::femtovg::main_window::FemtoVGWindow;
use crate::errors::{LayerShikaError, Result};
use core::result::Result as CoreResult;
use layer_shika_domain::errors::DomainError;
use layer_shika_domain::ports::windowing::RuntimeStatePort;
use layer_shika_domain::value_objects::popup_request::PopupHandle;
use slint::{LogicalPosition, PhysicalSize};
use slint::platform::WindowEvent;
use slint_interpreter::{ComponentInstance, CompilationResult};
@ -210,25 +208,17 @@ impl WindowState {
self.event_context.set_shared_pointer_serial(shared_serial);
}
pub fn set_popup_service(&mut self, popup_service: Rc<PopupService>) {
self.event_context.set_popup_service(popup_service);
}
pub fn set_popup_manager(&mut self, popup_manager: Rc<PopupManager>) {
self.display_metrics
.borrow()
.register_observer(Rc::downgrade(&popup_manager) as _);
let popup_service = Rc::new(PopupService::new(popup_manager));
self.event_context.set_popup_service(popup_service);
self.event_context.set_popup_manager(popup_manager);
}
pub fn set_entered_surface(&self, surface: &WlSurface) {
if let Some(popup_service) = self.event_context.popup_service() {
if let Some(popup_key) = popup_service
.manager()
.find_popup_key_by_surface_id(&surface.id())
{
if let Some(popup_manager) = self.event_context.popup_manager() {
if let Some(popup_key) = popup_manager.find_popup_key_by_surface_id(&surface.id()) {
*self.active_popup_key.borrow_mut() = Some(popup_key);
return;
}
@ -244,10 +234,8 @@ impl WindowState {
let active_popup = *self.active_popup_key.borrow();
if let Some(popup_key) = active_popup {
if let Some(popup_service) = self.event_context.popup_service() {
if let Some(popup_window) =
popup_service.get_popup_window(PopupHandle::new(popup_key))
{
if let Some(popup_manager) = self.event_context.popup_manager() {
if let Some(popup_window) = popup_manager.get_popup_window(popup_key) {
popup_window.dispatch_event(event);
return;
}
@ -277,11 +265,7 @@ impl WindowState {
.update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths);
}
pub fn popup_service(&self) -> &Option<Rc<PopupService>> {
self.event_context.popup_service()
}
pub fn popup_manager(&self) -> Option<Rc<PopupManager>> {
pub fn popup_manager(&self) -> &Option<Rc<PopupManager>> {
self.event_context.popup_manager()
}
}