cargo fmt
This commit is contained in:
parent
256f0e6d37
commit
8f0b4e68cd
16 changed files with 703 additions and 391 deletions
|
|
@ -1,42 +1,39 @@
|
|||
use {
|
||||
serde::{Deserialize, Serialize},
|
||||
std::collections::HashMap,
|
||||
serde::{
|
||||
Deserialize,
|
||||
Serialize
|
||||
}
|
||||
};
|
||||
|
||||
#[derive(Serialize,Deserialize,Clone, Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct WindowIcon {
|
||||
pub icon: String,
|
||||
pub substring: String
|
||||
pub substring: String,
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Profile {
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
pub program_args: Option<HashMap<String, Vec<String>>>,
|
||||
pub scripts: Option<Vec<ScriptConf>>
|
||||
pub scripts: Option<Vec<ScriptConf>>,
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Programs {
|
||||
pub name: Option<String>,
|
||||
pub command: String,
|
||||
pub arguments: Vec<String>
|
||||
pub arguments: Vec<String>,
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug,Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
pub struct LockConf {
|
||||
pub wallpaper_path: Option<String>,
|
||||
pub blur: f32,
|
||||
pub scale: f32,
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ScriptConf {
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
pub command: String
|
||||
pub command: String,
|
||||
}
|
||||
#[derive(Serialize,Deserialize,Clone,Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Config {
|
||||
pub preserve_keyboard_order: bool,
|
||||
pub window_icons: Vec<WindowIcon>,
|
||||
|
|
@ -47,5 +44,18 @@ pub struct Config {
|
|||
}
|
||||
|
||||
impl ::std::default::Default for Config {
|
||||
fn default() -> Self { Self { preserve_keyboard_order: false, window_icons: vec![], programs: HashMap::new(), lock: LockConf { wallpaper_path: None, blur: 10.0, scale: 0.75 }, profiles: vec![], scripts: vec![] } }
|
||||
}
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
preserve_keyboard_order: false,
|
||||
window_icons: vec![],
|
||||
programs: HashMap::new(),
|
||||
lock: LockConf {
|
||||
wallpaper_path: None,
|
||||
blur: 10.0,
|
||||
scale: 0.75,
|
||||
},
|
||||
profiles: vec![],
|
||||
scripts: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub struct Cli {
|
|||
|
||||
#[command(subcommand)]
|
||||
pub(crate) command: Commands,
|
||||
// command: Commands,
|
||||
// command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -32,7 +32,7 @@ pub enum Commands {
|
|||
#[clap(alias = "L")]
|
||||
Launch {
|
||||
#[arg(short, long)]
|
||||
program: String
|
||||
program: String,
|
||||
},
|
||||
/// Set up blurred wallpaper for screen lock, and locks screen
|
||||
#[clap(alias = "l")]
|
||||
|
|
@ -49,52 +49,47 @@ pub enum Commands {
|
|||
/// Lists global/profile shortcuts and optionally executes them
|
||||
#[clap(alias = "scut")]
|
||||
Shortcuts {
|
||||
/// List shortcuts from global shortcut list rather than
|
||||
// #[arg(short, long, action = ArgAction::SetTrue)]
|
||||
// global: Option<bool>,
|
||||
/// List shortcuts from global shortcut list rather than
|
||||
// #[arg(short, long, action = ArgAction::SetTrue)]
|
||||
// global: Option<bool>,
|
||||
#[command(subcommand)]
|
||||
shortcut_command: ShortcutCommand,
|
||||
// /// Execute foud command
|
||||
// #[arg(short, long, action = ArgAction::SetTrue)]
|
||||
// execute: bool,
|
||||
// /// Mode to print shortcut information
|
||||
// #[command(subcommand)]
|
||||
// mode: Option<ShortcutMode>
|
||||
|
||||
// /// Execute foud command
|
||||
// #[arg(short, long, action = ArgAction::SetTrue)]
|
||||
// execute: bool,
|
||||
// /// Mode to print shortcut information
|
||||
// #[command(subcommand)]
|
||||
// mode: Option<ShortcutMode>
|
||||
},
|
||||
/// List or Execute Power/Session Commands
|
||||
#[clap(alias = "pow")]
|
||||
Power {
|
||||
#[command(subcommand)]
|
||||
power_command: Option<PowerCommand>,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Subcommand)]
|
||||
#[derive(Clone, Subcommand)]
|
||||
pub enum ShortcutCommand {
|
||||
/// Execute command by passed name
|
||||
#[clap(alias = "exec")]
|
||||
Execute {
|
||||
shortcut_name: String
|
||||
},
|
||||
Execute { shortcut_name: String },
|
||||
/// Mode to print shortcut information
|
||||
#[clap(alias = "g")]
|
||||
Get {
|
||||
#[arg(short,long)]
|
||||
mode: Option<ShortcutMode>
|
||||
}
|
||||
#[arg(short, long)]
|
||||
mode: Option<ShortcutMode>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, ValueEnum)]
|
||||
#[derive(Subcommand)]
|
||||
#[derive(Clone, Copy, ValueEnum, Subcommand)]
|
||||
pub enum ShortcutMode {
|
||||
/// Print formatted for dmenu/wofi
|
||||
#[clap(alias = "d")]
|
||||
Dmenu,
|
||||
/// Print formatted as json/for eww
|
||||
#[clap(alias = "j")]
|
||||
Json
|
||||
Json,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -122,7 +117,7 @@ pub enum SwayGetCommand {
|
|||
Scratchpad,
|
||||
/// Get Window and Workspace Information in one JSON output
|
||||
#[clap(alias = "f")]
|
||||
Full
|
||||
Full,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -173,7 +168,7 @@ pub enum ProfileCommand {
|
|||
},
|
||||
/// Initialize Sway-DE-Utils
|
||||
#[clap(alias = "i")]
|
||||
Init
|
||||
Init,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -196,13 +191,11 @@ pub enum ProfileSwitchCommand {
|
|||
#[arg(short, long)]
|
||||
index: Option<usize>,
|
||||
/// Target Profile Name or Index
|
||||
query: Option<String>
|
||||
|
||||
}
|
||||
query: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Subcommand)]
|
||||
#[derive(Clone, Subcommand)]
|
||||
pub enum ProfileGetCommand {
|
||||
/// Get Profile Details in JSON Format
|
||||
#[clap(alias = "j")]
|
||||
|
|
@ -212,5 +205,5 @@ pub enum ProfileGetCommand {
|
|||
Name,
|
||||
/// Get Profile Icon in Plaintext
|
||||
#[clap(alias = "i")]
|
||||
Icon
|
||||
}
|
||||
Icon,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,35 +3,45 @@ use {
|
|||
config::Profile,
|
||||
lib::{
|
||||
cli::ProfileGetCommand,
|
||||
profile::{active_profile_index, profile_from_index}
|
||||
}
|
||||
profile::{active_profile_index, profile_from_index},
|
||||
},
|
||||
},
|
||||
miette::{IntoDiagnostic, Result},
|
||||
serde_json::json,
|
||||
watchexec::Watchexec,
|
||||
watchexec_events::Tag
|
||||
watchexec_events::Tag,
|
||||
};
|
||||
|
||||
pub fn profile_info(profiles: Vec<Profile>,info: ProfileGetCommand) -> String {
|
||||
pub fn profile_info(profiles: Vec<Profile>, info: ProfileGetCommand) -> String {
|
||||
let active_profile = profile_from_index(profiles, active_profile_index());
|
||||
match info {
|
||||
ProfileGetCommand::Json => json!(active_profile).to_string(),
|
||||
ProfileGetCommand::Name => active_profile.name,
|
||||
ProfileGetCommand::Icon => active_profile.icon
|
||||
ProfileGetCommand::Icon => active_profile.icon,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn watch(profiles_config: Vec<Profile>,info: ProfileGetCommand,watch_path: String) -> Result<()> {
|
||||
pub async fn watch(
|
||||
profiles_config: Vec<Profile>,
|
||||
info: ProfileGetCommand,
|
||||
watch_path: String,
|
||||
) -> Result<()> {
|
||||
let wx = Watchexec::new(move |mut action| {
|
||||
//yeah, this is... fine
|
||||
action.events.iter().find(|_event|_event.tags.iter().any(|tag| match tag {
|
||||
Tag::FileEventKind(watchexec_events::filekind::FileEventKind::Access(watchexec_events::filekind::AccessKind::Close(watchexec_events::filekind::AccessMode::Write))) => {
|
||||
println!("{}",profile_info(profiles_config.clone(),info.clone()));
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
}));
|
||||
action.events.iter().find(|_event| {
|
||||
_event.tags.iter().any(|tag| match tag {
|
||||
Tag::FileEventKind(watchexec_events::filekind::FileEventKind::Access(
|
||||
watchexec_events::filekind::AccessKind::Close(
|
||||
watchexec_events::filekind::AccessMode::Write,
|
||||
),
|
||||
)) => {
|
||||
println!("{}", profile_info(profiles_config.clone(), info.clone()));
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
});
|
||||
if action.signals().next().is_some() {
|
||||
println!("Quitting");
|
||||
action.quit();
|
||||
|
|
@ -43,4 +53,4 @@ pub async fn watch(profiles_config: Vec<Profile>,info: ProfileGetCommand,watch_p
|
|||
let _ = main.await.into_diagnostic();
|
||||
//todo: handle this return properly
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,44 +2,63 @@ use std::collections::HashMap;
|
|||
|
||||
use log::debug;
|
||||
|
||||
use crate::{utils::SDUError, config::{Profile, Programs}, lib::profile::active_profile, lib::sway_ipc::{get_sway_connection, run_sway_command}};
|
||||
use crate::{
|
||||
config::{Profile, Programs},
|
||||
lib::profile::active_profile,
|
||||
lib::sway_ipc::{get_sway_connection, run_sway_command},
|
||||
utils::SDUError,
|
||||
};
|
||||
|
||||
pub fn launch( exec: &String, profiles: Vec<Profile>, programs: HashMap<String, Programs> ) -> Result<(), SDUError> {
|
||||
debug!("{}",exec);
|
||||
pub fn launch(
|
||||
exec: &String,
|
||||
profiles: Vec<Profile>,
|
||||
programs: HashMap<String, Programs>,
|
||||
) -> Result<(), SDUError> {
|
||||
debug!("{}", exec);
|
||||
match profile_launch(profiles, programs, exec) {
|
||||
Ok(p) => {
|
||||
debug!("{}",p);
|
||||
run_sway_command(&mut get_sway_connection(),p)
|
||||
},
|
||||
debug!("{}", p);
|
||||
run_sway_command(&mut get_sway_connection(), p)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append_arguments(mut command: String, args: Vec<String>) -> String {
|
||||
for a in args {
|
||||
command = format!("{} {}",command,a);
|
||||
command = format!("{} {}", command, a);
|
||||
}
|
||||
command
|
||||
}
|
||||
|
||||
pub fn profile_launch(profiles: Vec<Profile>, programs_config: HashMap<String, Programs>, program_arg: &String) -> Result<String,SDUError> {
|
||||
match programs_config.iter().find(|x|x.0.eq(program_arg)) {
|
||||
pub fn profile_launch(
|
||||
profiles: Vec<Profile>,
|
||||
programs_config: HashMap<String, Programs>,
|
||||
program_arg: &String,
|
||||
) -> Result<String, SDUError> {
|
||||
match programs_config.iter().find(|x| x.0.eq(program_arg)) {
|
||||
Some(p) => {
|
||||
let mut swaymsg_command = format!("exec {}", p.1.command);
|
||||
swaymsg_command = append_arguments(swaymsg_command, p.1.arguments.clone());
|
||||
match active_profile(profiles) {
|
||||
Ok(profile) => {
|
||||
println!("{:#?}",profile);
|
||||
if let Some(profile_args) = profile.program_args.unwrap_or_default().iter().find(|x|x.0.eq(p.0)) {
|
||||
swaymsg_command = append_arguments(swaymsg_command, profile_args.1.to_owned());
|
||||
println!("{:#?}", profile);
|
||||
if let Some(profile_args) = profile
|
||||
.program_args
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.find(|x| x.0.eq(p.0))
|
||||
{
|
||||
swaymsg_command =
|
||||
append_arguments(swaymsg_command, profile_args.1.to_owned());
|
||||
}
|
||||
Ok(swaymsg_command)
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
None => {
|
||||
Err(SDUError { message: String::from("No matching program found") })
|
||||
},
|
||||
}
|
||||
None => Err(SDUError {
|
||||
message: String::from("No matching program found"),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
132
src/lib/lock.rs
132
src/lib/lock.rs
|
|
@ -1,79 +1,127 @@
|
|||
use std::{env::consts, fs::{self, DirBuilder, write}, io, path::PathBuf, vec};
|
||||
use log::debug;
|
||||
use std::{
|
||||
env::consts,
|
||||
fs::{self, DirBuilder, write},
|
||||
io,
|
||||
path::PathBuf,
|
||||
vec,
|
||||
};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use image::{imageops::GaussianBlurParameters, DynamicImage};
|
||||
use image::{DynamicImage, imageops::GaussianBlurParameters};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use sha2::{Sha256, Digest};
|
||||
use xdg::BaseDirectories;
|
||||
use sha2::{Digest, Sha256};
|
||||
use shellexpand::tilde;
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::{utils::DirectoryType, utils::SDUError, config::LockConf, lib::sway_ipc::get_sway_connection};
|
||||
use crate::{
|
||||
config::LockConf, lib::sway_ipc::get_sway_connection, utils::DirectoryType, utils::SDUError,
|
||||
};
|
||||
|
||||
#[derive(Serialize,Deserialize,Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct WallpaperCache {
|
||||
pub display: String,
|
||||
pub hash: String
|
||||
pub hash: String,
|
||||
}
|
||||
|
||||
pub fn lock_screen(lock_config: LockConf,force_bg_render: bool) -> Result<(),SDUError> {
|
||||
pub fn lock_screen(lock_config: LockConf, force_bg_render: bool) -> Result<(), SDUError> {
|
||||
let mut sway_connection = get_sway_connection();
|
||||
match &lock_config.wallpaper_path {
|
||||
Some(wallpaper_path) => {
|
||||
let wallpaper_root_path = PathBuf::from(tilde(&wallpaper_path).to_string());
|
||||
let wp_cache_dir = get_path(DirectoryType::Cache, "sway-profiles-rs/lock/");
|
||||
|
||||
DirBuilder::new().recursive(true).create(&wp_cache_dir).expect("Failed to create cache directory");
|
||||
DirBuilder::new()
|
||||
.recursive(true)
|
||||
.create(&wp_cache_dir)
|
||||
.expect("Failed to create cache directory");
|
||||
|
||||
let wp_hash_json = wallpaper_check_hash(wp_cache_dir.join("hashes.json"));
|
||||
|
||||
debug!("{:?}",wp_hash_json);
|
||||
debug!("{:?}", wp_hash_json);
|
||||
|
||||
let mut wp_hash_array: Vec<WallpaperCache> = vec![];
|
||||
|
||||
let sway_visible_workspaces = match sway_connection.get_workspaces() {
|
||||
Ok(w) => w.iter().filter(|w|w.visible).cloned().collect(),
|
||||
Ok(w) => w.iter().filter(|w| w.visible).cloned().collect(),
|
||||
Err(_) => vec![],
|
||||
};
|
||||
for workspace in sway_visible_workspaces {
|
||||
debug!("operating on workspace {} ({})",workspace.num, workspace.name);
|
||||
debug!(
|
||||
"operating on workspace {} ({})",
|
||||
workspace.num, workspace.name
|
||||
);
|
||||
let wp_output_path = wallpaper_root_path.join(&workspace.output);
|
||||
let output_image_path = wp_output_path.join(format!("{:0>2}.jpg",workspace.num));
|
||||
let output_image_path = wp_output_path.join(format!("{:0>2}.jpg", workspace.num));
|
||||
let mut wp_sha256 = Sha256::new();
|
||||
let img_file_data = match fs::File::open(&output_image_path) {
|
||||
Ok(mut img_file_data) => Ok(io::copy(&mut img_file_data, &mut wp_sha256).unwrap_or_default()),
|
||||
Err(_) => Err(SDUError { message: format!("Could not open wallpaper image for output {}", workspace.output) }),
|
||||
Ok(mut img_file_data) => {
|
||||
Ok(io::copy(&mut img_file_data, &mut wp_sha256).unwrap_or_default())
|
||||
}
|
||||
Err(_) => Err(SDUError {
|
||||
message: format!(
|
||||
"Could not open wallpaper image for output {}",
|
||||
workspace.output
|
||||
),
|
||||
}),
|
||||
};
|
||||
if img_file_data.is_ok() {
|
||||
let wp_hash = hex::encode(wp_sha256.finalize());
|
||||
let wp_image = image::open(output_image_path).expect("Could not open wallpaper file as image");
|
||||
let output_cache_image_path = wp_cache_dir.join(format!("{}.jpg",workspace.output));
|
||||
let wp_image = image::open(output_image_path)
|
||||
.expect("Could not open wallpaper file as image");
|
||||
let output_cache_image_path =
|
||||
wp_cache_dir.join(format!("{}.jpg", workspace.output));
|
||||
|
||||
match wp_hash_json.iter().find(|wc|wc.display == workspace.output) {
|
||||
Some (saved_hash) => {
|
||||
if !(saved_hash.hash == wp_hash && output_cache_image_path.exists()) || force_bg_render {
|
||||
generate_image(wp_image,output_cache_image_path, lock_config.clone())
|
||||
match wp_hash_json
|
||||
.iter()
|
||||
.find(|wc| wc.display == workspace.output)
|
||||
{
|
||||
Some(saved_hash) => {
|
||||
if !(saved_hash.hash == wp_hash && output_cache_image_path.exists())
|
||||
|| force_bg_render
|
||||
{
|
||||
generate_image(
|
||||
wp_image,
|
||||
output_cache_image_path,
|
||||
lock_config.clone(),
|
||||
)
|
||||
};
|
||||
},
|
||||
None => generate_image(wp_image, output_cache_image_path, lock_config.clone())
|
||||
}
|
||||
None => {
|
||||
generate_image(wp_image, output_cache_image_path, lock_config.clone())
|
||||
}
|
||||
}
|
||||
|
||||
wp_hash_array.push(WallpaperCache { display: workspace.output, hash: wp_hash });
|
||||
wp_hash_array.push(WallpaperCache {
|
||||
display: workspace.output,
|
||||
hash: wp_hash,
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
debug!("{:?}", wp_hash_array);
|
||||
|
||||
debug!("{:?}",wp_hash_array);
|
||||
|
||||
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);
|
||||
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![];
|
||||
|
||||
for gtklock_module in WalkDir::new(gktlock_modules_path).into_iter().filter(|x|x.as_ref().expect("TODO").file_name().to_str().unwrap_or_default().ends_with("-module.so")) {
|
||||
let gtklock_module_path = gtklock_module.expect("TODO").path().to_string_lossy().to_string();
|
||||
for gtklock_module in WalkDir::new(gktlock_modules_path).into_iter().filter(|x| {
|
||||
x.as_ref()
|
||||
.expect("TODO")
|
||||
.file_name()
|
||||
.to_str()
|
||||
.unwrap_or_default()
|
||||
.ends_with("-module.so")
|
||||
}) {
|
||||
let gtklock_module_path = gtklock_module
|
||||
.expect("TODO")
|
||||
.path()
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
debug!("Foud gtklock module: {}", gtklock_module_path);
|
||||
gtklock_args.push("-m".to_owned());
|
||||
gtklock_args.push(gtklock_module_path);
|
||||
|
|
@ -86,14 +134,19 @@ pub fn lock_screen(lock_config: LockConf,force_bg_render: bool) -> Result<(),SDU
|
|||
|
||||
match sway_connection.run_command(gtklock_command) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(SDUError { message: "Could not lock screen!".to_owned() }),
|
||||
Err(_) => Err(SDUError {
|
||||
message: "Could not lock screen!".to_owned(),
|
||||
}),
|
||||
}
|
||||
},
|
||||
None => Err(SDUError { message: "Wallpaper path is not set!".to_owned() }),
|
||||
}
|
||||
None => Err(SDUError {
|
||||
message: "Wallpaper path is not set!".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_image(orig_img_data: DynamicImage,gen_image_path: PathBuf, lock_conf: LockConf) {// Result<(), ImageError> {
|
||||
pub fn generate_image(orig_img_data: DynamicImage, gen_image_path: PathBuf, lock_conf: LockConf) {
|
||||
// Result<(), ImageError> {
|
||||
let w = orig_img_data.width() as f32 * lock_conf.scale;
|
||||
let h = orig_img_data.height() as f32 * lock_conf.scale;
|
||||
let blurred_img_data = orig_img_data
|
||||
|
|
@ -101,13 +154,15 @@ pub fn generate_image(orig_img_data: DynamicImage,gen_image_path: PathBuf, lock_
|
|||
.blur_advanced(GaussianBlurParameters::new_from_sigma(lock_conf.blur));
|
||||
match blurred_img_data.save(gen_image_path) {
|
||||
Ok(_) => println!("Image saved successfully"),
|
||||
Err(e) => println!("error: {:?}",e),
|
||||
Err(e) => println!("error: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
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_default();
|
||||
let wallpaper_hashes: Vec<WallpaperCache> = fs::File::open(hashes_json_path)
|
||||
.ok()
|
||||
.and_then(|f| serde_json::from_reader(f).ok())
|
||||
.unwrap_or_default();
|
||||
wallpaper_hashes
|
||||
}
|
||||
|
||||
|
|
@ -116,6 +171,7 @@ pub fn get_path(dir_type: DirectoryType, suffix: &str) -> PathBuf {
|
|||
let base_dir = match dir_type {
|
||||
DirectoryType::Cache => base_directories.cache_home,
|
||||
DirectoryType::Config => base_directories.config_home,
|
||||
}.expect("HOME could not be found");
|
||||
}
|
||||
.expect("HOME could not be found");
|
||||
base_dir.join(suffix)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,26 @@
|
|||
mod windows;
|
||||
mod workspaces;
|
||||
mod cli;
|
||||
mod get;
|
||||
mod launch;
|
||||
mod lock;
|
||||
mod power;
|
||||
mod profile;
|
||||
mod shortcuts;
|
||||
mod launch;
|
||||
mod get;
|
||||
mod sway_ipc;
|
||||
mod sway;
|
||||
mod lock;
|
||||
mod scratchpad;
|
||||
mod shortcuts;
|
||||
mod sway;
|
||||
mod sway_ipc;
|
||||
mod windows;
|
||||
mod workspaces;
|
||||
|
||||
pub use {
|
||||
windows::get_window_info,
|
||||
workspaces::get_workspace_info,
|
||||
cli::{Cli,Commands},
|
||||
cli::{Cli, Commands},
|
||||
launch::launch,
|
||||
lock::lock_screen,
|
||||
power::power_fn,
|
||||
profile::profile_fn,
|
||||
scratchpad::get_scratchpad_info,
|
||||
shortcuts::shortcuts_fn,
|
||||
launch::launch,
|
||||
sway_ipc::{
|
||||
run_sway_command,
|
||||
get_sway_connection
|
||||
},
|
||||
sway::sway_fn,
|
||||
lock::lock_screen,
|
||||
scratchpad::get_scratchpad_info
|
||||
};
|
||||
sway_ipc::{get_sway_connection, run_sway_command},
|
||||
windows::get_window_info,
|
||||
workspaces::get_workspace_info,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,53 +1,76 @@
|
|||
use {
|
||||
crate::{
|
||||
lib::lock_screen,
|
||||
utils::SDUError, lib::cli::PowerCommand, config::LockConf, run_sway_command, lib::sway_ipc::get_sway_connection
|
||||
}, dialog::DialogBox, log::debug
|
||||
config::LockConf, lib::cli::PowerCommand, lib::lock_screen,
|
||||
lib::sway_ipc::get_sway_connection, run_sway_command, utils::SDUError,
|
||||
},
|
||||
dialog::DialogBox,
|
||||
log::debug,
|
||||
};
|
||||
|
||||
pub fn power_fn(power_command_arg: &Option<PowerCommand>, lock_config: LockConf ) -> Result<(),SDUError> {
|
||||
pub fn power_fn(
|
||||
power_command_arg: &Option<PowerCommand>,
|
||||
lock_config: LockConf,
|
||||
) -> Result<(), SDUError> {
|
||||
match power_command_arg {
|
||||
Some(power_command) => {
|
||||
let action_prompt = match power_command {
|
||||
PowerCommand::Shutdown => vec!["shut down","poweroff.target"],
|
||||
PowerCommand::Reboot => vec!["restart","reboot.target"],
|
||||
PowerCommand::Suspend => vec!["suspend","suspend.target"],
|
||||
PowerCommand::Lock { force_render_background: _ } => vec!["lock"],
|
||||
PowerCommand::Shutdown => vec!["shut down", "poweroff.target"],
|
||||
PowerCommand::Reboot => vec!["restart", "reboot.target"],
|
||||
PowerCommand::Suspend => vec!["suspend", "suspend.target"],
|
||||
PowerCommand::Lock {
|
||||
force_render_background: _,
|
||||
} => vec!["lock"],
|
||||
PowerCommand::Logout => vec!["log out"],
|
||||
};
|
||||
let action = action_prompt.first().unwrap_or(&"not found");
|
||||
if let Ok(dialog::Choice::Yes) = dialog::Question::new(format!("Are you sure you would like to {}?",action)).title(format!("Confirm {}...",action)).show() {
|
||||
if let Ok(dialog::Choice::Yes) =
|
||||
dialog::Question::new(format!("Are you sure you would like to {}?", action))
|
||||
.title(format!("Confirm {}...", action))
|
||||
.show()
|
||||
{
|
||||
match power_command {
|
||||
PowerCommand::Lock { force_render_background } => {
|
||||
PowerCommand::Lock {
|
||||
force_render_background,
|
||||
} => {
|
||||
debug!("running lock_screen function");
|
||||
return lock_screen(lock_config, force_render_background.unwrap_or_default())
|
||||
},
|
||||
return lock_screen(
|
||||
lock_config,
|
||||
force_render_background.unwrap_or_default(),
|
||||
);
|
||||
}
|
||||
PowerCommand::Logout => {
|
||||
debug!("sending exit command to sway");
|
||||
return run_sway_command(&mut get_sway_connection(), "exit".to_string())
|
||||
},
|
||||
return run_sway_command(&mut get_sway_connection(), "exit".to_string());
|
||||
}
|
||||
_ => {
|
||||
let target = action_prompt.get(1).unwrap_or(&"not found");
|
||||
let systemctl = systemctl::SystemCtl::default();
|
||||
debug!("looking for {}",target);
|
||||
debug!("looking for {}", target);
|
||||
if let Ok(true) = systemctl.exists(target) {
|
||||
debug!("found and starting {}",target);
|
||||
debug!("found and starting {}", target);
|
||||
match systemctl.start(target) {
|
||||
Ok(_) => {
|
||||
debug!("started target [{}] successfully", target);
|
||||
return Ok(())
|
||||
},
|
||||
Err(_) => return Err(SDUError { message: format!("Could not start systemctl target [{}]", target) }),
|
||||
return Ok(());
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(SDUError {
|
||||
message: format!(
|
||||
"Could not start systemctl target [{}]",
|
||||
target
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
None => {
|
||||
println!("⏻ Shutdown\n Reboot\n Suspend\n Lock\n Logout");
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,172 +1,258 @@
|
|||
use {
|
||||
crate::{
|
||||
utils::SDUError,
|
||||
lib::{
|
||||
cli::{
|
||||
ProfileCommand,
|
||||
ProfileGetCommand,
|
||||
ProfileSwitchCommand
|
||||
},
|
||||
get,
|
||||
shortcuts_fn,
|
||||
run_sway_command,
|
||||
get_sway_connection
|
||||
},
|
||||
config::{ Config, Profile},
|
||||
config::{Config, Profile},
|
||||
//lib::get,
|
||||
get_xdg_dirs,
|
||||
lib::{
|
||||
cli::{ProfileCommand, ProfileGetCommand, ProfileSwitchCommand},
|
||||
get, get_sway_connection, run_sway_command, shortcuts_fn,
|
||||
},
|
||||
setup_runtime_dir,
|
||||
//lib::shortcuts::shortcuts_fn,
|
||||
//lib::sway_ipc::{get_sway_connection, run_sway_command}
|
||||
utils::SDUError,
|
||||
},
|
||||
log::{debug, error},
|
||||
serde_json::json,
|
||||
std::fs::{self, DirBuilder, write},
|
||||
swayipc::Connection,
|
||||
xdg::BaseDirectories
|
||||
xdg::BaseDirectories,
|
||||
};
|
||||
|
||||
pub fn profile_fn(profile_command: &ProfileCommand, profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<(),SDUError> {
|
||||
pub fn profile_fn(
|
||||
profile_command: &ProfileCommand,
|
||||
profiles_config: Vec<Profile>,
|
||||
preserve_keyboard_order: bool,
|
||||
) -> Result<(), SDUError> {
|
||||
let xdg_dirs = get_xdg_dirs();
|
||||
setup_runtime_dir(xdg_dirs);
|
||||
match profile_command {
|
||||
ProfileCommand::Init => {
|
||||
let active_profile_index = active_profile_index();
|
||||
match switch_by_index(profiles_config, active_profile_index, preserve_keyboard_order) {
|
||||
match switch_by_index(
|
||||
profiles_config,
|
||||
active_profile_index,
|
||||
preserve_keyboard_order,
|
||||
) {
|
||||
Ok(_) => {
|
||||
let _: () = debug!("successfully initialized sway-de-utils");
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
ProfileCommand::Switch { switch_command} => {
|
||||
match switch_command {
|
||||
Some(ProfileSwitchCommand::To { index,name,query }) => {
|
||||
match index {
|
||||
Some(i) => {
|
||||
switch_by_index(profiles_config, *i, preserve_keyboard_order)
|
||||
},
|
||||
None => {
|
||||
match name {
|
||||
Some(n) => {
|
||||
switch_by_name(profiles_config, n.to_string(), preserve_keyboard_order)
|
||||
},
|
||||
None => match query {
|
||||
Some(q) => match q.parse::<usize>() {
|
||||
Ok(i) => match switch_by_index(profiles_config.clone(), i, preserve_keyboard_order) {
|
||||
Ok(o) => Ok(o),
|
||||
Err(_) => switch_by_name(profiles_config, q.to_string(), preserve_keyboard_order),
|
||||
},
|
||||
Err(_) => switch_by_name(profiles_config, q.to_string(), preserve_keyboard_order),
|
||||
},
|
||||
None => Err(SDUError { message: "No profile index or name provided.".to_string() }),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
ProfileCommand::Switch { switch_command } => match switch_command {
|
||||
Some(ProfileSwitchCommand::To { index, name, query }) => match index {
|
||||
Some(i) => switch_by_index(profiles_config, *i, preserve_keyboard_order),
|
||||
None => match name {
|
||||
Some(n) => {
|
||||
switch_by_name(profiles_config, n.to_string(), preserve_keyboard_order)
|
||||
}
|
||||
None => match query {
|
||||
Some(q) => match q.parse::<usize>() {
|
||||
Ok(i) => match switch_by_index(
|
||||
profiles_config.clone(),
|
||||
i,
|
||||
preserve_keyboard_order,
|
||||
) {
|
||||
Ok(o) => Ok(o),
|
||||
Err(_) => switch_by_name(
|
||||
profiles_config,
|
||||
q.to_string(),
|
||||
preserve_keyboard_order,
|
||||
),
|
||||
},
|
||||
Err(_) => switch_by_name(
|
||||
profiles_config,
|
||||
q.to_string(),
|
||||
preserve_keyboard_order,
|
||||
),
|
||||
},
|
||||
None => Err(SDUError {
|
||||
message: "No profile index or name provided.".to_string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
Some(ProfileSwitchCommand::Next) => match next(profiles_config, preserve_keyboard_order) {
|
||||
},
|
||||
Some(ProfileSwitchCommand::Next) => {
|
||||
match next(profiles_config, preserve_keyboard_order) {
|
||||
Ok(_) => {
|
||||
debug!("Successfully switched to next profile");
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
Some(ProfileSwitchCommand::Prev) => match previous(profiles_config, preserve_keyboard_order) {
|
||||
}
|
||||
}
|
||||
Some(ProfileSwitchCommand::Prev) => {
|
||||
match previous(profiles_config, preserve_keyboard_order) {
|
||||
Ok(_) => {
|
||||
debug!("successfully switched to previous profile");
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
None => {
|
||||
for profile in profiles_config {
|
||||
println!("{} {}", profile.icon, profile.name);
|
||||
};
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
None => {
|
||||
for profile in profiles_config {
|
||||
println!("{} {}", profile.icon, profile.name);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
ProfileCommand::Get { get_command, monitor } => {
|
||||
ProfileCommand::Get {
|
||||
get_command,
|
||||
monitor,
|
||||
} => {
|
||||
let profile_detail = get_command.clone().unwrap_or(ProfileGetCommand::Json);
|
||||
println!("{}",get::profile_info(profiles_config.clone(),profile_detail.clone()));
|
||||
println!(
|
||||
"{}",
|
||||
get::profile_info(profiles_config.clone(), profile_detail.clone())
|
||||
);
|
||||
let _: () = if monitor.unwrap_or_default() {
|
||||
let _ = get::watch(profiles_config, profile_detail,get_xdg_dirs().runtime_dir.expect("XDG Runtime dir could not be found").join("sway-de-utils/active-profile.json").to_str().expect("could not create str from path").to_string());
|
||||
let _ = get::watch(
|
||||
profiles_config,
|
||||
profile_detail,
|
||||
get_xdg_dirs()
|
||||
.runtime_dir
|
||||
.expect("XDG Runtime dir could not be found")
|
||||
.join("sway-de-utils/active-profile.json")
|
||||
.to_str()
|
||||
.expect("could not create str from path")
|
||||
.to_string(),
|
||||
);
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
ProfileCommand::Shortcuts { shortcut_command } => {
|
||||
let active_profile = active_profile(profiles_config).expect("could not determine active profile");
|
||||
shortcuts_fn(shortcut_command, active_profile.scripts.expect("could not find scripts for profile"))
|
||||
},
|
||||
let active_profile =
|
||||
active_profile(profiles_config).expect("could not determine active profile");
|
||||
shortcuts_fn(
|
||||
shortcut_command,
|
||||
active_profile
|
||||
.scripts
|
||||
.expect("could not find scripts for profile"),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize(mut sway_connection: Connection, profile: Profile,uindex: usize, preserve_keyboard_order: bool) -> Result<(),SDUError> { //payload: String) {
|
||||
fn initialize(
|
||||
mut sway_connection: Connection,
|
||||
profile: Profile,
|
||||
uindex: usize,
|
||||
preserve_keyboard_order: bool,
|
||||
) -> Result<(), SDUError> {
|
||||
//payload: String) {
|
||||
for i in 0..10 {
|
||||
let workspace = (uindex*10) + match i.eq(&0) && !preserve_keyboard_order {
|
||||
true => 10,
|
||||
false => i,
|
||||
};
|
||||
debug!("key {}: workspace {}",i,workspace);
|
||||
debug!("bindsym $mod+{} workspace number {}:{}",i,workspace,profile.icon);
|
||||
let workspace = (uindex * 10)
|
||||
+ match i.eq(&0) && !preserve_keyboard_order {
|
||||
true => 10,
|
||||
false => i,
|
||||
};
|
||||
debug!("key {}: workspace {}", i, workspace);
|
||||
debug!(
|
||||
"bindsym $mod+{} workspace number {}:{}",
|
||||
i, workspace, profile.icon
|
||||
);
|
||||
|
||||
match run_sway_command(&mut sway_connection, format!("bindsym $mod+{} workspace number {}:{}",i,workspace,profile.icon)) {
|
||||
match run_sway_command(
|
||||
&mut sway_connection,
|
||||
format!(
|
||||
"bindsym $mod+{} workspace number {}:{}",
|
||||
i, workspace, profile.icon
|
||||
),
|
||||
) {
|
||||
Ok(_) => (),
|
||||
Err(_) => todo!(),
|
||||
}
|
||||
match run_sway_command(&mut sway_connection, format!("bindsym $mod+Shift+{} move container to workspace number {}:{}",i,workspace,profile.icon)) {
|
||||
match run_sway_command(
|
||||
&mut sway_connection,
|
||||
format!(
|
||||
"bindsym $mod+Shift+{} move container to workspace number {}:{}",
|
||||
i, workspace, profile.icon
|
||||
),
|
||||
) {
|
||||
Ok(_) => (),
|
||||
Err(_) => todo!(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let base_directories = BaseDirectories::new();
|
||||
let active_profile_cache = base_directories.get_runtime_directory().expect("why tf do xdg dirs not exist").join("sway-de-utils/active-profile.json");
|
||||
let active_profile_cache = base_directories
|
||||
.get_runtime_directory()
|
||||
.expect("why tf do xdg dirs not exist")
|
||||
.join("sway-de-utils/active-profile.json");
|
||||
let active_profile = json!(uindex);
|
||||
|
||||
DirBuilder::new().recursive(true).create(active_profile_cache.parent().expect("Unable to determine cache dir")).expect("Failed to create cache directory");
|
||||
|
||||
DirBuilder::new()
|
||||
.recursive(true)
|
||||
.create(
|
||||
active_profile_cache
|
||||
.parent()
|
||||
.expect("Unable to determine cache dir"),
|
||||
)
|
||||
.expect("Failed to create cache directory");
|
||||
match write(active_profile_cache, active_profile.to_string()) {
|
||||
Ok(o) => debug!("{:#?}",o),
|
||||
Err(e) => debug!("{:#?}",e),
|
||||
Ok(o) => debug!("{:#?}", o),
|
||||
Err(e) => debug!("{:#?}", e),
|
||||
};
|
||||
|
||||
match run_sway_command(&mut sway_connection, format!("workspace number {}:{}",(uindex*10)+1,profile.icon)) {
|
||||
match run_sway_command(
|
||||
&mut sway_connection,
|
||||
format!("workspace number {}:{}", (uindex * 10) + 1, profile.icon),
|
||||
) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn profile_from_index(profiles: Vec<Profile>, index: usize) -> Profile {
|
||||
profiles.get(index).expect("Profile not found for index").clone()
|
||||
profiles
|
||||
.get(index)
|
||||
.expect("Profile not found for index")
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn _profile_from_name(config: Config, name: String) -> Result<Profile,SDUError> {
|
||||
match config.profiles.iter().find(|x|x.name == name) {
|
||||
pub fn _profile_from_name(config: Config, name: String) -> Result<Profile, SDUError> {
|
||||
match config.profiles.iter().find(|x| x.name == name) {
|
||||
Some(p) => Ok(p.clone()),
|
||||
None => Err(SDUError { message: format!("Profile not found with name {}",name) }),
|
||||
None => Err(SDUError {
|
||||
message: format!("Profile not found with name {}", name),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_by_index(profiles_config: Vec<Profile>,index: usize, preserve_keyboard_order: bool) -> Result<(),SDUError> {
|
||||
fn switch_by_index(
|
||||
profiles_config: Vec<Profile>,
|
||||
index: usize,
|
||||
preserve_keyboard_order: bool,
|
||||
) -> Result<(), SDUError> {
|
||||
let profile = profile_from_index(profiles_config, index);
|
||||
match initialize(get_sway_connection(), profile, index, preserve_keyboard_order) {
|
||||
match initialize(
|
||||
get_sway_connection(),
|
||||
profile,
|
||||
index,
|
||||
preserve_keyboard_order,
|
||||
) {
|
||||
Ok(_) => {
|
||||
println!("successfully switched to profile at index {}",index);
|
||||
println!("successfully switched to profile at index {}", index);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_by_name(profiles_config: Vec<Profile>,name: String,preserve_keyboard_order: bool) -> Result<(),SDUError> {
|
||||
fn switch_by_name(
|
||||
profiles_config: Vec<Profile>,
|
||||
name: String,
|
||||
preserve_keyboard_order: bool,
|
||||
) -> Result<(), SDUError> {
|
||||
match index_from_name(profiles_config.clone(), name.clone()) {
|
||||
Ok(index) => match switch_by_index(profiles_config, index,preserve_keyboard_order) {
|
||||
Ok(index) => match switch_by_index(profiles_config, index, preserve_keyboard_order) {
|
||||
Ok(_) => {
|
||||
println!("Successfully switched to profile with name {}",name);
|
||||
println!("Successfully switched to profile with name {}", name);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
|
|
@ -175,11 +261,15 @@ fn switch_by_name(profiles_config: Vec<Profile>,name: String,preserve_keyboard_o
|
|||
|
||||
pub fn active_profile_index() -> usize {
|
||||
let base_directories = BaseDirectories::new();
|
||||
let active_profile_cache_json = base_directories.get_runtime_directory().expect("xdg dirs do not exist?").join("sway-de-utils/active-profile.json");
|
||||
let active_profile_cache_json = base_directories
|
||||
.get_runtime_directory()
|
||||
.expect("xdg dirs do not exist?")
|
||||
.join("sway-de-utils/active-profile.json");
|
||||
|
||||
if active_profile_cache_json.exists() {
|
||||
fs::File::open(active_profile_cache_json).ok()
|
||||
.and_then(|f|serde_json::from_reader::<fs::File,usize>(f).ok())
|
||||
fs::File::open(active_profile_cache_json)
|
||||
.ok()
|
||||
.and_then(|f| serde_json::from_reader::<fs::File, usize>(f).ok())
|
||||
.expect("could not parse active profile cache file")
|
||||
} else {
|
||||
error!("no active profile cache file");
|
||||
|
|
@ -187,14 +277,16 @@ pub fn active_profile_index() -> usize {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn active_profile(profiles: Vec<Profile>) -> Result<Profile,SDUError> {
|
||||
pub fn active_profile(profiles: Vec<Profile>) -> Result<Profile, SDUError> {
|
||||
match profiles.get(active_profile_index()) {
|
||||
Some(p) => Ok(p.clone()),
|
||||
None => Err(SDUError { message: "Could not get profile by index".to_string() }),
|
||||
None => Err(SDUError {
|
||||
message: "Could not get profile by index".to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn next(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<(),SDUError> {
|
||||
fn next(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<(), SDUError> {
|
||||
let profile_count = profiles_config.len();
|
||||
let mut next_profile = active_profile_index() + 1;
|
||||
if next_profile.ge(&profile_count) {
|
||||
|
|
@ -202,14 +294,14 @@ fn next(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<
|
|||
}
|
||||
match switch_by_index(profiles_config, next_profile, preserve_keyboard_order) {
|
||||
Ok(_) => {
|
||||
println!("switched to next profile ({})",next_profile);
|
||||
println!("switched to next profile ({})", next_profile);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn previous(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<(),SDUError> {
|
||||
fn previous(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Result<(), SDUError> {
|
||||
let profile_index = active_profile_index();
|
||||
let prev_profile: usize = if profile_index.eq(&0) {
|
||||
profiles_config.len() - 1
|
||||
|
|
@ -218,16 +310,18 @@ fn previous(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Res
|
|||
};
|
||||
match switch_by_index(profiles_config, prev_profile, preserve_keyboard_order) {
|
||||
Ok(_) => {
|
||||
println!("switched to prev profile ({})",prev_profile);
|
||||
println!("switched to prev profile ({})", prev_profile);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index_from_name(profiles_config: Vec<Profile>, name: String) -> Result<usize, SDUError>{
|
||||
match profiles_config.iter().position(|x|x.name == name) {
|
||||
pub fn index_from_name(profiles_config: Vec<Profile>, name: String) -> Result<usize, SDUError> {
|
||||
match profiles_config.iter().position(|x| x.name == name) {
|
||||
Some(i) => Ok(i),
|
||||
None => Err(SDUError { message: "Index not found for profile?".to_string() }),
|
||||
None => Err(SDUError {
|
||||
message: "Index not found for profile?".to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,39 +7,43 @@ use swayipc::{Node, ScratchpadState};
|
|||
|
||||
use crate::lib::get_sway_connection;
|
||||
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct ScratchpadInfo {
|
||||
icon: PathBuf,
|
||||
visible: bool,
|
||||
name: Option<String>,
|
||||
title: Option<String>,
|
||||
window_id: i64
|
||||
window_id: i64,
|
||||
}
|
||||
|
||||
fn app_icon_lookup(name: &str) -> Option<PathBuf> {
|
||||
lookup(name).with_theme("breeze").with_theme("Adwaita").with_size(64).with_cache().find()
|
||||
lookup(name)
|
||||
.with_theme("breeze")
|
||||
.with_theme("Adwaita")
|
||||
.with_size(64)
|
||||
.with_cache()
|
||||
.find()
|
||||
}
|
||||
|
||||
fn get_app_icon(window: Node) -> PathBuf {
|
||||
app_icon_lookup(&window.sandbox_app_id.unwrap_or_default()).or(
|
||||
match window.window_properties {
|
||||
app_icon_lookup(&window.sandbox_app_id.unwrap_or_default())
|
||||
.or(match window.window_properties {
|
||||
Some(w) => app_icon_lookup(&w.class.unwrap_or_default()),
|
||||
None => app_icon_lookup(&window.app_id.unwrap_or_default()),
|
||||
}
|
||||
).unwrap_or("/usr/share/icons/breeze-dark/mimetypes/32/unknown.svg".into())
|
||||
})
|
||||
.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);
|
||||
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);
|
||||
debug!("appending {:?} to {:?}", nodes, node_list);
|
||||
node_list.append(&mut nodes);
|
||||
}
|
||||
}
|
||||
|
|
@ -60,15 +64,32 @@ fn scratchpad_strip(node: Node) -> ScratchpadInfo {
|
|||
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 }
|
||||
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 scratch_start = Instant::now();
|
||||
|
||||
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());
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,51 @@
|
|||
use log::debug;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{utils::SDUError, lib::cli::{ShortcutCommand, ShortcutMode}, config::ScriptConf, lib::sway_ipc::{get_sway_connection, run_sway_command}};
|
||||
use crate::{
|
||||
config::ScriptConf,
|
||||
lib::cli::{ShortcutCommand, ShortcutMode},
|
||||
lib::sway_ipc::{get_sway_connection, run_sway_command},
|
||||
utils::SDUError,
|
||||
};
|
||||
|
||||
fn print_shortcuts(mode: &ShortcutMode, shortcuts: Vec<ScriptConf>) -> String {
|
||||
match mode {
|
||||
ShortcutMode::Dmenu => {
|
||||
let mut dmenu_shortcuts: String = String::new();
|
||||
for shortcut in shortcuts {
|
||||
dmenu_shortcuts = format!("{}\n{} {}",dmenu_shortcuts,shortcut.icon, shortcut.name)
|
||||
};
|
||||
dmenu_shortcuts =
|
||||
format!("{}\n{} {}", dmenu_shortcuts, shortcut.icon, shortcut.name)
|
||||
}
|
||||
dmenu_shortcuts
|
||||
},
|
||||
ShortcutMode::Json => {
|
||||
json!(shortcuts).to_string()
|
||||
},
|
||||
}
|
||||
ShortcutMode::Json => json!(shortcuts).to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_shortcut(shortcut_name: String, shortcuts: Vec<ScriptConf>) -> Result<(),SDUError> {
|
||||
let shortcut = shortcuts.iter().find(|x|x.name.eq(&shortcut_name)).expect("cannot find shortcut with name");
|
||||
fn exec_shortcut(shortcut_name: String, shortcuts: Vec<ScriptConf>) -> Result<(), SDUError> {
|
||||
let shortcut = shortcuts
|
||||
.iter()
|
||||
.find(|x| x.name.eq(&shortcut_name))
|
||||
.expect("cannot find shortcut with name");
|
||||
debug!("running [{}]", shortcut.command);
|
||||
run_sway_command(&mut get_sway_connection(), format!("exec {}",shortcut.command.clone()))
|
||||
run_sway_command(
|
||||
&mut get_sway_connection(),
|
||||
format!("exec {}", shortcut.command.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn shortcuts_fn(shortcut_command: &ShortcutCommand, shortcuts: Vec<ScriptConf> ) -> Result<(),SDUError> {
|
||||
pub fn shortcuts_fn(
|
||||
shortcut_command: &ShortcutCommand,
|
||||
shortcuts: Vec<ScriptConf>,
|
||||
) -> Result<(), SDUError> {
|
||||
match shortcut_command {
|
||||
ShortcutCommand::Execute { shortcut_name } => exec_shortcut(shortcut_name.to_string(), shortcuts),
|
||||
ShortcutCommand::Execute { shortcut_name } => {
|
||||
exec_shortcut(shortcut_name.to_string(), shortcuts)
|
||||
}
|
||||
ShortcutCommand::Get { mode } => {
|
||||
let shortcuts_string = print_shortcuts(&mode.unwrap_or(ShortcutMode::Json), shortcuts);
|
||||
println!("{}", shortcuts_string);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
use {
|
||||
crate::{
|
||||
config::{Profile, WindowIcon}, lib::{
|
||||
cli::{
|
||||
SwayCommand,
|
||||
SwayGetCommand
|
||||
}, get_scratchpad_info, get_window_info, get_workspace_info, sway_ipc::{
|
||||
self,
|
||||
get_sway_info
|
||||
}
|
||||
}, utils::SDUError
|
||||
config::{Profile, WindowIcon},
|
||||
lib::{
|
||||
cli::{SwayCommand, SwayGetCommand},
|
||||
get_scratchpad_info, get_window_info, get_workspace_info,
|
||||
sway_ipc::{self, get_sway_info},
|
||||
},
|
||||
utils::SDUError,
|
||||
},
|
||||
swayipc::EventType
|
||||
swayipc::EventType,
|
||||
};
|
||||
|
||||
pub fn sway_fn( sway_command: &SwayCommand, window_icons: &[WindowIcon], profile_list: Vec<Profile>, kb_order: bool) -> Result<(),SDUError> {
|
||||
pub fn sway_fn(
|
||||
sway_command: &SwayCommand,
|
||||
window_icons: &[WindowIcon],
|
||||
profile_list: Vec<Profile>,
|
||||
kb_order: bool,
|
||||
) -> Result<(), SDUError> {
|
||||
match sway_command {
|
||||
SwayCommand::Get { monitor, get_command } => {
|
||||
SwayCommand::Get {
|
||||
monitor,
|
||||
get_command,
|
||||
} => {
|
||||
let requested_info = get_command.as_ref().unwrap_or(&SwayGetCommand::Full);
|
||||
let sway_json = match requested_info {
|
||||
SwayGetCommand::Workspaces => get_workspace_info(profile_list.clone(), kb_order),
|
||||
|
|
@ -23,16 +29,24 @@ pub fn sway_fn( sway_command: &SwayCommand, window_icons: &[WindowIcon], profile
|
|||
SwayGetCommand::Full => get_sway_info(window_icons, profile_list.clone(), kb_order),
|
||||
SwayGetCommand::Scratchpad => get_scratchpad_info(),
|
||||
};
|
||||
println!("{}",sway_json);
|
||||
println!("{}", sway_json);
|
||||
let _: () = if monitor.unwrap_or_default() {
|
||||
let event_monitors = match requested_info {
|
||||
SwayGetCommand::Workspaces => vec![EventType::Workspace],
|
||||
SwayGetCommand::Scratchpad => vec![EventType::Window],
|
||||
SwayGetCommand::Window | SwayGetCommand::Full => vec![EventType::Window,EventType::Workspace],
|
||||
SwayGetCommand::Window | SwayGetCommand::Full => {
|
||||
vec![EventType::Window, EventType::Workspace]
|
||||
}
|
||||
};
|
||||
sway_ipc::monitor_events(event_monitors, requested_info, window_icons, profile_list, kb_order);
|
||||
sway_ipc::monitor_events(
|
||||
event_monitors,
|
||||
requested_info,
|
||||
window_icons,
|
||||
profile_list,
|
||||
kb_order,
|
||||
);
|
||||
};
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,58 +1,81 @@
|
|||
use {
|
||||
crate::{
|
||||
config::{Profile, WindowIcon}, lib::{cli::SwayGetCommand, get_scratchpad_info, windows::get_window_info, workspaces::get_workspace_info}, utils::SDUError
|
||||
}, log::debug, serde_json::{Value, json}, std::time::Instant, swayipc::{
|
||||
Connection,
|
||||
EventType
|
||||
}
|
||||
config::{Profile, WindowIcon},
|
||||
lib::{
|
||||
cli::SwayGetCommand, get_scratchpad_info, windows::get_window_info,
|
||||
workspaces::get_workspace_info,
|
||||
},
|
||||
utils::SDUError,
|
||||
},
|
||||
log::debug,
|
||||
serde_json::{Value, json},
|
||||
std::time::Instant,
|
||||
swayipc::{Connection, EventType},
|
||||
};
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct SwayInfo {
|
||||
window_info: Value,
|
||||
workspace_info: Value,
|
||||
scratchpad_info: Value
|
||||
scratchpad_info: Value,
|
||||
}
|
||||
|
||||
pub fn get_sway_connection() -> Connection {
|
||||
Connection::new().expect("Unable to connect to Sway IPC")
|
||||
}
|
||||
|
||||
pub fn run_sway_command(sway_connection: &mut Connection,payload: String) -> Result<(),SDUError> {
|
||||
pub fn run_sway_command(sway_connection: &mut Connection, payload: String) -> Result<(), SDUError> {
|
||||
match sway_connection.run_command(&payload) {
|
||||
Ok(sway_result) => {
|
||||
debug!("{:#?}", sway_result);
|
||||
debug!("Command [{}] ran successfully",payload);
|
||||
debug!("Command [{}] ran successfully", payload);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(SDUError{ message: e.to_string() }),
|
||||
}
|
||||
Err(e) => Err(SDUError {
|
||||
message: e.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_sway_info(window_icons: &[WindowIcon], profile_list: Vec<Profile>, kb_order: bool) -> Value {
|
||||
pub fn get_sway_info(
|
||||
window_icons: &[WindowIcon],
|
||||
profile_list: Vec<Profile>,
|
||||
kb_order: bool,
|
||||
) -> Value {
|
||||
let window_info = get_window_info(window_icons);
|
||||
let workspace_info = get_workspace_info(profile_list, kb_order);
|
||||
let scratchpad_info = get_scratchpad_info();
|
||||
let full_info = SwayInfo{ window_info, workspace_info, scratchpad_info };
|
||||
let full_info = SwayInfo {
|
||||
window_info,
|
||||
workspace_info,
|
||||
scratchpad_info,
|
||||
};
|
||||
json!(full_info)
|
||||
}
|
||||
|
||||
pub fn monitor_events(event_type: Vec<EventType>, get_command: &SwayGetCommand, window_icons: &[WindowIcon], profile_list: Vec<Profile>, kb_order: bool) {
|
||||
pub fn monitor_events(
|
||||
event_type: Vec<EventType>,
|
||||
get_command: &SwayGetCommand,
|
||||
window_icons: &[WindowIcon],
|
||||
profile_list: Vec<Profile>,
|
||||
kb_order: bool,
|
||||
) {
|
||||
let sway_connection = get_sway_connection();
|
||||
for event in sway_connection.subscribe(event_type).expect("unable to subscribe to sway events") {
|
||||
for event in sway_connection
|
||||
.subscribe(event_type)
|
||||
.expect("unable to subscribe to sway events")
|
||||
{
|
||||
let start = Instant::now();
|
||||
let sway_json = match event.expect("unable to parse sway event") {
|
||||
swayipc::Event::Workspace(_) | swayipc::Event::Window(_) => {
|
||||
match get_command {
|
||||
SwayGetCommand::Window => get_window_info(window_icons),
|
||||
SwayGetCommand::Workspaces => get_workspace_info(profile_list.clone(), kb_order),
|
||||
SwayGetCommand::Full => get_sway_info(window_icons, profile_list.clone(), kb_order),
|
||||
SwayGetCommand::Scratchpad => get_scratchpad_info(),
|
||||
}
|
||||
swayipc::Event::Workspace(_) | swayipc::Event::Window(_) => match get_command {
|
||||
SwayGetCommand::Window => get_window_info(window_icons),
|
||||
SwayGetCommand::Workspaces => get_workspace_info(profile_list.clone(), kb_order),
|
||||
SwayGetCommand::Full => get_sway_info(window_icons, profile_list.clone(), kb_order),
|
||||
SwayGetCommand::Scratchpad => get_scratchpad_info(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
println!("{}",sway_json);
|
||||
log::debug!("time taken: {:?}",start.elapsed());
|
||||
println!("{}", sway_json);
|
||||
log::debug!("time taken: {:?}", start.elapsed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +1,58 @@
|
|||
use {
|
||||
log::debug,
|
||||
serde_json::{
|
||||
Value,
|
||||
json
|
||||
},
|
||||
swayipc::Connection,
|
||||
crate::config::WindowIcon,
|
||||
log::debug,
|
||||
serde_json::{Value, json},
|
||||
swayipc::Connection,
|
||||
};
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct WindowInfo {
|
||||
pub title: String,
|
||||
pub window_count: usize
|
||||
pub window_count: usize,
|
||||
}
|
||||
|
||||
pub fn get_window_info(window_icons: &[WindowIcon]) -> Value {
|
||||
let mut sway_connection = Connection::new().expect("Unable to connect to sway ipc socket");
|
||||
let nodes_tree = sway_connection.get_tree().expect("Unable to parse Sway node tree");
|
||||
let focused_workspace_raw = nodes_tree.iter()
|
||||
.find(|x|x.node_type.eq(&swayipc::NodeType::Workspace) && x.iter().any(|x|x.focused));
|
||||
let nodes_tree = sway_connection
|
||||
.get_tree()
|
||||
.expect("Unable to parse Sway node tree");
|
||||
let focused_workspace_raw = nodes_tree
|
||||
.iter()
|
||||
.find(|x| x.node_type.eq(&swayipc::NodeType::Workspace) && x.iter().any(|x| x.focused));
|
||||
let window_count = match focused_workspace_raw {
|
||||
Some(ws) => ws.iter().filter(|x|(x.node_type.eq(&swayipc::NodeType::Con) || x.node_type.eq(&swayipc::NodeType::FloatingCon)) && x.name.is_some()).count(),
|
||||
Some(ws) => ws
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
(x.node_type.eq(&swayipc::NodeType::Con)
|
||||
|| x.node_type.eq(&swayipc::NodeType::FloatingCon))
|
||||
&& x.name.is_some()
|
||||
})
|
||||
.count(),
|
||||
None => 0,
|
||||
};
|
||||
debug!("{:#?}",window_count);
|
||||
debug!("{:#?}", window_count);
|
||||
let window_title = if window_count.gt(&0) {
|
||||
let window_node = nodes_tree.iter().find(|x|x.focused);
|
||||
let window_node = nodes_tree.iter().find(|x| x.focused);
|
||||
//debug!("{:#?}",window_node);
|
||||
match window_node {
|
||||
Some(n) => {
|
||||
let mut window_name = n.name.clone().unwrap_or_default();
|
||||
for pair in window_icons {
|
||||
if window_name.contains(&pair.substring) {
|
||||
window_name = format!("{} {}", pair.icon, window_name.replace(&pair.substring, ""))
|
||||
window_name =
|
||||
format!("{} {}", pair.icon, window_name.replace(&pair.substring, ""))
|
||||
}
|
||||
}
|
||||
Some(window_name)
|
||||
},
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let window_info = WindowInfo { title: window_title.unwrap_or_default(), window_count};
|
||||
let window_info = WindowInfo {
|
||||
title: window_title.unwrap_or_default(),
|
||||
window_count,
|
||||
};
|
||||
json!(window_info)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use {
|
||||
crate::{config::Profile, lib::profile}, serde_json::{
|
||||
Value,
|
||||
json,
|
||||
}, swayipc::Connection
|
||||
crate::{config::Profile, lib::profile},
|
||||
serde_json::{Value, json},
|
||||
swayipc::Connection,
|
||||
};
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
|
|
@ -12,34 +11,58 @@ pub struct WorkspaceInfo {
|
|||
pub profile: usize,
|
||||
pub profile_name: String,
|
||||
pub is_focused: bool,
|
||||
pub position: char
|
||||
pub position: char,
|
||||
}
|
||||
|
||||
fn get_workspace_profile(profile_index: usize, profile_list: Vec<Profile>, kb_order: bool) -> String {
|
||||
fn get_workspace_profile(
|
||||
profile_index: usize,
|
||||
profile_list: Vec<Profile>,
|
||||
kb_order: bool,
|
||||
) -> String {
|
||||
let ws_profile_index = if kb_order {
|
||||
(profile_index - 1) / 10
|
||||
} else {
|
||||
profile_index / 10
|
||||
};
|
||||
profile_list.get(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 {
|
||||
let workspaces = Connection::new().expect("unable to connect to sway IPC").get_workspaces().expect("Unable to parse sway workspaces");
|
||||
let current_ws = workspaces.iter().find(|&x| x.focused).expect("unable to find focused workspace").num;
|
||||
let workspaces = Connection::new()
|
||||
.expect("unable to connect to sway IPC")
|
||||
.get_workspaces()
|
||||
.expect("Unable to parse sway workspaces");
|
||||
let current_ws = workspaces
|
||||
.iter()
|
||||
.find(|&x| x.focused)
|
||||
.expect("unable to find focused workspace")
|
||||
.num;
|
||||
let mut workspaces_info: Vec<WorkspaceInfo> = vec![];
|
||||
for workspace in workspaces {
|
||||
let mut ws_position = 'c';
|
||||
if current_ws.lt(&workspace.num) {
|
||||
ws_position = 'r';
|
||||
} else if current_ws.gt(&workspace.num){
|
||||
} else if current_ws.gt(&workspace.num) {
|
||||
ws_position = 'l';
|
||||
}
|
||||
let ws_profile = get_workspace_profile(workspace.num as usize, profile_list.clone(), kb_order);
|
||||
let ws_profile_num = profile::index_from_name(profile_list.clone(), ws_profile.clone()).expect("could not determine profile index of workspace");
|
||||
let workspace_info = WorkspaceInfo { num: workspace.num, name: workspace.name, profile: ws_profile_num, profile_name: ws_profile, is_focused: workspace.focused, position: ws_position };
|
||||
let ws_profile =
|
||||
get_workspace_profile(workspace.num as usize, profile_list.clone(), kb_order);
|
||||
let ws_profile_num = profile::index_from_name(profile_list.clone(), ws_profile.clone())
|
||||
.expect("could not determine profile index of workspace");
|
||||
let workspace_info = WorkspaceInfo {
|
||||
num: workspace.num,
|
||||
name: workspace.name,
|
||||
profile: ws_profile_num,
|
||||
profile_name: ws_profile,
|
||||
is_focused: workspace.focused,
|
||||
position: ws_position,
|
||||
};
|
||||
workspaces_info.push(workspace_info);
|
||||
}
|
||||
workspaces_info.sort_by(|a, b| a.num.cmp(&b.num));
|
||||
json!(workspaces_info)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
47
src/main.rs
47
src/main.rs
|
|
@ -2,35 +2,31 @@
|
|||
//#![allow(clippy::style)]
|
||||
|
||||
mod config;
|
||||
mod utils;
|
||||
#[path = "lib/mod.rs"]
|
||||
mod lib;
|
||||
mod utils;
|
||||
|
||||
use {
|
||||
crate::{
|
||||
lib::{
|
||||
Cli,
|
||||
Commands,
|
||||
launch,
|
||||
lock_screen,
|
||||
sway_fn,
|
||||
profile_fn,
|
||||
run_sway_command,
|
||||
power_fn,
|
||||
shortcuts_fn
|
||||
},
|
||||
config::Config,
|
||||
utils::{setup_runtime_dir,get_xdg_dirs}
|
||||
lib::{
|
||||
Cli, Commands, launch, lock_screen, power_fn, profile_fn, run_sway_command,
|
||||
shortcuts_fn, sway_fn,
|
||||
},
|
||||
utils::{get_xdg_dirs, setup_runtime_dir},
|
||||
},
|
||||
clap::Parser,
|
||||
log::{debug, error},
|
||||
std::process::exit
|
||||
std::process::exit,
|
||||
};
|
||||
|
||||
fn main() -> Result<(),()> {
|
||||
fn main() -> Result<(), ()> {
|
||||
env_logger::init();
|
||||
let cli = Cli::parse();
|
||||
let config = if confy::get_configuration_file_path("sway-de-utils", "config").expect("Unable to determine config file location").exists() {
|
||||
let config = if confy::get_configuration_file_path("sway-de-utils", "config")
|
||||
.expect("Unable to determine config file location")
|
||||
.exists()
|
||||
{
|
||||
confy::load("sway-de-utils", "config").unwrap_or_default()
|
||||
} else {
|
||||
let _ = confy::store("sway-de-utils", "config", Config::default());
|
||||
|
|
@ -38,12 +34,23 @@ fn main() -> Result<(),()> {
|
|||
};
|
||||
|
||||
let sdu_result = match &cli.command {
|
||||
Commands::Sway { sway_command } => sway_fn(sway_command, &config.window_icons, config.profiles, config.preserve_keyboard_order),
|
||||
Commands::Sway { sway_command } => sway_fn(
|
||||
sway_command,
|
||||
&config.window_icons,
|
||||
config.profiles,
|
||||
config.preserve_keyboard_order,
|
||||
),
|
||||
Commands::Launch { program } => launch(program, config.profiles, config.programs),
|
||||
Commands::Lock { force_render_background } => lock_screen(config.lock, force_render_background.unwrap_or_default()),
|
||||
Commands::Profile { profile_command} => profile_fn(profile_command, config.profiles, config.preserve_keyboard_order),
|
||||
Commands::Lock {
|
||||
force_render_background,
|
||||
} => lock_screen(config.lock, force_render_background.unwrap_or_default()),
|
||||
Commands::Profile { profile_command } => profile_fn(
|
||||
profile_command,
|
||||
config.profiles,
|
||||
config.preserve_keyboard_order,
|
||||
),
|
||||
Commands::Shortcuts { shortcut_command } => shortcuts_fn(shortcut_command, config.scripts),
|
||||
Commands::Power { power_command } => power_fn(power_command, config.lock)
|
||||
Commands::Power { power_command } => power_fn(power_command, config.lock),
|
||||
};
|
||||
match sdu_result {
|
||||
Ok(_) => debug!("Command ran successfully"),
|
||||
|
|
|
|||
11
src/utils.rs
11
src/utils.rs
|
|
@ -1,16 +1,13 @@
|
|||
use {
|
||||
log::debug,
|
||||
xdg::BaseDirectories
|
||||
};
|
||||
use {log::debug, xdg::BaseDirectories};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SDUError {
|
||||
pub message: String
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
pub enum DirectoryType {
|
||||
Cache,
|
||||
Config
|
||||
Config,
|
||||
}
|
||||
|
||||
pub fn setup_runtime_dir(xdg_directories: BaseDirectories) {
|
||||
|
|
@ -22,4 +19,4 @@ pub fn setup_runtime_dir(xdg_directories: BaseDirectories) {
|
|||
|
||||
pub fn get_xdg_dirs() -> BaseDirectories {
|
||||
BaseDirectories::new()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue