some cleanup, finalized scratchpad logic

This commit is contained in:
Penelope Gwen 2026-01-22 00:09:47 -08:00
parent 41aeab7bda
commit 256f0e6d37
7 changed files with 46 additions and 68 deletions

12
Cargo.lock generated
View file

@ -690,16 +690,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "freedesktop-file-parser"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1998b5ee36700463150124ac6d6d6128a5a4da453a6f6777a26810f05539f41"
dependencies = [
"freedesktop-icons",
"thiserror 2.0.16",
]
[[package]]
name = "freedesktop-icons"
version = "0.4.0"
@ -1842,9 +1832,7 @@ dependencies = [
"clap",
"confy",
"dialog",
"dirs 6.0.0",
"env_logger",
"freedesktop-file-parser",
"freedesktop-icons",
"hex",
"image",

View file

@ -14,9 +14,7 @@ path = "src/main.rs"
clap = { version = "4.5.45", features = ["derive"] }
confy = "1.0.0"
dialog = "0.3.0"
dirs = "6.0.0"
env_logger = "0.11.8"
freedesktop-file-parser = "0.3.1"
freedesktop-icons = "0.4.0"
hex = "0.4.3"
image = "0.25.8"

View file

@ -68,7 +68,7 @@ pub fn lock_screen(lock_config: LockConf,force_bg_render: bool) -> Result<(),SDU
let new_json = json!(wp_hash_array);
let _ = write(wp_cache_dir.join("hashes.json"), new_json.to_string());
let gtklock_modules_dir = format!("/usr/lib/{}-linux-gnu/gtklock/",consts::ARCH);//.to_owned() + consts::ARCH + "-linux-gnu/gtklock/";
let gtklock_modules_dir = format!("/usr/lib/{}-linux-gnu/gtklock/",consts::ARCH);
let gktlock_modules_path = PathBuf::from(gtklock_modules_dir);
let mut gtklock_args: Vec<String> = vec![];
@ -107,7 +107,7 @@ pub fn generate_image(orig_img_data: DynamicImage,gen_image_path: PathBuf, lock_
pub fn wallpaper_check_hash(hashes_json_path: PathBuf) -> Vec<WallpaperCache> {
let wallpaper_hashes: Vec<WallpaperCache> = fs::File::open(hashes_json_path).ok()
.and_then(|f| serde_json::from_reader(f).ok()).unwrap_or(vec![]);
.and_then(|f| serde_json::from_reader(f).ok()).unwrap_or_default();
wallpaper_hashes
}

View file

@ -1,6 +1,7 @@
use std::path::PathBuf;
use std::{path::PathBuf, time::Instant};
use freedesktop_icons::lookup;
use log::debug;
use serde_json::{Value, json};
use swayipc::{Node, ScratchpadState};
@ -16,34 +17,8 @@ pub struct ScratchpadInfo {
window_id: i64
}
fn search_node(node: Node) -> Vec<Node> {
let mut node_vec: Vec<Node> = vec![];
if node.scratchpad_state.eq(&Some(ScratchpadState::Fresh)) {
node_vec.push(node);
} else {
for node in node.nodes {
let node_vec_recurse = search_node(node);
for n in node_vec_recurse {
node_vec.push(n);
}
};
for floating_node in node.floating_nodes {
let node_vec_recurse = search_node(floating_node);
for n in node_vec_recurse {
node_vec.push(n);
}
};
}
node_vec
}
fn icon_lookup(name : &str, size: u16) -> Option<PathBuf> {lookup(name).with_cache().with_size(size).find()}
fn app_icon_lookup(name: &str) -> Option<PathBuf> {
//TODO better & faster icon searching
//let sizes: Vec<u16> = vec![512, 256, 128, 64, 24, 22, 16];
//sizes.into_iter().find_map(|s|icon_lookup(name, s))
lookup(name).with_cache().with_theme("breeze").find()
lookup(name).with_theme("breeze").with_theme("Adwaita").with_size(64).with_cache().find()
}
fn get_app_icon(window: Node) -> PathBuf {
@ -55,28 +30,45 @@ fn get_app_icon(window: Node) -> PathBuf {
).unwrap_or("/usr/share/icons/breeze-dark/mimetypes/32/unknown.svg".into())
}
fn node_finder(mut node: Node) -> Option<Vec<Node>> {
let mut node_list = Vec::<Node>::new();
debug!("{:?}, {:?}",node.name,node.scratchpad_state);
if node.scratchpad_state.eq(&Some(ScratchpadState::Fresh)) {
node_list.push(node);
} else {
node.nodes.append(&mut node.floating_nodes);
for node in node.nodes {
if let Some(mut nodes) = node_finder(node) {
debug!("appending {:?} to {:?}",nodes,node_list);
node_list.append(&mut nodes);
}
}
};
debug!("{:?}", node_list);
if !node_list.is_empty() {
Some(node_list)
} else {
None
}
}
fn scratchpad_strip(node: Node) -> ScratchpadInfo {
let start = Instant::now();
let window_icon = get_app_icon(node.clone());
debug!("found window icon in {:?}", start.elapsed());
let title = match node.window_properties.clone() {
Some(w) => w.class,
None => node.app_id,
};
ScratchpadInfo { icon: window_icon, visible: node.visible.unwrap_or_default(), name: node.name, title, window_id: node.id }
}
pub fn get_scratchpad_info() -> Value {
let tree = get_sway_connection().get_tree().expect("todo");
let mut scratchpad_vec: Vec<ScratchpadInfo> = vec![];
let scratch_start = Instant::now();
// $20 says this is NOT the best way to recursively check all nodes but i'll fix it later
for output in tree.nodes {
for workspace in output.nodes {
for node_list in [workspace.nodes,workspace.floating_nodes] {
for node in node_list {
let sp_nodes = search_node(node);
for n in sp_nodes {
let app_icon = get_app_icon(n.clone());
let title = match n.window_properties.clone() {
Some(w) => w.class,
None => n.app_id,
};
let scratch_node: ScratchpadInfo = ScratchpadInfo { icon: app_icon, visible: n.visible.unwrap_or_default(), name: n.name, title: title, window_id: n.id };
scratchpad_vec.push(scratch_node);
}
}
};
}
}
json!(scratchpad_vec)
let scratchpad_nodes: Vec<Node> = tree.nodes.iter().filter_map(|x|node_finder(x.clone())).flatten().collect();
let scratchpad_windows: Vec<ScratchpadInfo> = scratchpad_nodes.iter().map(|node|scratchpad_strip(node.clone())).collect();
debug!("parsed scratchpad window info in {:?}", scratch_start.elapsed());
json!(scratchpad_windows)
}

View file

@ -26,7 +26,7 @@ pub fn get_window_info(window_icons: &[WindowIcon]) -> Value {
debug!("{:#?}",window_count);
let window_title = if window_count.gt(&0) {
let window_node = nodes_tree.iter().find(|x|x.focused);
debug!("{:#?}",window_node);
//debug!("{:#?}",window_node);
match window_node {
Some(n) => {
let mut window_name = n.name.clone().unwrap_or_default();

View file

@ -21,7 +21,7 @@ fn get_workspace_profile(profile_index: usize, profile_list: Vec<Profile>, kb_or
} else {
profile_index / 10
};
profile_list.iter().nth(ws_profile_index).expect("could not find profile for workspace").clone().name
profile_list.get(ws_profile_index).expect("could not find profile for workspace").clone().name
}
pub fn get_workspace_info(profile_list: Vec<Profile>, kb_order: bool) -> Value {

View file

@ -1,5 +1,5 @@
#![warn(unused_crate_dependencies)]
#![allow(clippy::style)]
//#![allow(clippy::style)]
mod config;
mod utils;