use crate::config::PasteShortcut;
use serde::Deserialize;
pub(crate) const DEFAULT_CHUNK_CHARS: usize = 150;
pub(crate) const DEFAULT_RESTORE_SETTLE_MS: u64 = 200;
pub(crate) const DEFAULT_CHUNK_FETCH_TIMEOUT_MS: u64 = 500;
pub(crate) const DEFAULT_TARGET_FETCH_RETRIES: u32 = 2;
pub(crate) const DEFAULT_TARGET_QUIESCENCE_MS: u64 = 50;
#[derive(Debug, Clone, Copy)]
pub struct PasteTiming {
pub restore_settle_ms: u64,
pub chunk_fetch_timeout_ms: u64,
pub target_quiescence_ms: u64,
}
impl Default for PasteTiming {
fn default() -> Self {
Self {
restore_settle_ms: DEFAULT_RESTORE_SETTLE_MS,
chunk_fetch_timeout_ms: DEFAULT_CHUNK_FETCH_TIMEOUT_MS,
target_quiescence_ms: DEFAULT_TARGET_QUIESCENCE_MS,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct WmClassPattern {
#[serde(rename = "match")]
pub pattern: String,
pub child: Box<PasteNodeConfig>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ForegroundAppPattern {
#[serde(rename = "match")]
pub pattern: String,
pub child: Box<PasteNodeConfig>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "node", rename_all = "kebab-case")]
pub enum PasteNodeConfig {
DetectDisplayServer {
x11: Box<PasteNodeConfig>,
#[serde(default)]
wayland: Option<Box<PasteNodeConfig>>,
},
MatchWmClass {
patterns: Vec<WmClassPattern>,
default: Box<PasteNodeConfig>,
},
MatchForegroundApp {
patterns: Vec<ForegroundAppPattern>,
default: Box<PasteNodeConfig>,
},
Chunk {
#[serde(default = "default_chunk_chars")]
chunk_chars: usize,
child: Box<PasteNodeConfig>,
},
Clipboard {
#[serde(default)]
shortcut: PasteShortcut,
#[serde(default = "default_restore_settle_ms")]
restore_settle_ms: u64,
#[serde(default = "default_chunk_fetch_timeout_ms")]
chunk_fetch_timeout_ms: u64,
#[serde(default = "default_target_quiescence_ms")]
target_quiescence_ms: u64,
#[serde(default = "default_target_fetch_retries")]
target_fetch_retries: u32,
},
XtestType {},
}
fn default_chunk_chars() -> usize {
DEFAULT_CHUNK_CHARS
}
fn default_restore_settle_ms() -> u64 {
DEFAULT_RESTORE_SETTLE_MS
}
fn default_chunk_fetch_timeout_ms() -> u64 {
DEFAULT_CHUNK_FETCH_TIMEOUT_MS
}
fn default_target_quiescence_ms() -> u64 {
DEFAULT_TARGET_QUIESCENCE_MS
}
fn default_target_fetch_retries() -> u32 {
DEFAULT_TARGET_FETCH_RETRIES
}
impl PasteNodeConfig {
pub fn strip_chunks(self) -> Self {
match self {
Self::Chunk { child, .. } => child.strip_chunks(),
Self::DetectDisplayServer { x11, wayland } => Self::DetectDisplayServer {
x11: Box::new(x11.strip_chunks()),
wayland: wayland.map(|w| Box::new(w.strip_chunks())),
},
Self::MatchWmClass { patterns, default } => Self::MatchWmClass {
patterns: patterns
.into_iter()
.map(|p| WmClassPattern {
pattern: p.pattern,
child: Box::new(p.child.strip_chunks()),
})
.collect(),
default: Box::new(default.strip_chunks()),
},
Self::MatchForegroundApp { patterns, default } => Self::MatchForegroundApp {
patterns: patterns
.into_iter()
.map(|pattern| ForegroundAppPattern {
pattern: pattern.pattern,
child: Box::new(pattern.child.strip_chunks()),
})
.collect(),
default: Box::new(default.strip_chunks()),
},
leaf @ (Self::Clipboard { .. } | Self::XtestType {}) => leaf,
}
}
}
pub(crate) fn timing_from_tree(cfg: &PasteNodeConfig) -> PasteTiming {
match cfg {
PasteNodeConfig::Clipboard {
restore_settle_ms,
chunk_fetch_timeout_ms,
target_quiescence_ms,
..
} => PasteTiming {
restore_settle_ms: *restore_settle_ms,
chunk_fetch_timeout_ms: *chunk_fetch_timeout_ms,
target_quiescence_ms: *target_quiescence_ms,
},
PasteNodeConfig::Chunk { child, .. } => timing_from_tree(child),
PasteNodeConfig::DetectDisplayServer { x11, .. } => timing_from_tree(x11),
PasteNodeConfig::MatchWmClass { default, .. } => timing_from_tree(default),
PasteNodeConfig::MatchForegroundApp { default, .. } => timing_from_tree(default),
PasteNodeConfig::XtestType {} => PasteTiming::default(),
}
}