approaching first major release
This commit is contained in:
parent
4100c0dff9
commit
9add5c827f
5 changed files with 159 additions and 56 deletions
|
@ -1,31 +1,34 @@
|
|||
use std::fs::File;
|
||||
//use std::io::{Write, Error};
|
||||
use xdg::BaseDirectories;
|
||||
use config_file::FromConfigFile;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize,Clone)]
|
||||
#[derive(Serialize,Deserialize,Clone)]
|
||||
pub struct WindowIcon {
|
||||
pub icon: String,
|
||||
pub substring: String
|
||||
}
|
||||
#[derive(Deserialize, Default)]
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
pub struct BrowserConf {
|
||||
pub profile: String,
|
||||
pub startpage: String
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
pub struct Profile {
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
pub browser: BrowserConf,
|
||||
pub directory: String
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
pub struct Programs {
|
||||
pub name: String,
|
||||
pub command: String,
|
||||
pub arguments: Vec<String>
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Default)]
|
||||
pub struct Config {
|
||||
pub title_length: usize,
|
||||
pub window_icons: Vec<WindowIcon>
|
||||
}
|
||||
|
||||
pub fn parse_config() -> Config {
|
||||
let xdg_dirs = BaseDirectories::with_prefix("sway-profiles-rs");
|
||||
let config_path = xdg_dirs
|
||||
.place_config_file("config.toml")
|
||||
.expect("cannot create configuration directory");
|
||||
// println!("{}",config_path.exists());
|
||||
if !config_path.exists() {
|
||||
let _ = File::create(&config_path);
|
||||
// let config_file = File::create(&config_path);
|
||||
// write!(&mut config_file, "title_length = 20");
|
||||
}
|
||||
Config::from_config_file(config_path).unwrap()
|
||||
}
|
||||
|
||||
pub window_icons: Vec<WindowIcon>,
|
||||
pub wallpaper_path: String,
|
||||
pub programs: HashMap<String, Programs>,
|
||||
pub profiles: HashMap<String, Profile>
|
||||
}
|
|
@ -1 +1,73 @@
|
|||
use
|
||||
use std::{env::consts, fs::{self, exists}, io, ops::Sub, path::{Path, PathBuf}};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use image::imageops::GaussianBlurParameters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use sha2::{Sha256, Digest};
|
||||
use swayipc::Connection;
|
||||
use xdg::BaseDirectories;
|
||||
use shellexpand::tilde;
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
#[derive(Serialize,Deserialize,Debug)]
|
||||
pub struct WallpaperCache {
|
||||
pub display: String,
|
||||
pub hash: String
|
||||
}
|
||||
|
||||
pub fn lock_screen(config: &Config, mut sway_connection: Connection) {
|
||||
let wallpaper_root_path = tilde(&config.wallpaper_path).to_string();
|
||||
let wallpaper_root_path = Path::new(&wallpaper_root_path);
|
||||
let cache_dir = BaseDirectories::with_prefix("sway-profiles-rs").cache_home;
|
||||
let wp_cache_dir = cache_dir.clone().unwrap().join("sway-profiles-rs/lock/");
|
||||
|
||||
let mut wp_hash_json: Vec<WallpaperCache> = vec![];
|
||||
let hashes_json_path = wp_cache_dir.join("hashes.json");
|
||||
if exists(&hashes_json_path).unwrap() {
|
||||
let file = fs::File::open(&hashes_json_path).unwrap();
|
||||
wp_hash_json = serde_json::from_reader(file).unwrap();
|
||||
}
|
||||
|
||||
let mut wp_hash_array: Vec<WallpaperCache> = vec![];
|
||||
for output in sway_connection.get_outputs().unwrap() {
|
||||
let sway_workspaces = sway_connection.get_workspaces().unwrap().clone();
|
||||
let output_ws_num = format!("{:0>2}",sway_workspaces.iter().find(|x|x.name == output.current_workspace
|
||||
.clone().unwrap()).unwrap().num.sub(1)).chars().next().unwrap();
|
||||
let image_path = wallpaper_root_path.join(output.name.clone()).join(format!("p_{}.jpg",output_ws_num));
|
||||
|
||||
let mut img_file_data = fs::File::open(&image_path).unwrap();
|
||||
let mut sha256 = Sha256::new();
|
||||
let _ = io::copy(&mut img_file_data, &mut sha256);
|
||||
let hash = format!("{:x}",sha256.finalize());
|
||||
wp_hash_array.push(WallpaperCache { display: output.name.clone(), hash: hash.clone() });
|
||||
|
||||
if let Some(output_saved_hash) = wp_hash_json.iter().find(|x|x.display == output.name) && output_saved_hash.hash.ne(&hash) {
|
||||
let img_data = image::open(image_path).unwrap();
|
||||
let blurred_img_data = img_data
|
||||
.resize((img_data.width() as f64 * 0.75) as u32, (img_data.height() as f64 * 0.75) as u32, image::imageops::FilterType::Nearest)
|
||||
.blur_advanced(GaussianBlurParameters::new_from_sigma(10.0));
|
||||
let blurred_image_path = cache_dir.clone().unwrap().join(format!("sway-profiles-rs/lock/{}.jpg",output.name));
|
||||
let _ = blurred_img_data.save(blurred_image_path);
|
||||
}
|
||||
}
|
||||
let gtklock_modules_dir = "/usr/lib/".to_owned() + consts::ARCH + "-linux-gnu/gtklock/";
|
||||
let gktlock_modules_path = Path::new(>klock_modules_dir);
|
||||
let mut gtklock_args: Vec<String> = vec![];
|
||||
for file in WalkDir::new(gktlock_modules_path).into_iter() {//.find(|x|x.as_ref().unwrap().file_name().to_str().unwrap().ends_with("-module.so")) {
|
||||
|
||||
if let Some(f) = file.iter().find(|&x|x.path().to_str().unwrap().ends_with("-module.so")) {
|
||||
gtklock_args.push("-m".to_owned());
|
||||
gtklock_args.push(f.path().to_str().unwrap().to_string());
|
||||
}
|
||||
}
|
||||
let new_json = json!(wp_hash_array);
|
||||
let _ = std::fs::write::<PathBuf, String>(hashes_json_path, new_json.to_string());
|
||||
let mut gtklock_command = "exec gtklock".to_owned();
|
||||
for a in gtklock_args {
|
||||
gtklock_command = gtklock_command + " " + &a;
|
||||
}
|
||||
println!("{:?}",gtklock_command);
|
||||
let _ = sway_connection.run_command(gtklock_command);
|
||||
}
|
|
@ -3,9 +3,10 @@ use serde_json::json;
|
|||
use swayipc::Node;
|
||||
use crate::{config::Config, Cli};
|
||||
|
||||
//#[path = "../results.rs"]
|
||||
mod results;
|
||||
use results::WindowInfo;
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct WindowInfo {
|
||||
pub title: String
|
||||
}
|
||||
|
||||
pub fn print_window_title(window_node: Node,cli: &Cli,config: &Config) {
|
||||
let mut window_title_display: String = window_node.name.unwrap();
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use serde_json::json;
|
||||
use swayipc::Workspace;
|
||||
|
||||
//#[path = "../results.rs"]
|
||||
mod results;
|
||||
use results::WorkspaceInfo;
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct WorkspaceInfo {
|
||||
pub num: i32,
|
||||
pub name: String,
|
||||
pub is_focused: bool,
|
||||
pub position: char
|
||||
}
|
||||
|
||||
pub fn print_workspace_array(workspaces: Vec<Workspace>) {
|
||||
let current_ws = workspaces.iter().find(|&x| x.focused).unwrap().num;
|
||||
|
|
73
src/main.rs
73
src/main.rs
|
@ -1,9 +1,10 @@
|
|||
use std::process::exit;
|
||||
|
||||
|
||||
|
||||
use clap::{Parser,Subcommand,ArgAction};
|
||||
use swayipc::{Connection, Event, EventType, Fallible};
|
||||
|
||||
|
||||
mod config;
|
||||
#[path = "lib/windows.rs"]
|
||||
mod windows;
|
||||
|
@ -11,9 +12,11 @@ use windows::print_window_title;
|
|||
#[path = "lib/workspaces.rs"]
|
||||
mod workspaces;
|
||||
use workspaces::print_workspace_array;
|
||||
#[path = "lib/lock.rs"]
|
||||
mod lock;
|
||||
use lock::lock_screen;
|
||||
|
||||
use crate::config::Config;
|
||||
mod monitor;
|
||||
use config::Config;
|
||||
|
||||
|
||||
#[derive(Parser)]
|
||||
|
@ -43,12 +46,16 @@ pub struct Cli {
|
|||
enum Commands {
|
||||
/// Prints the Currently Active Window Title
|
||||
Windows,
|
||||
// Prints the Currently Active Workspace layout
|
||||
/// Prints the Currently Active Workspace layout
|
||||
Workspaces,
|
||||
// Launch Program with Current Profile's Configuration
|
||||
Launch,
|
||||
/// Launch Program with Current Workspace's Profile Configuration
|
||||
Launch {
|
||||
#[arg(short, long)]
|
||||
program: String
|
||||
},
|
||||
/// Set up blurred wallpaper for screen lock, and load gtklock modules
|
||||
Lock,
|
||||
Rename,
|
||||
//Rename,
|
||||
Profile,
|
||||
Shortcuts {
|
||||
#[arg(short, long, action = ArgAction::SetTrue)]
|
||||
|
@ -73,35 +80,52 @@ enum MonitorTypes {
|
|||
}
|
||||
|
||||
fn main() -> Fallible<()> {
|
||||
//let xdg_dirs = BaseDirectories::with_prefix("sway-profiles-rs");
|
||||
let cli = Cli::parse();
|
||||
let config = config::parse_config();
|
||||
if let Some(no_truncate_title) = cli.no_truncate_title {
|
||||
println!("Value for no_truncate_title: {no_truncate_title}");
|
||||
}
|
||||
// let config = config::parse_config();
|
||||
let config = confy::load("sway-profiles-rs", "config").unwrap();
|
||||
|
||||
let mut sway_connection = Connection::new()?;
|
||||
match &cli.command {
|
||||
Commands::Windows => {
|
||||
print_window_title(sway_connection.get_tree().iter().find(|&x | x.focused).unwrap().clone(), &cli, &config);
|
||||
print_window_title(sway_connection.get_tree().unwrap().iter().find(|&x | x.focused).unwrap().clone(), &cli, &config);
|
||||
if cli.monitor.unwrap() {
|
||||
let _ = monitor_events(EventType::Window, cli, config);
|
||||
monitor_events(EventType::Window, cli, config);
|
||||
}
|
||||
}
|
||||
Commands::Workspaces => {
|
||||
print_workspace_array(sway_connection.get_workspaces().unwrap());
|
||||
if cli.monitor.unwrap() {
|
||||
let _ = monitor_events(EventType::Workspace, cli, config);
|
||||
monitor_events(EventType::Workspace, cli, config);
|
||||
}
|
||||
}
|
||||
Commands::Launch => todo!(),
|
||||
Commands::Lock => todo!(),
|
||||
Commands::Rename => todo!(),
|
||||
Commands::Profile => todo!(),
|
||||
Commands::Shortcuts { global } => todo!(),
|
||||
Commands::Launch { program } => {
|
||||
if let Some(launch_program) = config.programs.iter().find(|x|x.0 == program) {
|
||||
println!("found: {:#?} {:?}",launch_program.1.command, launch_program.1.arguments);
|
||||
let mut swaymsg_command = "exec ".to_owned() + &launch_program.1.command;
|
||||
for a in &launch_program.1.arguments {
|
||||
swaymsg_command = swaymsg_command + " " + a;
|
||||
}
|
||||
println!("{:#?}",swaymsg_command);
|
||||
let _ = sway_connection.run_command(swaymsg_command);
|
||||
}
|
||||
},
|
||||
Commands::Lock => {
|
||||
lock_screen(&config, sway_connection);
|
||||
},
|
||||
//Commands::Rename => todo!(),
|
||||
Commands::Profile => {
|
||||
println!("{:?}", config.profiles.len());
|
||||
for p in config.profiles {
|
||||
println!("{:?} {:?}",p.0, p.1.name )
|
||||
}
|
||||
},
|
||||
Commands::Shortcuts { global: _ } => todo!(),
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pub fn monitor_events(event_type: EventType, cli: Cli, config: Config) -> Fallible<()> {
|
||||
pub fn monitor_events(event_type: EventType, cli: Cli, config: Config) {
|
||||
/* let subs = [
|
||||
// Valid EventTypes: Workspace, Output, Input, Tick, Shutdown, Mode, Window, BarStateUpdate, BarConfigUpdate, Binding
|
||||
//EventType::Workspace,
|
||||
|
@ -109,14 +133,14 @@ pub fn monitor_events(event_type: EventType, cli: Cli, config: Config) -> Fallib
|
|||
//EventType::Window,
|
||||
event_type
|
||||
]; */
|
||||
let sway_connection = Connection::new()?;
|
||||
for event in sway_connection.subscribe([event_type])? {
|
||||
let e = event?;
|
||||
let sway_connection = Connection::new().unwrap();
|
||||
for event in sway_connection.subscribe([event_type]).unwrap() {
|
||||
let e = event.unwrap();
|
||||
match e {
|
||||
Event::Window(w) => {
|
||||
print_window_title(w.container, &cli, &config);
|
||||
},
|
||||
Event::Workspace(w) => {
|
||||
Event::Workspace(_) => {
|
||||
print_workspace_array(self::Connection::get_workspaces(&mut self::Connection::new().unwrap()).unwrap());
|
||||
},
|
||||
Event::Tick(w) => {
|
||||
|
@ -125,5 +149,4 @@ pub fn monitor_events(event_type: EventType, cli: Cli, config: Config) -> Fallib
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Reference in a new issue