use super::WindowManager;
pub(super) enum PendingScriptAction {
Notify { title: String, body: String },
SetBadge { text: String },
SetVariable { name: String, value: String },
WriteText { text: String, config_index: usize },
RunCommand {
command: String,
config_index: usize,
},
ChangeConfig {
key: String,
value: serde_json::Value,
config_index: usize,
},
}
pub(super) fn tokenise_command(command: &str) -> Option<(String, Vec<String>)> {
let mut tokens: Vec<String> = Vec::new();
let mut current = String::new();
let mut in_quotes = false;
for ch in command.chars() {
match ch {
'"' => in_quotes = !in_quotes,
' ' | '\t' if !in_quotes => {
if !current.is_empty() {
tokens.push(std::mem::take(&mut current));
}
}
_ => current.push(ch),
}
}
if !current.is_empty() {
tokens.push(current);
}
if tokens.is_empty() {
return None;
}
let program = tokens.remove(0);
Some((program, tokens))
}
impl WindowManager {
pub(super) fn apply_script_config_change(
ws: &mut crate::app::window_state::WindowState,
key: &str,
value: &serde_json::Value,
config_index: usize,
) {
match key {
"font_size" => {
if let Some(v) = value.as_f64() {
let new_size = (v as f32).clamp(6.0, 72.0);
ws.config.font_size = new_size;
ws.focus_state.needs_redraw = true;
ws.request_redraw();
log::info!(
"Script[{}] ChangeConfig: font_size = {}",
config_index,
new_size
);
} else {
log::warn!(
"Script[{}] ChangeConfig: font_size expected number, got {:?}",
config_index,
value
);
}
}
"window_opacity" => {
if let Some(v) = value.as_f64() {
let new_opacity = (v as f32).clamp(0.0, 1.0);
ws.config.window_opacity = new_opacity;
if let Some(renderer) = &mut ws.renderer {
renderer.update_opacity(new_opacity);
}
ws.focus_state.needs_redraw = true;
ws.request_redraw();
log::info!(
"Script[{}] ChangeConfig: window_opacity = {}",
config_index,
new_opacity
);
} else {
log::warn!(
"Script[{}] ChangeConfig: window_opacity expected number, got {:?}",
config_index,
value
);
}
}
"scrollback_lines" => {
if let Some(v) = value.as_u64() {
ws.config.scrollback.scrollback_lines = v as usize;
log::info!(
"Script[{}] ChangeConfig: scrollback_lines = {}",
config_index,
v
);
} else {
log::warn!(
"Script[{}] ChangeConfig: scrollback_lines expected integer, got {:?}",
config_index,
value
);
}
}
"cursor_blink" => {
if let Some(v) = value.as_bool() {
ws.config.cursor_blink = v;
ws.focus_state.needs_redraw = true;
ws.request_redraw();
log::info!(
"Script[{}] ChangeConfig: cursor_blink = {}",
config_index,
v
);
} else {
log::warn!(
"Script[{}] ChangeConfig: cursor_blink expected bool, got {:?}",
config_index,
value
);
}
}
"notification_bell_desktop" => {
if let Some(v) = value.as_bool() {
ws.config.notifications.notification_bell_desktop = v;
log::info!(
"Script[{}] ChangeConfig: notification_bell_desktop = {}",
config_index,
v
);
} else {
log::warn!(
"Script[{}] ChangeConfig: notification_bell_desktop expected bool, \
got {:?}",
config_index,
value
);
}
}
"notification_bell_visual" => {
if let Some(v) = value.as_bool() {
ws.config.notifications.notification_bell_visual = v;
ws.focus_state.needs_redraw = true;
ws.request_redraw();
log::info!(
"Script[{}] ChangeConfig: notification_bell_visual = {}",
config_index,
v
);
} else {
log::warn!(
"Script[{}] ChangeConfig: notification_bell_visual expected bool, \
got {:?}",
config_index,
value
);
}
}
_ => {
log::warn!(
"Script[{}] ChangeConfig: key '{}' not in runtime allowlist",
config_index,
key
);
}
}
}
}