mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-11-17 23:14:23 +00:00
refactor: minor popup types
This commit is contained in:
parent
911f801ece
commit
65a4ff41f7
5 changed files with 66 additions and 48 deletions
|
|
@ -9,7 +9,7 @@ pub use rendering::femtovg::popup_window::PopupWindow;
|
||||||
pub use wayland::config::WaylandWindowConfig;
|
pub use wayland::config::WaylandWindowConfig;
|
||||||
pub use wayland::facade::{PopupManagerFacade, RuntimeStateFacade, WindowingSystemFacade};
|
pub use wayland::facade::{PopupManagerFacade, RuntimeStateFacade, WindowingSystemFacade};
|
||||||
pub use wayland::shell_adapter::WaylandWindowingSystem;
|
pub use wayland::shell_adapter::WaylandWindowingSystem;
|
||||||
pub use wayland::surfaces::popup_manager::{PopupId, PopupManager};
|
pub use wayland::surfaces::popup_manager::PopupManager;
|
||||||
pub use wayland::surfaces::surface_state::WindowState;
|
pub use wayland::surfaces::surface_state::WindowState;
|
||||||
|
|
||||||
pub mod platform {
|
pub mod platform {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use super::renderable_window::{RenderState, RenderableWindow};
|
use super::renderable_window::{RenderState, RenderableWindow};
|
||||||
use crate::errors::{RenderingError, Result};
|
use crate::errors::{RenderingError, Result};
|
||||||
use crate::wayland::surfaces::popup_manager::{OnCloseCallback, PopupId};
|
use crate::wayland::surfaces::popup_manager::OnCloseCallback;
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
|
use layer_shika_domain::value_objects::popup_request::PopupHandle;
|
||||||
use log::info;
|
use log::info;
|
||||||
use slint::{
|
use slint::{
|
||||||
PhysicalSize, Window, WindowSize,
|
PhysicalSize, Window, WindowSize,
|
||||||
|
|
@ -17,7 +18,7 @@ pub struct PopupWindow {
|
||||||
render_state: Cell<RenderState>,
|
render_state: Cell<RenderState>,
|
||||||
size: Cell<PhysicalSize>,
|
size: Cell<PhysicalSize>,
|
||||||
scale_factor: Cell<f32>,
|
scale_factor: Cell<f32>,
|
||||||
popup_id: Cell<Option<PopupId>>,
|
popup_handle: Cell<Option<PopupHandle>>,
|
||||||
on_close: OnceCell<OnCloseCallback>,
|
on_close: OnceCell<OnCloseCallback>,
|
||||||
configured: Cell<bool>,
|
configured: Cell<bool>,
|
||||||
component_instance: OnceCell<ComponentInstance>,
|
component_instance: OnceCell<ComponentInstance>,
|
||||||
|
|
@ -34,7 +35,7 @@ impl PopupWindow {
|
||||||
render_state: Cell::new(RenderState::Clean),
|
render_state: Cell::new(RenderState::Clean),
|
||||||
size: Cell::new(PhysicalSize::default()),
|
size: Cell::new(PhysicalSize::default()),
|
||||||
scale_factor: Cell::new(1.),
|
scale_factor: Cell::new(1.),
|
||||||
popup_id: Cell::new(None),
|
popup_handle: Cell::new(None),
|
||||||
on_close: OnceCell::new(),
|
on_close: OnceCell::new(),
|
||||||
configured: Cell::new(false),
|
configured: Cell::new(false),
|
||||||
component_instance: OnceCell::new(),
|
component_instance: OnceCell::new(),
|
||||||
|
|
@ -49,8 +50,8 @@ impl PopupWindow {
|
||||||
window
|
window
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_popup_id(&self, id: PopupId) {
|
pub fn set_popup_id(&self, handle: PopupHandle) {
|
||||||
self.popup_id.set(Some(id));
|
self.popup_handle.set(Some(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_popup(&self) {
|
pub fn close_popup(&self) {
|
||||||
|
|
@ -60,20 +61,20 @@ impl PopupWindow {
|
||||||
info!("Failed to hide popup window: {e}");
|
info!("Failed to hide popup window: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = self.popup_id.get() {
|
if let Some(handle) = self.popup_handle.get() {
|
||||||
info!("Destroying popup with id {:?}", id);
|
info!("Destroying popup with handle {:?}", handle);
|
||||||
if let Some(on_close) = self.on_close.get() {
|
if let Some(on_close) = self.on_close.get() {
|
||||||
on_close(id);
|
on_close(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.popup_id.set(None);
|
self.popup_handle.set(None);
|
||||||
|
|
||||||
info!("Popup window cleanup complete");
|
info!("Popup window cleanup complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn popup_key(&self) -> Option<usize> {
|
pub fn popup_key(&self) -> Option<usize> {
|
||||||
self.popup_id.get().map(PopupId::key)
|
self.popup_handle.get().map(PopupHandle::key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_configured(&self) {
|
pub fn mark_configured(&self) {
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,8 @@ impl EventContext {
|
||||||
ActiveWindow::Main => {
|
ActiveWindow::Main => {
|
||||||
self.main_window.window().dispatch_event(event);
|
self.main_window.window().dispatch_event(event);
|
||||||
}
|
}
|
||||||
ActiveWindow::Popup(index) => {
|
ActiveWindow::Popup(handle) => {
|
||||||
if let Some(popup_window) = popup_manager.get_popup_window(index) {
|
if let Some(popup_window) = popup_manager.get_popup_window(handle.key()) {
|
||||||
popup_window.dispatch_event(event);
|
popup_window.dispatch_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,26 +29,31 @@ use super::surface_state::WindowState;
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ActiveWindow {
|
pub enum ActiveWindow {
|
||||||
Main,
|
Main,
|
||||||
Popup(usize),
|
Popup(PopupHandle),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct PopupId(pub(crate) usize);
|
struct PopupId(usize);
|
||||||
|
|
||||||
impl PopupId {
|
impl PopupId {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn key(self) -> usize {
|
const fn key(self) -> usize {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn from_key(key: usize) -> Self {
|
const fn from_handle(handle: PopupHandle) -> Self {
|
||||||
Self(key)
|
Self(handle.key())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
const fn to_handle(self) -> PopupHandle {
|
||||||
|
PopupHandle::new(self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type OnCloseCallback = Box<dyn Fn(PopupId)>;
|
pub type OnCloseCallback = Box<dyn Fn(PopupHandle)>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct CreatePopupParams {
|
pub struct CreatePopupParams {
|
||||||
|
|
@ -291,15 +296,16 @@ impl PopupManager {
|
||||||
|
|
||||||
let on_close: OnCloseCallback = {
|
let on_close: OnCloseCallback = {
|
||||||
let weak_self = Rc::downgrade(self);
|
let weak_self = Rc::downgrade(self);
|
||||||
Box::new(move |id: PopupId| {
|
Box::new(move |handle: PopupHandle| {
|
||||||
if let Some(manager) = weak_self.upgrade() {
|
if let Some(manager) = weak_self.upgrade() {
|
||||||
|
let id = PopupId::from_handle(handle);
|
||||||
manager.destroy_popup(id);
|
manager.destroy_popup(id);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let popup_window = PopupWindow::new_with_callback(renderer, on_close);
|
let popup_window = PopupWindow::new_with_callback(renderer, on_close);
|
||||||
popup_window.set_popup_id(popup_id);
|
popup_window.set_popup_id(popup_id.to_handle());
|
||||||
popup_window.set_scale_factor(scale_factor);
|
popup_window.set_scale_factor(scale_factor);
|
||||||
popup_window.set_size(WindowSize::Logical(slint::LogicalSize::new(
|
popup_window.set_size(WindowSize::Logical(slint::LogicalSize::new(
|
||||||
params.width,
|
params.width,
|
||||||
|
|
@ -373,7 +379,7 @@ impl PopupManager {
|
||||||
.map(|popup| Rc::clone(&popup.window))
|
.map(|popup| Rc::clone(&popup.window))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy_popup(&self, id: PopupId) {
|
fn destroy_popup(&self, id: PopupId) {
|
||||||
if let Some(popup) = self.state.borrow_mut().popups.remove(&id) {
|
if let Some(popup) = self.state.borrow_mut().popups.remove(&id) {
|
||||||
info!("Destroying popup with id {:?}", id);
|
info!("Destroying popup with id {:?}", id);
|
||||||
|
|
||||||
|
|
@ -423,7 +429,7 @@ impl PopupManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self, handle: PopupHandle) -> Result<()> {
|
pub fn close(&self, handle: PopupHandle) -> Result<()> {
|
||||||
let id = PopupId::from_key(handle.key());
|
let id = PopupId::from_handle(handle);
|
||||||
self.destroy_popup(id);
|
self.destroy_popup(id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -464,8 +470,11 @@ impl PopupManager {
|
||||||
return ActiveWindow::Main;
|
return ActiveWindow::Main;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(popup_key) = self.find_popup_key_by_surface_id(&surface_id) {
|
if let Some(popup_handle) = self
|
||||||
return ActiveWindow::Popup(popup_key);
|
.find_popup_key_by_surface_id(&surface_id)
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
{
|
||||||
|
return ActiveWindow::Popup(popup_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveWindow::None
|
ActiveWindow::None
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@ use layer_shika_adapters::platform::slint::{ComponentHandle, SharedString};
|
||||||
use layer_shika_adapters::platform::slint_interpreter::{
|
use layer_shika_adapters::platform::slint_interpreter::{
|
||||||
CompilationResult, ComponentDefinition, ComponentInstance, Value,
|
CompilationResult, ComponentDefinition, ComponentInstance, Value,
|
||||||
};
|
};
|
||||||
use layer_shika_adapters::{
|
use layer_shika_adapters::{PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade};
|
||||||
PopupId, PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade,
|
|
||||||
};
|
|
||||||
use layer_shika_domain::config::WindowConfig;
|
use layer_shika_domain::config::WindowConfig;
|
||||||
use layer_shika_domain::errors::DomainError;
|
use layer_shika_domain::errors::DomainError;
|
||||||
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
|
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
|
||||||
|
|
@ -27,7 +25,11 @@ use std::time::{Duration, Instant};
|
||||||
pub enum PopupCommand {
|
pub enum PopupCommand {
|
||||||
Show(PopupRequest),
|
Show(PopupRequest),
|
||||||
Close(PopupHandle),
|
Close(PopupHandle),
|
||||||
Resize { key: usize, width: f32, height: f32 },
|
Resize {
|
||||||
|
handle: PopupHandle,
|
||||||
|
width: f32,
|
||||||
|
height: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventLoopHandle {
|
pub struct EventLoopHandle {
|
||||||
|
|
@ -197,15 +199,18 @@ impl RuntimeState<'_> {
|
||||||
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_key = popup_manager.current_popup_key().ok_or_else(|| {
|
let popup_handle = popup_manager
|
||||||
|
.current_popup_key()
|
||||||
|
.map(PopupHandle::new)
|
||||||
|
.ok_or_else(|| {
|
||||||
Error::Domain(DomainError::Configuration {
|
Error::Domain(DomainError::Configuration {
|
||||||
message: "No popup key available after creation".to_string(),
|
message: "No popup key available after creation".to_string(),
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup_key_cell.set(popup_key);
|
popup_key_cell.set(popup_handle.key());
|
||||||
|
|
||||||
if let Some(popup_window) = popup_manager.get_popup_window(popup_key) {
|
if let Some(popup_window) = popup_manager.get_popup_window(popup_handle.key()) {
|
||||||
popup_window.set_component_instance(instance);
|
popup_window.set_component_instance(instance);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Domain(DomainError::Configuration {
|
return Err(Error::Domain(DomainError::Configuration {
|
||||||
|
|
@ -213,13 +218,12 @@ impl RuntimeState<'_> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PopupHandle::new(popup_key))
|
Ok(popup_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_popup(&mut self, handle: PopupHandle) -> Result<()> {
|
pub fn close_popup(&mut self, handle: PopupHandle) -> Result<()> {
|
||||||
if let Some(popup_manager) = self.window_state.popup_manager() {
|
if let Some(popup_manager) = self.window_state.popup_manager() {
|
||||||
let id = PopupId::from_key(handle.key());
|
popup_manager.close(handle)?;
|
||||||
popup_manager.destroy_popup(id);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -233,7 +237,7 @@ impl RuntimeState<'_> {
|
||||||
|
|
||||||
pub fn resize_popup(
|
pub fn resize_popup(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: usize,
|
handle: PopupHandle,
|
||||||
width: f32,
|
width: f32,
|
||||||
height: f32,
|
height: f32,
|
||||||
resize_sender: Option<channel::Sender<PopupCommand>>,
|
resize_sender: Option<channel::Sender<PopupCommand>>,
|
||||||
|
|
@ -248,10 +252,10 @@ impl RuntimeState<'_> {
|
||||||
})
|
})
|
||||||
.cloned()?;
|
.cloned()?;
|
||||||
|
|
||||||
let Some((request, _serial)) = popup_manager.get_popup_info(key) else {
|
let Some((request, _serial)) = popup_manager.get_popup_info(handle.key()) else {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Ignoring resize request for non-existent popup with key {}",
|
"Ignoring resize request for non-existent popup with handle {:?}",
|
||||||
key
|
handle
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
@ -270,7 +274,7 @@ impl RuntimeState<'_> {
|
||||||
height
|
height
|
||||||
);
|
);
|
||||||
|
|
||||||
self.close_popup(PopupHandle::new(key))?;
|
self.close_popup(handle)?;
|
||||||
|
|
||||||
let new_request = PopupRequest::builder(request.component)
|
let new_request = PopupRequest::builder(request.component)
|
||||||
.at(request.at)
|
.at(request.at)
|
||||||
|
|
@ -280,7 +284,7 @@ impl RuntimeState<'_> {
|
||||||
|
|
||||||
self.show_popup(new_request, resize_sender)?;
|
self.show_popup(new_request, resize_sender)?;
|
||||||
} else if size_changed {
|
} else if size_changed {
|
||||||
if let Some(popup_window) = popup_manager.get_popup_window(key) {
|
if let Some(popup_window) = popup_manager.get_popup_window(handle.key()) {
|
||||||
popup_window.request_resize(width, height);
|
popup_window.request_resize(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +341,7 @@ impl RuntimeState<'_> {
|
||||||
|
|
||||||
if sender
|
if sender
|
||||||
.send(PopupCommand::Resize {
|
.send(PopupCommand::Resize {
|
||||||
key: popup_key,
|
handle: PopupHandle::new(popup_key),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
})
|
})
|
||||||
|
|
@ -451,9 +455,13 @@ impl WindowingSystem {
|
||||||
log::error!("Failed to close popup: {}", e);
|
log::error!("Failed to close popup: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PopupCommand::Resize { key, width, height } => {
|
PopupCommand::Resize {
|
||||||
|
handle,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
} => {
|
||||||
if let Err(e) = runtime_state.resize_popup(
|
if let Err(e) = runtime_state.resize_popup(
|
||||||
key,
|
handle,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
Some(sender_for_handler.clone()),
|
Some(sender_for_handler.clone()),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue