mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 07:05:56 +00:00
fix: session lock selectors, lost filter during clone, and wrong surface id
This commit is contained in:
parent
e025cb008c
commit
a2d6dd5f9f
10 changed files with 245 additions and 23 deletions
|
|
@ -8,7 +8,9 @@ pub use rendering::femtovg::popup_window::PopupWindow;
|
||||||
|
|
||||||
pub use wayland::config::{MultiSurfaceConfig, ShellSurfaceConfig, WaylandSurfaceConfig};
|
pub use wayland::config::{MultiSurfaceConfig, ShellSurfaceConfig, WaylandSurfaceConfig};
|
||||||
pub use wayland::ops::WaylandSystemOps;
|
pub use wayland::ops::WaylandSystemOps;
|
||||||
pub use wayland::session_lock::{LockSurfaceOutputContext, OutputFilter};
|
pub use wayland::session_lock::{
|
||||||
|
create_lock_property_operation_with_output_filter, LockSurfaceOutputContext, OutputFilter,
|
||||||
|
};
|
||||||
pub use wayland::shell_adapter::WaylandShellSystem;
|
pub use wayland::shell_adapter::WaylandShellSystem;
|
||||||
pub use wayland::surfaces::app_state::AppState;
|
pub use wayland::surfaces::app_state::AppState;
|
||||||
pub use wayland::surfaces::popup_manager::PopupManager;
|
pub use wayland::surfaces::popup_manager::PopupManager;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::errors::Result;
|
use crate::errors::Result;
|
||||||
use crate::wayland::config::ShellSurfaceConfig;
|
use crate::wayland::config::ShellSurfaceConfig;
|
||||||
use crate::wayland::session_lock::OutputFilter;
|
use crate::wayland::session_lock::{LockPropertyOperation, OutputFilter};
|
||||||
use crate::wayland::surfaces::app_state::AppState;
|
use crate::wayland::surfaces::app_state::AppState;
|
||||||
use layer_shika_domain::value_objects::lock_config::LockConfig;
|
use layer_shika_domain::value_objects::lock_config::LockConfig;
|
||||||
use layer_shika_domain::value_objects::lock_state::LockState;
|
use layer_shika_domain::value_objects::lock_state::LockState;
|
||||||
|
|
@ -38,6 +38,8 @@ pub trait WaylandSystemOps {
|
||||||
filter: OutputFilter,
|
filter: OutputFilter,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn register_session_lock_property_operation(&mut self, property_operation: LockPropertyOperation);
|
||||||
|
|
||||||
fn session_lock_component_name(&self) -> Option<String>;
|
fn session_lock_component_name(&self) -> Option<String>;
|
||||||
|
|
||||||
fn iter_lock_surfaces(&self, f: &mut dyn FnMut(OutputHandle, &ComponentInstance));
|
fn iter_lock_surfaces(&self, f: &mut dyn FnMut(OutputHandle, &ComponentInstance));
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ pub(crate) trait FilterContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilterFn<Ctx> = Box<dyn Fn(&Ctx) -> bool>;
|
type FilterFn<Ctx> = Rc<dyn Fn(&Ctx) -> bool>;
|
||||||
|
|
||||||
pub(crate) struct CallbackEntry<Ctx: FilterContext, Handler> {
|
pub(crate) struct CallbackEntry<Ctx: FilterContext, Handler> {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -34,7 +34,7 @@ impl<Ctx: FilterContext, Handler: Clone> CallbackEntry<Ctx, Handler> {
|
||||||
Self {
|
Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
handler,
|
handler,
|
||||||
filter: Some(Box::new(filter)),
|
filter: Some(Rc::new(filter)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ impl<Ctx: FilterContext, Handler: Clone> Clone for CallbackEntry<Ctx, Handler> {
|
||||||
Self {
|
Self {
|
||||||
name: self.name.clone(),
|
name: self.name.clone(),
|
||||||
handler: self.handler.clone(),
|
handler: self.handler.clone(),
|
||||||
filter: None,
|
filter: self.filter.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -168,3 +168,115 @@ impl LockCallbackExt for LockCallbackEntry {
|
||||||
self.apply_to_component(component)
|
self.apply_to_component(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LockPropertyOperation {
|
||||||
|
name: String,
|
||||||
|
value: Value,
|
||||||
|
filter: Option<FilterFn<LockCallbackContext>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LockPropertyOperation {
|
||||||
|
pub fn new(name: impl Into<String>, value: Value) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
value,
|
||||||
|
filter: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_filter<F>(name: impl Into<String>, value: Value, filter: F) -> Self
|
||||||
|
where
|
||||||
|
F: Fn(&LockCallbackContext) -> bool + 'static,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
value,
|
||||||
|
filter: Some(Rc::new(filter)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn should_apply(&self, context: &LockCallbackContext) -> bool {
|
||||||
|
self.filter
|
||||||
|
.as_ref()
|
||||||
|
.is_none_or(|f| context.matches_filter(f.as_ref()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> &Value {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for LockPropertyOperation {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
name: self.name.clone(),
|
||||||
|
value: self.value.clone(),
|
||||||
|
filter: self.filter.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_lock_property_operation(name: impl Into<String>, value: Value) -> LockPropertyOperation {
|
||||||
|
LockPropertyOperation::new(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_lock_property_operation_with_output_filter<F>(
|
||||||
|
name: impl Into<String>,
|
||||||
|
value: Value,
|
||||||
|
output_filter: F,
|
||||||
|
) -> LockPropertyOperation
|
||||||
|
where
|
||||||
|
F: Fn(
|
||||||
|
&str,
|
||||||
|
OutputHandle,
|
||||||
|
Option<&OutputInfo>,
|
||||||
|
Option<OutputHandle>,
|
||||||
|
Option<OutputHandle>,
|
||||||
|
) -> bool
|
||||||
|
+ 'static,
|
||||||
|
{
|
||||||
|
LockPropertyOperation::with_filter(name, value, move |ctx: &LockCallbackContext| {
|
||||||
|
output_filter(
|
||||||
|
&ctx.component_name,
|
||||||
|
ctx.output_handle,
|
||||||
|
ctx.output_info.as_ref(),
|
||||||
|
ctx.primary_handle,
|
||||||
|
ctx.active_handle,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LockPropertyOperationExt {
|
||||||
|
fn apply_to_component(&self, component: &ComponentInstance) -> Result<()>;
|
||||||
|
fn apply_with_context(
|
||||||
|
&self,
|
||||||
|
component: &ComponentInstance,
|
||||||
|
context: &LockCallbackContext,
|
||||||
|
) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LockPropertyOperationExt for LockPropertyOperation {
|
||||||
|
fn apply_to_component(&self, component: &ComponentInstance) -> Result<()> {
|
||||||
|
component
|
||||||
|
.set_property(self.name(), self.value().clone())
|
||||||
|
.map_err(|e| LayerShikaError::InvalidInput {
|
||||||
|
message: format!("Failed to set property '{}': {e}", self.name()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_with_context(
|
||||||
|
&self,
|
||||||
|
component: &ComponentInstance,
|
||||||
|
context: &LockCallbackContext,
|
||||||
|
) -> Result<()> {
|
||||||
|
if !self.should_apply(context) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.apply_to_component(component)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,10 @@ use wayland_client::{
|
||||||
};
|
};
|
||||||
use wayland_protocols::ext::session_lock::v1::client::ext_session_lock_v1::ExtSessionLockV1;
|
use wayland_protocols::ext::session_lock::v1::client::ext_session_lock_v1::ExtSessionLockV1;
|
||||||
|
|
||||||
pub use callbacks::{LockCallback, OutputFilter};
|
pub use callbacks::{
|
||||||
|
create_lock_property_operation_with_output_filter, LockCallback, LockPropertyOperation,
|
||||||
|
OutputFilter,
|
||||||
|
};
|
||||||
pub use state::{ActiveLockSurface, LockConfigureContext, LockSurfaceOutputContext};
|
pub use state::{ActiveLockSurface, LockConfigureContext, LockSurfaceOutputContext};
|
||||||
|
|
||||||
use self::input_handling::InputState;
|
use self::input_handling::InputState;
|
||||||
|
|
@ -39,6 +42,7 @@ pub struct SessionLockManager {
|
||||||
compilation_result: Option<Rc<CompilationResult>>,
|
compilation_result: Option<Rc<CompilationResult>>,
|
||||||
platform: Rc<CustomSlintPlatform>,
|
platform: Rc<CustomSlintPlatform>,
|
||||||
callbacks: Vec<LockCallback>,
|
callbacks: Vec<LockCallback>,
|
||||||
|
property_operations: Vec<LockPropertyOperation>,
|
||||||
input_state: InputState,
|
input_state: InputState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,6 +65,7 @@ impl SessionLockManager {
|
||||||
compilation_result,
|
compilation_result,
|
||||||
platform,
|
platform,
|
||||||
callbacks: Vec::new(),
|
callbacks: Vec::new(),
|
||||||
|
property_operations: Vec::new(),
|
||||||
input_state: InputState::new(),
|
input_state: InputState::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +224,7 @@ impl SessionLockManager {
|
||||||
pub fn find_output_id_for_lock_surface(&self, lock_surface_id: &ObjectId) -> Option<ObjectId> {
|
pub fn find_output_id_for_lock_surface(&self, lock_surface_id: &ObjectId) -> Option<ObjectId> {
|
||||||
self.lock_surfaces
|
self.lock_surfaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, surface)| surface.surface().surface_id() == *lock_surface_id)
|
.find(|(_, surface)| surface.surface().lock_surface_id() == *lock_surface_id)
|
||||||
.map(|(id, _)| id.clone())
|
.map(|(id, _)| id.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,6 +244,7 @@ impl SessionLockManager {
|
||||||
compilation_result: self.compilation_result.clone(),
|
compilation_result: self.compilation_result.clone(),
|
||||||
platform: Rc::clone(&self.platform),
|
platform: Rc::clone(&self.platform),
|
||||||
callbacks: self.callbacks.clone(),
|
callbacks: self.callbacks.clone(),
|
||||||
|
property_operations: self.property_operations.clone(),
|
||||||
component_name,
|
component_name,
|
||||||
output_handle: output_ctx.output_handle,
|
output_handle: output_ctx.output_handle,
|
||||||
output_info: output_ctx.output_info,
|
output_info: output_ctx.output_info,
|
||||||
|
|
@ -269,6 +275,7 @@ impl SessionLockManager {
|
||||||
compilation_result: self.compilation_result.clone(),
|
compilation_result: self.compilation_result.clone(),
|
||||||
platform: Rc::clone(&self.platform),
|
platform: Rc::clone(&self.platform),
|
||||||
callbacks: self.callbacks.clone(),
|
callbacks: self.callbacks.clone(),
|
||||||
|
property_operations: self.property_operations.clone(),
|
||||||
component_name,
|
component_name,
|
||||||
output_handle: output_ctx.output_handle,
|
output_handle: output_ctx.output_handle,
|
||||||
output_info: output_ctx.output_info,
|
output_info: output_ctx.output_info,
|
||||||
|
|
@ -298,6 +305,7 @@ impl SessionLockManager {
|
||||||
compilation_result: self.compilation_result.clone(),
|
compilation_result: self.compilation_result.clone(),
|
||||||
platform: Rc::clone(&self.platform),
|
platform: Rc::clone(&self.platform),
|
||||||
callbacks: self.callbacks.clone(),
|
callbacks: self.callbacks.clone(),
|
||||||
|
property_operations: self.property_operations.clone(),
|
||||||
component_name: component_name.clone(),
|
component_name: component_name.clone(),
|
||||||
output_handle,
|
output_handle,
|
||||||
output_info: surface.output_info.clone(),
|
output_info: surface.output_info.clone(),
|
||||||
|
|
@ -323,6 +331,13 @@ impl SessionLockManager {
|
||||||
self.callbacks.push(callback);
|
self.callbacks.push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn register_property_operation(&mut self, property_operation: LockPropertyOperation) {
|
||||||
|
for (_, surface) in &self.lock_surfaces {
|
||||||
|
surface.apply_property_operation(&property_operation);
|
||||||
|
}
|
||||||
|
self.property_operations.push(property_operation);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_fractional_scale(&mut self, fractional_scale_id: &ObjectId, scale_120ths: u32) {
|
pub fn handle_fractional_scale(&mut self, fractional_scale_id: &ObjectId, scale_120ths: u32) {
|
||||||
for (_, surface) in &mut self.lock_surfaces {
|
for (_, surface) in &mut self.lock_surfaces {
|
||||||
let matches = surface
|
let matches = surface
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::callbacks::{LockCallbackContext, LockCallbackExt};
|
use super::callbacks::{LockCallbackContext, LockCallbackExt, LockPropertyOperationExt};
|
||||||
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;
|
||||||
|
|
@ -39,6 +39,7 @@ pub struct LockConfigureContext {
|
||||||
pub compilation_result: Option<Rc<CompilationResult>>,
|
pub compilation_result: Option<Rc<CompilationResult>>,
|
||||||
pub platform: Rc<CustomSlintPlatform>,
|
pub platform: Rc<CustomSlintPlatform>,
|
||||||
pub callbacks: Vec<LockCallback>,
|
pub callbacks: Vec<LockCallback>,
|
||||||
|
pub property_operations: Vec<super::callbacks::LockPropertyOperation>,
|
||||||
pub component_name: String,
|
pub component_name: String,
|
||||||
pub output_handle: OutputHandle,
|
pub output_handle: OutputHandle,
|
||||||
pub output_info: Option<OutputInfo>,
|
pub output_info: Option<OutputInfo>,
|
||||||
|
|
@ -175,6 +176,29 @@ impl ActiveLockSurface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for property_op in &context.property_operations {
|
||||||
|
if property_op.should_apply(&callback_context) {
|
||||||
|
if let Err(err) =
|
||||||
|
property_op.apply_to_component(component.component_instance())
|
||||||
|
{
|
||||||
|
info!(
|
||||||
|
"Failed to set lock property '{}': {err}",
|
||||||
|
property_op.name()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!("Set lock property '{}' on output {:?}", property_op.name(), context.output_handle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!(
|
||||||
|
"Skipping property '{}' due to selector filter (output {:?}, primary={:?})",
|
||||||
|
property_op.name(),
|
||||||
|
context.output_handle,
|
||||||
|
context.primary_handle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.component = Some(component);
|
self.component = Some(component);
|
||||||
self.pending_component_initialization = false;
|
self.pending_component_initialization = false;
|
||||||
|
|
||||||
|
|
@ -233,6 +257,37 @@ impl ActiveLockSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply_property_operation(&self, property_op: &super::callbacks::LockPropertyOperation) {
|
||||||
|
let Some(component) = self.component.as_ref() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
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) =
|
||||||
|
property_op.apply_with_context(component.component_instance(), &callback_context)
|
||||||
|
{
|
||||||
|
info!(
|
||||||
|
"Failed to set lock property '{}': {err}",
|
||||||
|
property_op.name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn scaling_mode(&self) -> LockScalingMode {
|
fn scaling_mode(&self) -> LockScalingMode {
|
||||||
if self.surface.has_fractional_scale() && self.surface.has_viewport() {
|
if self.surface.has_fractional_scale() && self.surface.has_viewport() {
|
||||||
LockScalingMode::FractionalWithViewport
|
LockScalingMode::FractionalWithViewport
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,7 @@ pub mod lock_context;
|
||||||
pub mod lock_surface;
|
pub mod lock_surface;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
|
|
||||||
pub use manager::{LockCallback, LockSurfaceOutputContext, OutputFilter, SessionLockManager};
|
pub use manager::{
|
||||||
|
create_lock_property_operation_with_output_filter, LockCallback, LockPropertyOperation,
|
||||||
|
LockSurfaceOutputContext, OutputFilter, SessionLockManager,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::wayland::{
|
||||||
ops::WaylandSystemOps,
|
ops::WaylandSystemOps,
|
||||||
outputs::{OutputManager, OutputManagerContext},
|
outputs::{OutputManager, OutputManagerContext},
|
||||||
rendering::RenderableSet,
|
rendering::RenderableSet,
|
||||||
session_lock::OutputFilter,
|
session_lock::{LockPropertyOperation, OutputFilter},
|
||||||
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
|
surfaces::layer_surface::{SurfaceCtx, SurfaceSetupParams},
|
||||||
surfaces::popup_manager::{PopupContext, PopupManager},
|
surfaces::popup_manager::{PopupContext, PopupManager},
|
||||||
surfaces::{
|
surfaces::{
|
||||||
|
|
@ -902,6 +902,10 @@ impl WaylandSystemOps for WaylandShellSystem {
|
||||||
.register_session_lock_callback_with_filter(callback_name, handler, filter);
|
.register_session_lock_callback_with_filter(callback_name, handler, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_session_lock_property_operation(&mut self, property_operation: LockPropertyOperation) {
|
||||||
|
self.state.register_session_lock_property_operation(property_operation);
|
||||||
|
}
|
||||||
|
|
||||||
fn session_lock_component_name(&self) -> Option<String> {
|
fn session_lock_component_name(&self) -> Option<String> {
|
||||||
self.state.session_lock_component_name()
|
self.state.session_lock_component_name()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::wayland::session_lock::lock_context::SessionLockContext;
|
||||||
use crate::wayland::session_lock::manager::callbacks::{
|
use crate::wayland::session_lock::manager::callbacks::{
|
||||||
create_lock_callback, create_lock_callback_with_output_filter,
|
create_lock_callback, create_lock_callback_with_output_filter,
|
||||||
};
|
};
|
||||||
use crate::wayland::session_lock::{LockCallback, OutputFilter, SessionLockManager};
|
use crate::wayland::session_lock::{LockCallback, LockPropertyOperation, 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;
|
||||||
use layer_shika_domain::value_objects::lock_config::LockConfig;
|
use layer_shika_domain::value_objects::lock_config::LockConfig;
|
||||||
|
|
@ -71,6 +71,7 @@ pub struct AppState {
|
||||||
keyboard_state: KeyboardState,
|
keyboard_state: KeyboardState,
|
||||||
lock_manager: Option<SessionLockManager>,
|
lock_manager: Option<SessionLockManager>,
|
||||||
lock_callbacks: Vec<LockCallback>,
|
lock_callbacks: Vec<LockCallback>,
|
||||||
|
lock_property_operations: Vec<LockPropertyOperation>,
|
||||||
queue_handle: Option<wayland_client::QueueHandle<AppState>>,
|
queue_handle: Option<wayland_client::QueueHandle<AppState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,6 +102,7 @@ impl AppState {
|
||||||
keyboard_state: KeyboardState::new(),
|
keyboard_state: KeyboardState::new(),
|
||||||
lock_manager: None,
|
lock_manager: None,
|
||||||
lock_callbacks: Vec::new(),
|
lock_callbacks: Vec::new(),
|
||||||
|
lock_property_operations: Vec::new(),
|
||||||
queue_handle: None,
|
queue_handle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -176,6 +178,16 @@ impl AppState {
|
||||||
self.lock_callbacks.push(callback);
|
self.lock_callbacks.push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_session_lock_property_operation(
|
||||||
|
&mut self,
|
||||||
|
property_operation: LockPropertyOperation,
|
||||||
|
) {
|
||||||
|
if let Some(manager) = self.lock_manager.as_mut() {
|
||||||
|
manager.register_property_operation(property_operation.clone());
|
||||||
|
}
|
||||||
|
self.lock_property_operations.push(property_operation);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn activate_session_lock(
|
pub fn activate_session_lock(
|
||||||
&mut self,
|
&mut self,
|
||||||
component_name: &str,
|
component_name: &str,
|
||||||
|
|
@ -212,6 +224,9 @@ impl AppState {
|
||||||
for callback in self.lock_callbacks.iter().cloned() {
|
for callback in self.lock_callbacks.iter().cloned() {
|
||||||
manager.register_callback(callback);
|
manager.register_callback(callback);
|
||||||
}
|
}
|
||||||
|
for property_op in self.lock_property_operations.iter().cloned() {
|
||||||
|
manager.register_property_operation(property_op);
|
||||||
|
}
|
||||||
|
|
||||||
let outputs = self.collect_session_lock_outputs();
|
let outputs = self.collect_session_lock_outputs();
|
||||||
manager.activate(outputs, queue_handle)?;
|
manager.activate(outputs, queue_handle)?;
|
||||||
|
|
|
||||||
|
|
@ -63,20 +63,13 @@ impl<'a> LockSelection<'a> {
|
||||||
|
|
||||||
/// Sets a property value on all matching lock surfaces
|
/// Sets a property value on all matching lock surfaces
|
||||||
///
|
///
|
||||||
/// If the lock is inactive, this operation succeeds silently with no effect.
|
/// If the lock is inactive, the property operation is stored and will be applied
|
||||||
/// If the lock is active, the property is set on all matching component instances.
|
/// when the lock is activated. If the lock is active, the property is set immediately
|
||||||
|
/// on all matching component instances.
|
||||||
pub fn set_property(&self, name: &str, value: &Value) -> Result<(), Error> {
|
pub fn set_property(&self, name: &str, value: &Value) -> Result<(), Error> {
|
||||||
let mut result = Ok(());
|
|
||||||
self.shell
|
self.shell
|
||||||
.with_selected_lock(&self.selector, |_, component| {
|
.register_lock_property_internal(&self.selector, name, value.clone());
|
||||||
if let Err(e) = component.set_property(name, value.clone()) {
|
Ok(())
|
||||||
log::error!("Failed to set property '{}' on lock surface: {}", name, e);
|
|
||||||
result = Err(Error::Domain(DomainError::Configuration {
|
|
||||||
message: format!("Failed to set property '{}': {}", name, e),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets property values from all matching lock surfaces
|
/// Gets property values from all matching lock surfaces
|
||||||
|
|
|
||||||
|
|
@ -1387,6 +1387,27 @@ impl Shell {
|
||||||
.register_session_lock_callback_with_filter(&callback_name, callback_handler, filter);
|
.register_session_lock_callback_with_filter(&callback_name, callback_handler, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn register_lock_property_internal(
|
||||||
|
&self,
|
||||||
|
selector: &crate::Selector,
|
||||||
|
property_name: &str,
|
||||||
|
value: Value,
|
||||||
|
) {
|
||||||
|
use layer_shika_adapters::create_lock_property_operation_with_output_filter;
|
||||||
|
|
||||||
|
let filter = Self::selector_to_output_filter(selector);
|
||||||
|
let property_operation = create_lock_property_operation_with_output_filter(
|
||||||
|
property_name,
|
||||||
|
value,
|
||||||
|
move |component_name, output_handle, output_info, primary, active| {
|
||||||
|
filter(component_name, output_handle, output_info, primary, active)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.register_session_lock_property_operation(property_operation);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn with_selected_lock<F>(&self, selector: &crate::Selector, mut f: F)
|
pub(crate) fn with_selected_lock<F>(&self, selector: &crate::Selector, mut f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&str, &ComponentInstance),
|
F: FnMut(&str, &ComponentInstance),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue