Compare commits

...

2 commits

Author SHA1 Message Date
Penelope Gwen
1bdab513b6 begin implementing scratchpad functionality 2026-01-19 18:10:48 -08:00
Penelope Gwen
96991b6ff1 some refactoring 2026-01-19 18:10:22 -08:00
18 changed files with 244 additions and 128 deletions

2
Cargo.lock generated
View file

@ -1783,7 +1783,7 @@ dependencies = [
[[package]]
name = "sway-de-utils"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"clap",
"confy",

View file

@ -1,6 +1,6 @@
[package]
name = "sway-de-utils"
version = "0.1.0"
version = "0.1.1"
authors = ["Penelope Gwen <support@pogmom.me>"]
edition = "2024"
license-file = "LICENSE.md"
@ -30,3 +30,7 @@ walkdir = "2.5.0"
watchexec = "8.0.1"
watchexec-events = "6.0.0"
xdg = "3.0.0"
[package.metadata.deb]
#conflicts = ["sway-profiles"]
changelog = "debian/changelog"

11
debian/changelog vendored Normal file
View file

@ -0,0 +1,11 @@
sway-de-utils (0.1.1-1) unstable; urgency=medium
* increase information provided by sdu sway get workspaces
-- Penelope Gwen <support@pogmom.me> Tue, 13 Jan 2026 19:26:17 -0800
sway-de-utils (0.1.0-1) unstable; urgency=medium
* Initial release.
-- Penelope Gwen <support@pogmom.me> Tue, 13 Jan 2026 19:23:17 -0800

View file

@ -1,5 +1,10 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use {
std::collections::HashMap,
serde::{
Deserialize,
Serialize
}
};
#[derive(Serialize,Deserialize,Clone, Debug)]
pub struct WindowIcon {

View file

@ -1,8 +1,4 @@
use clap::{
ArgAction,
Parser,
Subcommand, ValueEnum
};
use clap::{ArgAction, Parser, Subcommand, ValueEnum};
#[derive(Parser)]
#[command(version, about, long_about = None)]
@ -119,8 +115,11 @@ pub enum SwayGetCommand {
#[clap(alias = "ws")]
Workspaces,
/// Get Window Information
#[clap(alias = "n")]
#[clap(alias = "wi")]
Window,
/// Get Scratchpad Information
#[clap(alias = "s")]
Scratchpad,
/// Get Window and Workspace Information in one JSON output
#[clap(alias = "f")]
Full

View file

@ -1,13 +1,15 @@
use {
crate::{
cli::ProfileGetCommand, config::Profile, profile::{
active_profile_index,
profile_from_index
config::Profile,
lib::{
cli::ProfileGetCommand,
profile::{active_profile_index, profile_from_index}
}
}, miette::{
IntoDiagnostic,
Result
}, serde_json::json, watchexec::Watchexec, watchexec_events::Tag
},
miette::{IntoDiagnostic, Result},
serde_json::json,
watchexec::Watchexec,
watchexec_events::Tag
};
pub fn profile_info(profiles: Vec<Profile>,info: ProfileGetCommand) -> String {

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use log::debug;
use crate::{SDUError, config::{Profile, Programs}, profile::active_profile, sway_ipc::{get_sway_connection, run_sway_command}};
use crate::{utils::SDUError, config::{Profile, Programs}, lib::profile::active_profile, lib::sway_ipc::{get_sway_connection, run_sway_command}};
pub fn launch( exec: &String, profiles: Vec<Profile>, programs: HashMap<String, Programs> ) -> Result<(), SDUError> {
debug!("{}",exec);

View file

@ -9,7 +9,7 @@ use sha2::{Sha256, Digest};
use xdg::BaseDirectories;
use shellexpand::tilde;
use crate::{DirectoryType, SDUError, config::LockConf, sway_ipc::get_sway_connection};
use crate::{utils::DirectoryType, utils::SDUError, config::LockConf, lib::sway_ipc::get_sway_connection};
#[derive(Serialize,Deserialize,Debug)]
pub struct WallpaperCache {
@ -17,7 +17,7 @@ pub struct WallpaperCache {
pub hash: String
}
pub fn lock(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) => {

29
src/lib/mod.rs Normal file
View file

@ -0,0 +1,29 @@
mod windows;
mod workspaces;
mod cli;
mod power;
mod profile;
mod shortcuts;
mod launch;
mod get;
mod sway_ipc;
mod sway;
mod lock;
mod scratchpad;
pub use {
windows::get_window_info,
workspaces::get_workspace_info,
cli::{Cli,Commands},
power::power_fn,
profile::profile_fn,
shortcuts::shortcuts_fn,
launch::launch,
sway_ipc::{
run_sway_command,
get_sway_connection
},
sway::sway_fn,
lock::lock_screen,
scratchpad::get_scratchpad_info
};

View file

@ -1,10 +1,11 @@
use {
crate::{
SDUError, cli::PowerCommand, config::LockConf, lock, run_sway_command, sway_ipc::get_sway_connection
lib::lock_screen,
utils::SDUError, lib::cli::PowerCommand, config::LockConf, run_sway_command, lib::sway_ipc::get_sway_connection
}, dialog::DialogBox, log::debug
};
pub fn power(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 {
@ -19,7 +20,7 @@ pub fn power(power_command_arg: &Option<PowerCommand>, lock_config: LockConf ) -
match power_command {
PowerCommand::Lock { force_render_background } => {
debug!("running lock_screen function");
return lock(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");

View file

@ -1,16 +1,23 @@
use {
crate::{
SDUError,
cli::{
ProfileCommand,
ProfileGetCommand,
ProfileSwitchCommand
}, config::{ Config, Profile},
/*error_handler,*/ get,
utils::SDUError,
lib::{
cli::{
ProfileCommand,
ProfileGetCommand,
ProfileSwitchCommand
},
get,
shortcuts_fn,
run_sway_command,
get_sway_connection
},
config::{ Config, Profile},
//lib::get,
get_xdg_dirs,
setup_runtime_dir,
shortcuts::shortcuts,
sway_ipc::{get_sway_connection, run_sway_command}
//lib::shortcuts::shortcuts_fn,
//lib::sway_ipc::{get_sway_connection, run_sway_command}
},
log::{debug, error},
serde_json::json,
@ -19,7 +26,7 @@ use {
xdg::BaseDirectories
};
pub fn profile(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 {
@ -91,12 +98,12 @@ pub fn profile(profile_command: &ProfileCommand, profiles_config: Vec<Profile>,
}
ProfileCommand::Shortcuts { shortcut_command } => {
let active_profile = active_profile(profiles_config).expect("could not determine active profile");
shortcuts(shortcut_command, active_profile.scripts.expect("could not find scripts for profile"))
shortcuts_fn(shortcut_command, active_profile.scripts.expect("could not find scripts for profile"))
},
}
}
pub 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,
@ -106,8 +113,11 @@ pub fn initialize(mut sway_connection: Connection, profile: Profile,uindex: usiz
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)) {
Ok(_) => {
},
Ok(_) => (),
Err(_) => todo!(),
}
match run_sway_command(&mut sway_connection, format!("bindsym $mod+Shift+{} move container to workspace number {}:{}",i,workspace,profile.icon)) {
Ok(_) => (),
Err(_) => todo!(),
}
};
@ -139,7 +149,7 @@ pub fn _profile_from_name(config: Config, name: String) -> Result<Profile,SDUErr
}
}
pub 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) {
Ok(_) => {
@ -150,7 +160,7 @@ pub fn switch_by_index(profiles_config: Vec<Profile>,index: usize, preserve_keyb
}
}
pub 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(_) => {
@ -184,7 +194,7 @@ pub fn active_profile(profiles: Vec<Profile>) -> Result<Profile,SDUError> {
}
}
pub 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) {
@ -199,7 +209,7 @@ pub fn next(profiles_config: Vec<Profile>, preserve_keyboard_order: bool) -> Res
}
}
pub 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

55
src/lib/scratchpad.rs Normal file
View file

@ -0,0 +1,55 @@
use log::debug;
use serde_json::Value;
use swayipc::{Node, NodeType};
use crate::lib::get_sway_connection;
fn search_node(node: Node, indent: String, search_type: NodeType) -> Vec<Node> {
let mut node_vec: Vec<Node> = vec![];
println!("{}{:?}: {} - {:?} ({} nodes)", indent, node.node_type, node.name.unwrap_or_default(), node.scratchpad_state, node.nodes.len()+node.floating_nodes.len());
for n in node.nodes {
for nn in search_node(n, indent.clone()+"--", search_type) {
node_vec.push(nn);
}
/* match search_node(n, indent.clone()+"--", search_type) {
Some(n) => node_vec.push(n),
None => todo!(),
} */
};
for f in node.floating_nodes {
for ff in search_node(f, indent.clone()+"--", search_type) {
node_vec.push(ff);
}
/* match search_node(f, indent.clone()+"--", search_type) {
Some(_) => todo!(),
None => todo!(),
} */
};
node_vec
}
pub fn get_scratchpad_info() -> Value {
let tree = get_sway_connection().get_tree().expect("todo");
// search_node(tree, "-".to_string());
for output in tree.nodes {
println!("{:?}",output.node_type);
for workspace in output.nodes {
println!("{:?}",workspace.node_type);
for node in workspace.nodes {
let con_nodes = search_node(node, "--".to_string(), NodeType::Con);
println!("con_nodes: {:?}", con_nodes.len())
}
for floating_node in workspace.floating_nodes {
let floating_nodes = search_node(floating_node, "--".to_string(), NodeType::Con);
println!("floating_nodes: {:?}", floating_nodes.len())
}
}
}
//let outputs = tree.nodes.iter()//.filter(|x|x.node_type.eq(&swayipc::NodeType::Output));//.expect("todo"); //(|x|x.t .clone().unwrap().eq("__i3")).expect("todo").clone().find(|x|x.node_type.eq(&swayipc::NodeType::Workspace));
//for w in outputs {
// let workspace = w.f
//}
//let workspaces = outputs.nodes.iter().find(|x|x.node_type.eq(&swayipc::NodeType::Workspace)).expect("todo");
//println!("{:#?}",workspaces);
Value::Null
}

View file

@ -1,9 +1,9 @@
use log::debug;
use serde_json::json;
use crate::{SDUError, cli::{ShortcutCommand, ShortcutMode}, config::ScriptConf, sway_ipc::{get_sway_connection, run_sway_command}};
use crate::{utils::SDUError, lib::cli::{ShortcutCommand, ShortcutMode}, config::ScriptConf, lib::sway_ipc::{get_sway_connection, run_sway_command}};
pub fn print_shortcuts(mode: &ShortcutMode, shortcuts: Vec<ScriptConf>) -> String {
fn print_shortcuts(mode: &ShortcutMode, shortcuts: Vec<ScriptConf>) -> String {
match mode {
ShortcutMode::Dmenu => {
let mut dmenu_shortcuts: String = String::new();
@ -18,13 +18,13 @@ pub fn print_shortcuts(mode: &ShortcutMode, shortcuts: Vec<ScriptConf>) -> Strin
}
}
pub fn exec_shortcut(shortcut_name: String, shortcuts: Vec<ScriptConf>) -> Result<(),SDUError> {
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()))
}
pub fn shortcuts(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::Get { mode } => {

View file

@ -1,32 +1,36 @@
use {
crate::{
SDUError, cli::{
SwayCommand,
SwayGetCommand
}, config::WindowIcon, get_window_info, get_workspace_info, sway_ipc::{
self,
get_sway_info
}
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
};
pub fn sway( sway_command: &SwayCommand, window_icons: &[WindowIcon] ) -> 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 } => {
let requested_info = get_command.as_ref().unwrap_or(&SwayGetCommand::Full);
let sway_json = match requested_info {
SwayGetCommand::Workspaces => get_workspace_info(),
SwayGetCommand::Workspaces => get_workspace_info(profile_list.clone(), kb_order),
SwayGetCommand::Window => get_window_info(window_icons),
SwayGetCommand::Full => get_sway_info(window_icons),
SwayGetCommand::Full => get_sway_info(window_icons, profile_list.clone(), kb_order),
SwayGetCommand::Scratchpad => get_scratchpad_info(),
};
println!("{}",sway_json);
let _: () = if monitor.unwrap_or_default() {
let event_monitors = match requested_info {
SwayGetCommand::Workspaces => vec![EventType::Workspace],
SwayGetCommand::Scratchpad => todo!(),
SwayGetCommand::Window | SwayGetCommand::Full => vec![EventType::Window,EventType::Workspace],
};
sway_ipc::monitor_events(event_monitors, requested_info, window_icons);
sway_ipc::monitor_events(event_monitors, requested_info, window_icons, profile_list, kb_order);
};
Ok(())
},

View file

@ -1,6 +1,6 @@
use {
crate::{
SDUError, cli::SwayGetCommand, config::WindowIcon, windows::get_window_info, workspaces::get_workspace_info
config::{Profile, WindowIcon}, lib::{cli::SwayGetCommand, windows::get_window_info, workspaces::get_workspace_info}, utils::SDUError
}, log::debug, serde_json::{Value, json}, std::time::Instant, swayipc::{
Connection,
EventType
@ -28,14 +28,14 @@ pub fn run_sway_command(sway_connection: &mut Connection,payload: String) -> Res
}
}
pub fn get_sway_info(window_icons: &[WindowIcon]) -> 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();
let workspace_info = get_workspace_info(profile_list, kb_order);
let full_info = SwayInfo{ window_info, workspace_info };
json!(full_info)
}
pub fn monitor_events(event_type: Vec<EventType>, get_command: &SwayGetCommand, window_icons: &[WindowIcon]) {
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") {
let start = Instant::now();
@ -43,8 +43,9 @@ pub fn monitor_events(event_type: Vec<EventType>, get_command: &SwayGetCommand,
swayipc::Event::Workspace(_) | swayipc::Event::Window(_) => {
match get_command {
SwayGetCommand::Window => get_window_info(window_icons),
SwayGetCommand::Workspaces => get_workspace_info(),
SwayGetCommand::Full => get_sway_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 => todo!(),
}
},
_ => unreachable!(),

View file

@ -1,20 +1,30 @@
use {
swayipc::Connection,
serde_json::{
crate::{config::Profile, lib::profile}, serde_json::{
Value,
json,
}
}, swayipc::Connection
};
#[derive(serde::Serialize)]
pub struct WorkspaceInfo {
pub num: i32,
pub name: String,
pub profile: usize,
pub profile_name: String,
pub is_focused: bool,
pub position: char
}
pub fn get_workspace_info() -> Value {
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.iter().nth(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 mut workspaces_info: Vec<WorkspaceInfo> = vec![];
@ -25,7 +35,9 @@ pub fn get_workspace_info() -> Value {
} else if current_ws.gt(&workspace.num){
ws_position = 'l';
}
let workspace_info = WorkspaceInfo { num: workspace.num, name: workspace.name, 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));

View file

@ -2,73 +2,31 @@
#![allow(clippy::style)]
mod config;
#[path = "lib/windows.rs"]
mod windows;
#[path = "lib/workspaces.rs"]
mod workspaces;
#[path = "lib/lock.rs"]
mod lock;
#[path = "lib/launch.rs"]
mod launch;
#[path = "lib/sway_ipc.rs"]
mod sway_ipc;
#[path = "lib/profile.rs"]
mod profile;
#[path = "lib/get.rs"]
mod get;
#[path = "lib/sway.rs"]
mod sway;
#[path = "lib/power.rs"]
mod power;
#[path = "lib/cli.rs"]
mod cli;
#[path = "lib/shortcuts.rs"]
mod shortcuts;
mod utils;
#[path = "lib/mod.rs"]
mod lib;
use {
crate::{
cli::{
lib::{
Cli,
Commands
Commands,
launch,
lock_screen,
sway_fn,
profile_fn,
run_sway_command,
power_fn,
shortcuts_fn
},
config::Config,
power::power,
shortcuts::shortcuts,
sway::sway
utils::{setup_runtime_dir,get_xdg_dirs}
},
clap::Parser,
launch::launch,
lock::lock,
log::{debug, error},
profile::profile,
std::process::exit,
sway_ipc::run_sway_command,
windows::get_window_info,
workspaces::get_workspace_info,
xdg::BaseDirectories
std::process::exit
};
pub enum DirectoryType {
Cache,
Config
}
#[derive(Debug)]
pub struct SDUError {
message: String
}
pub fn setup_runtime_dir(xdg_directories: BaseDirectories) {
match xdg_directories.create_runtime_directory("sway-de-utils") {
Ok(_) => debug!("created runtime directories"),
Err(_) => debug!("failed to create runtime directories"),
}
}
pub fn get_xdg_dirs() -> BaseDirectories {
BaseDirectories::new()
}
fn main() -> Result<(),()> {
env_logger::init();
let cli = Cli::parse();
@ -80,12 +38,12 @@ fn main() -> Result<(),()> {
};
let sdu_result = match &cli.command {
Commands::Sway { sway_command } => sway(sway_command, &config.window_icons),
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(config.lock, force_render_background.unwrap_or_default()),
Commands::Profile { profile_command} => profile(profile_command, config.profiles, config.preserve_keyboard_order),
Commands::Shortcuts { shortcut_command } => shortcuts(shortcut_command, config.scripts),
Commands::Power { power_command } => power(power_command, config.lock)
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)
};
match sdu_result {
Ok(_) => debug!("Command ran successfully"),

View file

@ -0,0 +1,25 @@
use {
log::debug,
xdg::BaseDirectories
};
#[derive(Debug)]
pub struct SDUError {
pub message: String
}
pub enum DirectoryType {
Cache,
Config
}
pub fn setup_runtime_dir(xdg_directories: BaseDirectories) {
match xdg_directories.create_runtime_directory("sway-de-utils") {
Ok(_) => debug!("created runtime directories"),
Err(_) => debug!("failed to create runtime directories"),
}
}
pub fn get_xdg_dirs() -> BaseDirectories {
BaseDirectories::new()
}