refactor: popup manager minor changes

This commit is contained in:
drendog 2025-11-16 17:44:04 +01:00
parent 16ca0552c9
commit 596f0a5cf6
Signed by: dwenya
GPG key ID: 8DD77074645332D0
3 changed files with 51 additions and 57 deletions

View file

@ -2,7 +2,7 @@ use crate::wayland::{
config::{LayerSurfaceParams, WaylandWindowConfig}, config::{LayerSurfaceParams, WaylandWindowConfig},
globals::context::GlobalContext, globals::context::GlobalContext,
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams}, surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
surfaces::popup_manager::{CreatePopupParams, PopupContext, PopupManager}, surfaces::popup_manager::{PopupContext, PopupManager},
surfaces::{ surfaces::{
event_context::SharedPointerSerial, surface_builder::WindowStateBuilder, event_context::SharedPointerSerial, surface_builder::WindowStateBuilder,
surface_state::WindowState, surface_state::WindowState,
@ -183,38 +183,8 @@ 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()
{
log::info!(
"Using popup request: component='{}', position=({}, {}), size={}x{}, mode={:?}",
request.component,
request.at.position().0,
request.at.position().1,
width,
height,
request.mode
);
let params = CreatePopupParams {
last_pointer_serial: serial,
reference_x: request.at.position().0,
reference_y: request.at.position().1,
width,
height,
positioning_mode: request.mode,
};
(params, request)
} else {
log::warn!("Popup creator called without pending popup request - aborting");
return Err(PlatformError::Other(
"No popup request available - cannot create popup without parameters"
.to_string(),
));
};
let popup_window = popup_manager_clone let popup_window = popup_manager_clone
.create_popup(&queue_handle, &layer_surface, params, request) .create_pending_popup(&queue_handle, &layer_surface, serial)
.map_err(|e| PlatformError::Other(format!("Failed to create popup: {e}")))?; .map_err(|e| PlatformError::Other(format!("Failed to create popup: {e}")))?;
let result = Ok(popup_window as Rc<dyn WindowAdapter>); let result = Ok(popup_window as Rc<dyn WindowAdapter>);

View file

@ -34,7 +34,7 @@ pub enum ActiveWindow {
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct PopupId(usize); pub(crate) struct PopupId(usize);
impl PopupId { impl PopupId {
#[must_use] #[must_use]
@ -110,6 +110,7 @@ impl Drop for ActivePopup {
} }
struct PendingPopup { struct PendingPopup {
id: PopupId,
request: PopupRequest, request: PopupRequest,
width: f32, width: f32,
height: f32, height: f32,
@ -133,6 +134,12 @@ impl PopupManagerState {
id_generator: 0, id_generator: 0,
} }
} }
fn allocate_id(&mut self) -> PopupId {
let id = PopupId(self.id_generator);
self.id_generator += 1;
id
}
} }
pub struct PopupManager { pub struct PopupManager {
@ -152,21 +159,28 @@ impl PopupManager {
} }
} }
pub fn set_pending_popup(&self, request: PopupRequest, width: f32, height: f32) { pub fn request_popup(&self, request: PopupRequest, width: f32, height: f32) -> PopupHandle {
self.state.borrow_mut().pending_popup = Some(PendingPopup { let mut state = self.state.borrow_mut();
let id = state.allocate_id();
state.pending_popup = Some(PendingPopup {
id,
request, request,
width, width,
height, height,
}); });
id.to_handle()
} }
#[must_use] #[must_use]
pub fn take_pending_popup(&self) -> Option<(PopupRequest, f32, f32)> { pub(crate) fn take_pending_popup_params(&self) -> Option<(PopupId, PopupRequest, f32, f32)> {
self.state self.state
.borrow_mut() .borrow_mut()
.pending_popup .pending_popup
.take() .take()
.map(|p| (p.request, p.width, p.height)) .map(|p| (p.id, p.request, p.width, p.height))
} }
#[must_use] #[must_use]
@ -208,12 +222,37 @@ impl PopupManager {
self.state.borrow().current_popup_id.map(PopupId::key) self.state.borrow().current_popup_id.map(PopupId::key)
} }
pub fn create_popup( pub fn create_pending_popup(
self: &Rc<Self>,
queue_handle: &QueueHandle<WindowState>,
parent_layer_surface: &ZwlrLayerSurfaceV1,
last_pointer_serial: u32,
) -> Result<Rc<PopupWindow>> {
let (id, request, width, height) = self.take_pending_popup_params().ok_or_else(|| {
LayerShikaError::WindowConfiguration {
message: "No pending popup request available".into(),
}
})?;
let params = CreatePopupParams {
last_pointer_serial,
reference_x: request.at.position().0,
reference_y: request.at.position().1,
width,
height,
positioning_mode: request.mode,
};
self.create_popup_internal(queue_handle, parent_layer_surface, params, request, id)
}
fn create_popup_internal(
self: &Rc<Self>, self: &Rc<Self>,
queue_handle: &QueueHandle<WindowState>, queue_handle: &QueueHandle<WindowState>,
parent_layer_surface: &ZwlrLayerSurfaceV1, parent_layer_surface: &ZwlrLayerSurfaceV1,
params: CreatePopupParams, params: CreatePopupParams,
request: PopupRequest, request: PopupRequest,
popup_id: PopupId,
) -> Result<Rc<PopupWindow>> { ) -> Result<Rc<PopupWindow>> {
let xdg_wm_base = self.context.xdg_wm_base.as_ref().ok_or_else(|| { let xdg_wm_base = self.context.xdg_wm_base.as_ref().ok_or_else(|| {
LayerShikaError::WindowConfiguration { LayerShikaError::WindowConfiguration {
@ -285,13 +324,6 @@ impl PopupManager {
let renderer = FemtoVGRenderer::new(context) let renderer = FemtoVGRenderer::new(context)
.map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?; .map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?;
let popup_id = {
let mut state = self.state.borrow_mut();
let id = PopupId(state.id_generator);
state.id_generator += 1;
id
};
let on_close: OnCloseCallback = { let on_close: OnCloseCallback = {
let weak_self = Rc::downgrade(self); let weak_self = Rc::downgrade(self);
Box::new(move |handle: PopupHandle| { Box::new(move |handle: PopupHandle| {
@ -422,8 +454,8 @@ impl PopupManager {
} }
} }
pub fn show(&self, request: PopupRequest, width: f32, height: f32) { pub fn show(&self, request: PopupRequest, width: f32, height: f32) -> PopupHandle {
self.set_pending_popup(request, width, height); self.request_popup(request, width, height)
} }
pub fn close(&self, handle: PopupHandle) -> Result<()> { pub fn close(&self, handle: PopupHandle) -> Result<()> {

View file

@ -193,20 +193,12 @@ impl RuntimeState<'_> {
req.mode req.mode
); );
popup_manager.set_pending_popup(req, initial_dimensions.0, initial_dimensions.1); let popup_handle =
popup_manager.request_popup(req, initial_dimensions.0, initial_dimensions.1);
let (instance, popup_key_cell) = let (instance, popup_key_cell) =
Self::create_popup_instance(&definition, &popup_manager, resize_sender)?; Self::create_popup_instance(&definition, &popup_manager, resize_sender)?;
let popup_handle = popup_manager
.current_popup_key()
.map(PopupHandle::new)
.ok_or_else(|| {
Error::Domain(DomainError::Configuration {
message: "No popup key available after creation".to_string(),
})
})?;
popup_key_cell.set(popup_handle.key()); popup_key_cell.set(popup_handle.key());
if let Some(popup_window) = popup_manager.get_popup_window(popup_handle.key()) { if let Some(popup_window) = popup_manager.get_popup_window(popup_handle.key()) {