mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 07:05:56 +00:00
refactor: minor lock callback refactor
This commit is contained in:
parent
6cbbce773f
commit
d5b4953c1a
3 changed files with 215 additions and 77 deletions
|
|
@ -4,7 +4,99 @@ use layer_shika_domain::value_objects::output_info::OutputInfo;
|
||||||
use slint_interpreter::{ComponentInstance, Value};
|
use slint_interpreter::{ComponentInstance, Value};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub type LockCallbackHandler = Rc<dyn Fn(&[Value]) -> Value>;
|
pub(crate) trait FilterContext {
|
||||||
|
fn matches_filter(&self, filter: &dyn Fn(&Self) -> bool) -> bool {
|
||||||
|
filter(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterFn<Ctx> = Box<dyn Fn(&Ctx) -> bool>;
|
||||||
|
|
||||||
|
pub(crate) struct CallbackEntry<Ctx: FilterContext, Handler> {
|
||||||
|
name: String,
|
||||||
|
handler: Handler,
|
||||||
|
filter: Option<FilterFn<Ctx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Ctx: FilterContext, Handler: Clone> CallbackEntry<Ctx, Handler> {
|
||||||
|
fn new(name: impl Into<String>, handler: Handler) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
handler,
|
||||||
|
filter: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_filter<F>(name: impl Into<String>, handler: Handler, filter: F) -> Self
|
||||||
|
where
|
||||||
|
F: Fn(&Ctx) -> bool + 'static,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
handler,
|
||||||
|
filter: Some(Box::new(filter)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn should_apply(&self, context: &Ctx) -> bool {
|
||||||
|
self.filter
|
||||||
|
.as_ref()
|
||||||
|
.is_none_or(|f| context.matches_filter(f.as_ref()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handler(&self) -> &Handler {
|
||||||
|
&self.handler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Ctx: FilterContext, Handler: Clone> Clone for CallbackEntry<Ctx, Handler> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
name: self.name.clone(),
|
||||||
|
handler: self.handler.clone(),
|
||||||
|
filter: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CallbackHandler = Rc<dyn Fn(&[Value]) -> Value>;
|
||||||
|
|
||||||
|
pub struct LockCallbackContext {
|
||||||
|
pub component_name: String,
|
||||||
|
pub output_handle: OutputHandle,
|
||||||
|
pub output_info: Option<OutputInfo>,
|
||||||
|
pub primary_handle: Option<OutputHandle>,
|
||||||
|
pub active_handle: Option<OutputHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LockCallbackContext {
|
||||||
|
pub fn new(
|
||||||
|
component_name: String,
|
||||||
|
output_handle: OutputHandle,
|
||||||
|
output_info: Option<OutputInfo>,
|
||||||
|
primary_handle: Option<OutputHandle>,
|
||||||
|
active_handle: Option<OutputHandle>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
component_name,
|
||||||
|
output_handle,
|
||||||
|
output_info,
|
||||||
|
primary_handle,
|
||||||
|
active_handle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FilterContext for LockCallbackContext {}
|
||||||
|
|
||||||
|
pub type LockCallbackEntry = CallbackEntry<LockCallbackContext, CallbackHandler>;
|
||||||
|
|
||||||
|
pub type LockCallback = LockCallbackEntry;
|
||||||
|
|
||||||
pub type OutputFilter = Rc<
|
pub type OutputFilter = Rc<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&str,
|
&str,
|
||||||
|
|
@ -15,66 +107,64 @@ pub type OutputFilter = Rc<
|
||||||
) -> bool,
|
) -> bool,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub fn create_lock_callback(name: impl Into<String>, handler: CallbackHandler) -> LockCallback {
|
||||||
pub struct LockCallback {
|
LockCallbackEntry::new(name, handler)
|
||||||
name: String,
|
|
||||||
handler: LockCallbackHandler,
|
|
||||||
filter: Option<OutputFilter>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LockCallback {
|
pub fn create_lock_callback_with_output_filter<F>(
|
||||||
pub fn new(name: impl Into<String>, handler: LockCallbackHandler) -> Self {
|
name: impl Into<String>,
|
||||||
Self {
|
handler: CallbackHandler,
|
||||||
name: name.into(),
|
output_filter: F,
|
||||||
handler,
|
) -> LockCallback
|
||||||
filter: None,
|
where
|
||||||
}
|
F: Fn(
|
||||||
}
|
&str,
|
||||||
|
OutputHandle,
|
||||||
pub fn with_filter(
|
Option<&OutputInfo>,
|
||||||
name: impl Into<String>,
|
Option<OutputHandle>,
|
||||||
handler: LockCallbackHandler,
|
Option<OutputHandle>,
|
||||||
filter: OutputFilter,
|
) -> bool
|
||||||
) -> Self {
|
+ 'static,
|
||||||
Self {
|
{
|
||||||
name: name.into(),
|
LockCallbackEntry::with_filter(name, handler, move |ctx: &LockCallbackContext| {
|
||||||
handler,
|
output_filter(
|
||||||
filter: Some(filter),
|
&ctx.component_name,
|
||||||
}
|
ctx.output_handle,
|
||||||
}
|
ctx.output_info.as_ref(),
|
||||||
|
ctx.primary_handle,
|
||||||
pub fn should_apply(
|
ctx.active_handle,
|
||||||
&self,
|
|
||||||
component_name: &str,
|
|
||||||
output_handle: OutputHandle,
|
|
||||||
output_info: Option<&OutputInfo>,
|
|
||||||
primary_handle: Option<OutputHandle>,
|
|
||||||
active_handle: Option<OutputHandle>,
|
|
||||||
) -> bool {
|
|
||||||
self.filter.as_ref().map_or_else(
|
|
||||||
|| true,
|
|
||||||
|f| {
|
|
||||||
f(
|
|
||||||
component_name,
|
|
||||||
output_handle,
|
|
||||||
output_info,
|
|
||||||
primary_handle,
|
|
||||||
active_handle,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_to(&self, component: &ComponentInstance) -> Result<()> {
|
pub trait LockCallbackExt {
|
||||||
let handler = Rc::clone(&self.handler);
|
fn apply_to_component(&self, component: &ComponentInstance) -> Result<()>;
|
||||||
|
fn apply_with_context(
|
||||||
|
&self,
|
||||||
|
component: &ComponentInstance,
|
||||||
|
context: &LockCallbackContext,
|
||||||
|
) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LockCallbackExt for LockCallbackEntry {
|
||||||
|
fn apply_to_component(&self, component: &ComponentInstance) -> Result<()> {
|
||||||
|
let handler = Rc::clone(self.handler());
|
||||||
component
|
component
|
||||||
.set_callback(&self.name, move |args| handler(args))
|
.set_callback(self.name(), move |args| handler(args))
|
||||||
.map_err(|e| LayerShikaError::InvalidInput {
|
.map_err(|e| LayerShikaError::InvalidInput {
|
||||||
message: format!("Failed to register callback '{}': {e}", self.name),
|
message: format!("Failed to register callback '{}': {e}", self.name()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn name(&self) -> &String {
|
fn apply_with_context(
|
||||||
&self.name
|
&self,
|
||||||
|
component: &ComponentInstance,
|
||||||
|
context: &LockCallbackContext,
|
||||||
|
) -> Result<()> {
|
||||||
|
if !self.should_apply(context) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.apply_to_component(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::callbacks::{LockCallbackContext, LockCallbackExt};
|
||||||
use crate::errors::Result;
|
use crate::errors::Result;
|
||||||
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
||||||
use crate::rendering::femtovg::renderable_window::RenderableWindow;
|
use crate::rendering::femtovg::renderable_window::RenderableWindow;
|
||||||
|
|
@ -51,6 +52,11 @@ pub struct ActiveLockSurface {
|
||||||
component: Option<ComponentState>,
|
component: Option<ComponentState>,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
has_fractional_scale: bool,
|
has_fractional_scale: bool,
|
||||||
|
output_handle: Option<OutputHandle>,
|
||||||
|
component_name: Option<String>,
|
||||||
|
output_info: Option<OutputInfo>,
|
||||||
|
primary_handle: Option<OutputHandle>,
|
||||||
|
active_handle: Option<OutputHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveLockSurface {
|
impl ActiveLockSurface {
|
||||||
|
|
@ -61,6 +67,11 @@ impl ActiveLockSurface {
|
||||||
window,
|
window,
|
||||||
component: None,
|
component: None,
|
||||||
scale_factor: 1.0,
|
scale_factor: 1.0,
|
||||||
|
output_handle: None,
|
||||||
|
component_name: None,
|
||||||
|
output_info: None,
|
||||||
|
primary_handle: None,
|
||||||
|
active_handle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,6 +84,11 @@ impl ActiveLockSurface {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.surface.handle_configure(serial, width, height);
|
self.surface.handle_configure(serial, width, height);
|
||||||
self.scale_factor = context.scale_factor;
|
self.scale_factor = context.scale_factor;
|
||||||
|
self.output_handle = Some(context.output_handle);
|
||||||
|
self.component_name = Some(context.component_name.clone());
|
||||||
|
self.output_info.clone_from(&context.output_info);
|
||||||
|
self.primary_handle = context.primary_handle;
|
||||||
|
self.active_handle = context.active_handle;
|
||||||
let dimensions = match SurfaceDimensions::calculate(width, height, context.scale_factor) {
|
let dimensions = match SurfaceDimensions::calculate(width, height, context.scale_factor) {
|
||||||
Ok(dimensions) => dimensions,
|
Ok(dimensions) => dimensions,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
@ -103,22 +119,25 @@ impl ActiveLockSurface {
|
||||||
self.window
|
self.window
|
||||||
.window()
|
.window()
|
||||||
.dispatch_event(WindowEvent::WindowActiveChanged(true));
|
.dispatch_event(WindowEvent::WindowActiveChanged(true));
|
||||||
|
|
||||||
|
let callback_context = LockCallbackContext::new(
|
||||||
|
context.component_name.clone(),
|
||||||
|
context.output_handle,
|
||||||
|
context.output_info.clone(),
|
||||||
|
context.primary_handle,
|
||||||
|
context.active_handle,
|
||||||
|
);
|
||||||
|
|
||||||
for callback in &context.callbacks {
|
for callback in &context.callbacks {
|
||||||
if callback.should_apply(
|
if let Err(err) =
|
||||||
&context.component_name,
|
callback.apply_with_context(component.component_instance(), &callback_context)
|
||||||
context.output_handle,
|
{
|
||||||
context.output_info.as_ref(),
|
info!(
|
||||||
context.primary_handle,
|
"Failed to register lock callback '{}': {err}",
|
||||||
context.active_handle,
|
callback.name()
|
||||||
) {
|
);
|
||||||
if let Err(err) = callback.apply_to(component.component_instance()) {
|
} else if callback.should_apply(&callback_context) {
|
||||||
info!(
|
info!("Registered lock callback '{}'", callback.name());
|
||||||
"Failed to register lock callback '{}': {err}",
|
|
||||||
callback.name()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
info!("Registered lock callback '{}'", callback.name());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
info!(
|
info!(
|
||||||
"Skipping callback '{}' due to selector filter (output {:?})",
|
"Skipping callback '{}' due to selector filter (output {:?})",
|
||||||
|
|
@ -156,13 +175,33 @@ impl ActiveLockSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_callback(&self, callback: &LockCallback) {
|
pub fn apply_callback(&self, callback: &LockCallback) {
|
||||||
if let Some(component) = self.component.as_ref() {
|
let Some(component) = self.component.as_ref() else {
|
||||||
if let Err(err) = callback.apply_to(component.component_instance()) {
|
return;
|
||||||
info!(
|
};
|
||||||
"Failed to register lock callback '{}': {err}",
|
|
||||||
callback.name()
|
let Some(component_name) = &self.component_name else {
|
||||||
);
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let Some(output_handle) = self.output_handle else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let callback_context = LockCallbackContext::new(
|
||||||
|
component_name.clone(),
|
||||||
|
output_handle,
|
||||||
|
self.output_info.clone(),
|
||||||
|
self.primary_handle,
|
||||||
|
self.active_handle,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Err(err) =
|
||||||
|
callback.apply_with_context(component.component_instance(), &callback_context)
|
||||||
|
{
|
||||||
|
info!(
|
||||||
|
"Failed to register lock callback '{}': {err}",
|
||||||
|
callback.name()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ use crate::wayland::globals::context::GlobalContext;
|
||||||
use crate::wayland::managed_proxies::{ManagedWlKeyboard, ManagedWlPointer};
|
use crate::wayland::managed_proxies::{ManagedWlKeyboard, ManagedWlPointer};
|
||||||
use crate::wayland::outputs::{OutputManager, OutputMapping};
|
use crate::wayland::outputs::{OutputManager, OutputMapping};
|
||||||
use crate::wayland::session_lock::lock_context::SessionLockContext;
|
use crate::wayland::session_lock::lock_context::SessionLockContext;
|
||||||
|
use crate::wayland::session_lock::manager::callbacks::{
|
||||||
|
create_lock_callback, create_lock_callback_with_output_filter,
|
||||||
|
};
|
||||||
use crate::wayland::session_lock::{LockCallback, OutputFilter, SessionLockManager};
|
use crate::wayland::session_lock::{LockCallback, OutputFilter, SessionLockManager};
|
||||||
use layer_shika_domain::entities::output_registry::OutputRegistry;
|
use layer_shika_domain::entities::output_registry::OutputRegistry;
|
||||||
use layer_shika_domain::value_objects::handle::SurfaceHandle;
|
use layer_shika_domain::value_objects::handle::SurfaceHandle;
|
||||||
|
|
@ -138,7 +141,7 @@ impl AppState {
|
||||||
callback_name: impl Into<String>,
|
callback_name: impl Into<String>,
|
||||||
handler: SessionLockCallback,
|
handler: SessionLockCallback,
|
||||||
) {
|
) {
|
||||||
let callback = LockCallback::new(callback_name, handler);
|
let callback = create_lock_callback(callback_name, handler);
|
||||||
if let Some(manager) = self.lock_manager.as_mut() {
|
if let Some(manager) = self.lock_manager.as_mut() {
|
||||||
manager.register_callback(callback.clone());
|
manager.register_callback(callback.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +154,13 @@ impl AppState {
|
||||||
handler: SessionLockCallback,
|
handler: SessionLockCallback,
|
||||||
filter: OutputFilter,
|
filter: OutputFilter,
|
||||||
) {
|
) {
|
||||||
let callback = LockCallback::with_filter(callback_name, handler, filter);
|
let callback = create_lock_callback_with_output_filter(
|
||||||
|
callback_name,
|
||||||
|
handler,
|
||||||
|
move |component_name, output_handle, output_info, primary, active| {
|
||||||
|
filter(component_name, output_handle, output_info, primary, active)
|
||||||
|
},
|
||||||
|
);
|
||||||
if let Some(manager) = self.lock_manager.as_mut() {
|
if let Some(manager) = self.lock_manager.as_mut() {
|
||||||
manager.register_callback(callback.clone());
|
manager.register_callback(callback.clone());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue