From 82153d31c9ad3302b2144fa184dd9fa1132d837d Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 25 Aug 2024 22:24:06 -0400 Subject: [PATCH] Update to current winapi, split project --- Cargo.lock | 406 ++++++++++++++++-- Cargo.toml | 29 +- crates/auto_mute_cli/Cargo.toml | 27 ++ crates/auto_mute_cli/src/main.rs | 52 +++ crates/auto_mute_gui/Cargo.toml | 10 + crates/auto_mute_gui/src/main.rs | 70 +++ crates/auto_mute_lib/Cargo.toml | 28 ++ .../src}/device_notification_client.rs | 7 +- crates/auto_mute_lib/src/lib.rs | 6 + .../auto_mute_lib/src/muter.rs | 61 +-- .../auto_mute_lib/src}/pid_to_exe.rs | 4 +- .../src}/session_notification.rs | 14 +- .../auto_mute_lib/src}/sm_session_notifier.rs | 12 +- .../auto_mute_lib/src}/window_change.rs | 6 +- mute.txt | 4 +- res/muted.ico | Bin 0 -> 4158 bytes res/unmuted.ico | Bin 0 -> 4286 bytes todo.txt | 2 - 18 files changed, 593 insertions(+), 145 deletions(-) create mode 100644 crates/auto_mute_cli/Cargo.toml create mode 100644 crates/auto_mute_cli/src/main.rs create mode 100644 crates/auto_mute_gui/Cargo.toml create mode 100644 crates/auto_mute_gui/src/main.rs create mode 100644 crates/auto_mute_lib/Cargo.toml rename {src => crates/auto_mute_lib/src}/device_notification_client.rs (89%) create mode 100644 crates/auto_mute_lib/src/lib.rs rename src/main.rs => crates/auto_mute_lib/src/muter.rs (71%) rename {src => crates/auto_mute_lib/src}/pid_to_exe.rs (94%) rename {src => crates/auto_mute_lib/src}/session_notification.rs (55%) rename {src => crates/auto_mute_lib/src}/sm_session_notifier.rs (95%) rename {src => crates/auto_mute_lib/src}/window_change.rs (96%) create mode 100644 res/muted.ico create mode 100644 res/unmuted.ico diff --git a/Cargo.lock b/Cargo.lock index 425b450..29ab0c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,35 +3,213 @@ version = 3 [[package]] -name = "auto_mute_tool" +name = "auto_mute_cli" version = "0.2.0" dependencies = [ + "auto_mute_lib", "windows", ] [[package]] -name = "proc-macro2" -version = "1.0.51" +name = "auto_mute_gui" +version = "0.2.0" +dependencies = [ + "auto_mute_lib", + "native-windows-derive", + "native-windows-gui", +] + +[[package]] +name = "auto_mute_lib" +version = "0.2.0" +dependencies = [ + "windows", + "windows-core", +] + +[[package]] +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "native-windows-derive" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76134ae81020d89d154f619fd2495a2cecad204276b1dc21174b55e4d0975edd" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "native-windows-gui" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7003a669f68deb6b7c57d74fff4f8e533c44a3f0b297492440ef4ff5a28454" +dependencies = [ + "bitflags", + "lazy_static", + "newline-converter", + "plotters", + "plotters-backend", + "stretch", + "winapi", + "winapi-build", +] + +[[package]] +name = "newline-converter" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] -name = "syn" -version = "1.0.107" +name = "serde" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "stretch" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0dc6d20ce137f302edf90f9cd3d278866fd7fb139efca6f246161222ad6d87" +dependencies = [ + "lazy_static", + "libm", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -39,53 +217,203 @@ dependencies = [ ] [[package]] -name = "unicode-ident" -version = "1.0.6" +name = "syn" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.44.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ "windows-implement", "windows-interface", + "windows-result", + "windows-strings", "windows-targets", ] [[package]] name = "windows-implement" -version = "0.44.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce87ca8e3417b02dc2a8a22769306658670ec92d78f1bd420d6310a67c245c6" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "windows-interface" -version = "0.44.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f69a591ecd4f810d29f17e902d40e349fb05b0b11fff63b08b826bfe39c7f" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -94,42 +422,48 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index b0ffade..6f685a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,3 @@ -[package] -name = "auto_mute_tool" -version = "0.2.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies.windows] -version = "0.44.0" -features = [ - "implement", - "Win32_Media_Audio", - "Win32_UI_Shell_PropertiesSystem", - "Data_Xml_Dom", - "Win32_UI", - "Win32_UI_Accessibility", - "Win32_Foundation", - "Win32_Security", - "Win32_System_Threading", - "Win32_UI_WindowsAndMessaging", - "Win32_System_Com", - "Win32_System_Com_StructuredStorage", - "Win32_Devices_FunctionDiscovery", - "Win32_Storage_FileSystem", - "Win32_System_WindowsProgramming", -] \ No newline at end of file +[workspace] +members = ["crates/*"] +resolver = "2" \ No newline at end of file diff --git a/crates/auto_mute_cli/Cargo.toml b/crates/auto_mute_cli/Cargo.toml new file mode 100644 index 0000000..34dfb17 --- /dev/null +++ b/crates/auto_mute_cli/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "auto_mute_cli" +version = "0.2.0" +edition = "2021" + +[dependencies.windows] +version = "0.58.0" +features = [ + "implement", + "Win32_Media_Audio", + "Win32_UI_Shell_PropertiesSystem", + "Data_Xml_Dom", + "Win32_UI", + "Win32_UI_Accessibility", + "Win32_Foundation", + "Win32_Security", + "Win32_System_Threading", + "Win32_UI_WindowsAndMessaging", + "Win32_System_Com", + "Win32_System_Com_StructuredStorage", + "Win32_Devices_FunctionDiscovery", + "Win32_Storage_FileSystem", + "Win32_System_WindowsProgramming", +] + +[dependencies] +auto_mute_lib = { path = "../auto_mute_lib" } \ No newline at end of file diff --git a/crates/auto_mute_cli/src/main.rs b/crates/auto_mute_cli/src/main.rs new file mode 100644 index 0000000..a226d0d --- /dev/null +++ b/crates/auto_mute_cli/src/main.rs @@ -0,0 +1,52 @@ +use std::{ + collections::HashSet, + env, + error::Error, + fs::{self, File}, + io::{BufRead, BufReader}, +}; + +use auto_mute_lib::muter::MuterThread; +use windows::{ + Win32::{ + Foundation::HANDLE, + Storage::FileSystem::{ + FindCloseChangeNotification, FindFirstChangeNotificationW, FindNextChangeNotification, + FILE_NOTIFY_CHANGE_LAST_WRITE, + }, + System::{ + Com::{CoInitializeEx, COINIT_MULTITHREADED}, + Threading::{WaitForSingleObject, INFINITE} + }, + }, core::w, +}; + +pub fn load_mute_txt(file_name: &str) -> HashSet { + let file = File::open(file_name).unwrap(); + HashSet::from_iter(BufReader::new(file).lines().map(|line| line.unwrap())) +} + +pub fn await_file_change(file_name: &str) -> Result<(), Box> { + unsafe { + let md = fs::metadata(file_name)?.modified()?; + let handle = FindFirstChangeNotificationW(w!("."), false, FILE_NOTIFY_CHANGE_LAST_WRITE)?; + while md == fs::metadata(file_name)?.modified()? { + WaitForSingleObject(HANDLE(handle.0), INFINITE); + FindNextChangeNotification(handle)?; + } + println!("File change detected, restarting"); + FindCloseChangeNotification(handle)?; + Ok(()) + } +} + +fn main() { + unsafe { + CoInitializeEx(None, COINIT_MULTITHREADED).unwrap(); + } + let mute_file: String = env::args().nth(1).unwrap_or("mute.txt".to_string()); + loop { + let mut _mt = MuterThread::new(load_mute_txt(&mute_file)); + await_file_change(&mute_file).unwrap(); + } +} diff --git a/crates/auto_mute_gui/Cargo.toml b/crates/auto_mute_gui/Cargo.toml new file mode 100644 index 0000000..9087d59 --- /dev/null +++ b/crates/auto_mute_gui/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "auto_mute_gui" +version = "0.2.0" +edition = "2021" + + +[dependencies] +auto_mute_lib = { path = "../auto_mute_lib" } +native-windows-gui = "1.0.13" +native-windows-derive = "1.0.5" \ No newline at end of file diff --git a/crates/auto_mute_gui/src/main.rs b/crates/auto_mute_gui/src/main.rs new file mode 100644 index 0000000..c5bb190 --- /dev/null +++ b/crates/auto_mute_gui/src/main.rs @@ -0,0 +1,70 @@ +extern crate native_windows_gui as nwg; +extern crate native_windows_derive as nwd; + +use nwd::NwgUi; +use nwg::NativeUi; + + +#[derive(Default, NwgUi)] +pub struct BasicApp { + #[nwg_control(size: (300, 515), position: (300, 300), title: "Basic example", flags: "WINDOW")] + window: nwg::Window, + + #[nwg_resource(source_file: Some("./res/muted.ico"))] + muted_icon: nwg::Icon, + + #[nwg_resource(source_file: Some("./res/unmuted.ico"))] + unmuted_icon: nwg::Icon, + + #[nwg_layout(parent: window, spacing: 1)] + grid: nwg::GridLayout, + + #[nwg_control()] + #[nwg_layout_item(layout: grid, row: 0, col: 0)] + listbox: nwg::ListBox, + + #[nwg_control(text: "Test", size: (50, 50))] + #[nwg_layout_item(layout: grid, col: 0, row: 1, row_span: 2)] + hello_button: nwg::Button, + + #[nwg_control(parent: window, popup: true)] + tray_menu: nwg::Menu, + + #[nwg_control(parent: tray_menu, text: "Show")] + #[nwg_events(OnMenuItemSelected: [BasicApp::on_show])] + tray_show: nwg::MenuItem, + + #[nwg_control(parent: tray_menu)] + tray_sep: nwg::MenuSeparator, + + #[nwg_control(parent: tray_menu, text: "Exit")] + #[nwg_events(OnMenuItemSelected: [BasicApp::on_close])] + tray_exit: nwg::MenuItem, + + #[nwg_control(icon: Some(&data.muted_icon))] + #[nwg_events( OnContextMenu: [BasicApp::on_menu] )] + tray: nwg::TrayNotification, +} + +impl BasicApp { + fn on_close(&self) { + nwg::stop_thread_dispatch(); + } + + fn on_show(&self) { + self.window.set_visible(true); + self.listbox.set_collection(vec!["potato".to_string(), "good".to_string()]); + } + + fn on_menu(&self) { + let (x, y) = nwg::GlobalCursor::position(); + self.tray_menu.popup(x, y); + } +} + +fn main() { + nwg::init().expect("Failed to init Native Windows GUI"); + nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font"); + let _app = BasicApp::build_ui(Default::default()).expect("Failed to build UI"); + nwg::dispatch_thread_events(); +} diff --git a/crates/auto_mute_lib/Cargo.toml b/crates/auto_mute_lib/Cargo.toml new file mode 100644 index 0000000..2b2c9f1 --- /dev/null +++ b/crates/auto_mute_lib/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "auto_mute_lib" +version = "0.2.0" +edition = "2021" + +[dependencies] +windows-core = "0.58.0" + +[dependencies.windows] +version = "0.58.0" +features = [ + "implement", + "Win32_Media_Audio", + "Win32_UI_Shell_PropertiesSystem", + "Data_Xml_Dom", + "Win32_UI", + "Win32_UI_Accessibility", + "Win32_Foundation", + "Win32_Security", + "Win32_System_Threading", + "Win32_UI_WindowsAndMessaging", + "Win32_System_Com", + "Win32_System_Com_StructuredStorage", + "Win32_Devices_FunctionDiscovery", + "Win32_Storage_FileSystem", + "Win32_System_WindowsProgramming", + "Win32_System_Variant" +] diff --git a/src/device_notification_client.rs b/crates/auto_mute_lib/src/device_notification_client.rs similarity index 89% rename from src/device_notification_client.rs rename to crates/auto_mute_lib/src/device_notification_client.rs index b379ea8..7e71b9c 100644 --- a/src/device_notification_client.rs +++ b/crates/auto_mute_lib/src/device_notification_client.rs @@ -1,5 +1,4 @@ -use windows::Win32::Media::Audio::{IMMNotificationClient, IMMNotificationClient_Impl}; - +use windows::Win32::Media::Audio::{IMMNotificationClient, IMMNotificationClient_Impl, DEVICE_STATE}; pub trait DeviceNotificationObserver { fn add_device(&self, device_id: &windows::core::PCWSTR); } @@ -9,11 +8,11 @@ pub(crate) struct DeviceNotificationClient { pub observer: Box, } -impl IMMNotificationClient_Impl for DeviceNotificationClient { +impl IMMNotificationClient_Impl for DeviceNotificationClient_Impl { fn OnDeviceStateChanged( &self, _pwstrdeviceid: &windows::core::PCWSTR, - _dwnewstate: u32, + _dwnewstate: DEVICE_STATE, ) -> windows::core::Result<()> { Ok(()) } diff --git a/crates/auto_mute_lib/src/lib.rs b/crates/auto_mute_lib/src/lib.rs new file mode 100644 index 0000000..69700d3 --- /dev/null +++ b/crates/auto_mute_lib/src/lib.rs @@ -0,0 +1,6 @@ +mod device_notification_client; +mod pid_to_exe; +mod session_notification; +mod sm_session_notifier; +mod window_change; +pub mod muter; \ No newline at end of file diff --git a/src/main.rs b/crates/auto_mute_lib/src/muter.rs similarity index 71% rename from src/main.rs rename to crates/auto_mute_lib/src/muter.rs index e06ea69..6e2241d 100644 --- a/src/main.rs +++ b/crates/auto_mute_lib/src/muter.rs @@ -1,44 +1,23 @@ -mod device_notification_client; -mod pid_to_exe; -mod session_notification; -mod sm_session_notifier; -mod window_change; use std::{ collections::HashSet, - env, error::Error, ffi::OsString, - fs::{self, File}, - io::{BufRead, BufReader}, path::Path, ptr::null_mut, sync::mpsc::{self, Receiver, Sender}, thread::{self, JoinHandle}, }; -use sm_session_notifier::SMSessionNotifierThread; -use window_change::WindowChangeMonitor; +use crate::sm_session_notifier::SMSessionNotifierThread; +use crate::window_change::WindowChangeMonitor; use windows::{ core::Interface, - w, - Win32::{ - Foundation::HANDLE, - Media::Audio::{IAudioSessionControl2, ISimpleAudioVolume}, - Storage::FileSystem::{ - FindCloseChangeNotification, FindFirstChangeNotificationW, FindNextChangeNotification, - FILE_NOTIFY_CHANGE_LAST_WRITE, - }, - System::{ - Com::{CoInitializeEx, COINIT_MULTITHREADED}, - Threading::WaitForSingleObject, - WindowsProgramming::INFINITE, - }, - }, + Win32::Media::Audio::{IAudioSessionControl2, ISimpleAudioVolume}, }; -use crate::pid_to_exe::pid_to_exe_path; +use crate::pid_to_exe::pid_to_exe_path; enum MuterMessage { WindowChange(String), AddSession(IAudioSessionControl2), @@ -116,7 +95,7 @@ impl SessionMuter { .sessions .iter() .map(|session_control2| session_control2.cast::()) - .map(|vol_result| vol_result.map(|volume| volume.SetMute(mute, null_mut()))); + .map(|vol_result| vol_result?.SetMute(mute, null_mut())); for err in results.filter_map(|x| x.err()) { println!("Error muting a session: {:?}", err); } @@ -182,33 +161,3 @@ impl Drop for MuterThread { } } } - -fn load_mute_txt(file_name: &str) -> HashSet { - let file = File::open(file_name).unwrap(); - HashSet::from_iter(BufReader::new(file).lines().map(|line| line.unwrap())) -} - -fn await_file_change(file_name: &str) -> Result<(), Box> { - unsafe { - let md = fs::metadata(file_name)?.modified()?; - let handle = FindFirstChangeNotificationW(w!("."), false, FILE_NOTIFY_CHANGE_LAST_WRITE)?; - while md == fs::metadata(file_name)?.modified()? { - WaitForSingleObject(HANDLE(handle.0), INFINITE).ok()?; - FindNextChangeNotification(handle); - } - println!("File change detected, restarting"); - FindCloseChangeNotification(handle).ok()?; - Ok(()) - } -} - -fn main() { - unsafe { - CoInitializeEx(None, COINIT_MULTITHREADED).unwrap(); - } - let mute_file: String = env::args().nth(1).unwrap_or("mute.txt".to_string()); - loop { - let mut _mt = MuterThread::new(load_mute_txt(&mute_file)); - await_file_change(&mute_file).unwrap(); - } -} diff --git a/src/pid_to_exe.rs b/crates/auto_mute_lib/src/pid_to_exe.rs similarity index 94% rename from src/pid_to_exe.rs rename to crates/auto_mute_lib/src/pid_to_exe.rs index b5dc398..c30826f 100644 --- a/src/pid_to_exe.rs +++ b/crates/auto_mute_lib/src/pid_to_exe.rs @@ -18,9 +18,9 @@ pub fn pid_to_exe_path(pid: u32) -> Result> { windows::core::PWSTR(exe_name.as_mut_ptr()), &mut size, ) - .ok()?; + .ok(); - CloseHandle(process); + CloseHandle(process)?; exe_name.set_len(size.try_into().unwrap()); } diff --git a/src/session_notification.rs b/crates/auto_mute_lib/src/session_notification.rs similarity index 55% rename from src/session_notification.rs rename to crates/auto_mute_lib/src/session_notification.rs index 473c559..89e3dee 100644 --- a/src/session_notification.rs +++ b/crates/auto_mute_lib/src/session_notification.rs @@ -1,12 +1,11 @@ use windows::{ - core::Interface, + core::{implement, Interface}, Win32::Media::Audio::{ - IAudioSessionControl, IAudioSessionControl2, IAudioSessionNotification, - IAudioSessionNotification_Impl, + IAudioSessionControl, IAudioSessionControl2, IAudioSessionNotification, IAudioSessionNotification_Impl, }, }; -#[windows::core::implement(IAudioSessionNotification)] +#[implement(IAudioSessionNotification)] pub(crate) struct SessionNotification { pub(crate) observer: Box, } @@ -15,11 +14,8 @@ pub trait SessionObserver { fn add_session(&self, session: IAudioSessionControl2); } -impl IAudioSessionNotification_Impl for SessionNotification { - fn OnSessionCreated( - self: &SessionNotification, - newsession: &core::option::Option, - ) -> windows::core::Result<()> { +impl IAudioSessionNotification_Impl for SessionNotification_Impl { + fn OnSessionCreated(&self,newsession:Option<&IAudioSessionControl>) -> windows::core::Result<()> { let ses: IAudioSessionControl2 = newsession.as_ref().unwrap().cast().unwrap(); self.observer.add_session(ses); Ok(()) diff --git a/src/sm_session_notifier.rs b/crates/auto_mute_lib/src/sm_session_notifier.rs similarity index 95% rename from src/sm_session_notifier.rs rename to crates/auto_mute_lib/src/sm_session_notifier.rs index a7ede57..9bf7ee1 100644 --- a/src/sm_session_notifier.rs +++ b/crates/auto_mute_lib/src/sm_session_notifier.rs @@ -14,7 +14,7 @@ use windows::{ Devices::FunctionDiscovery::PKEY_Device_FriendlyName, Media::Audio::{ eRender, IAudioSessionControl2, IAudioSessionManager2, IAudioSessionNotification, - IMMDeviceEnumerator, IMMNotificationClient, MMDeviceEnumerator, DEVICE_STATE_ACTIVE, + IMMDeviceEnumerator, IMMNotificationClient, MMDeviceEnumerator, DEVICE_STATE_ACTIVE, IMMDevice, }, System::Com::{ CoCreateInstance, StructuredStorage::PropVariantClear, CLSCTX_ALL, STGM_READ, @@ -106,15 +106,15 @@ impl SMSessionNotifier { unsafe { let device_enumerator: IMMDeviceEnumerator = CoCreateInstance(&MMDeviceEnumerator, None, CLSCTX_ALL)?; - let device = device_enumerator.GetDevice(id)?; + let device = device_enumerator.GetDevice(*id)?; self.add_device(device)?; Ok(()) - } + } } unsafe fn add_device( self: &mut SMSessionNotifier, - device: windows::Win32::Media::Audio::IMMDevice, + device: IMMDevice, ) -> Result<(), Box> { let session_manager: IAudioSessionManager2 = device.Activate(CLSCTX_ALL, None)?; session_manager.RegisterSessionNotification(&self.session_notification)?; @@ -133,8 +133,8 @@ impl SMSessionNotifier { let prop_store = device.OpenPropertyStore(STGM_READ)?; let mut prop_var = prop_store.GetValue(&PKEY_Device_FriendlyName)?; println!( - "Device Added: {} Existing Sessions: {}", - prop_var.Anonymous.Anonymous.Anonymous.pwszVal.to_string()?, + "Device Added: {} Existing Sessions: {}", + prop_var.to_string(), session_count ); PropVariantClear(&mut prop_var)?; diff --git a/src/window_change.rs b/crates/auto_mute_lib/src/window_change.rs similarity index 96% rename from src/window_change.rs rename to crates/auto_mute_lib/src/window_change.rs index ac9bf15..25d9c93 100644 --- a/src/window_change.rs +++ b/crates/auto_mute_lib/src/window_change.rs @@ -71,11 +71,11 @@ pub fn await_win_change_events(callback: WinCallback) { let mut msg: MSG = MSG::default(); while GetMessageW(&mut msg, HWND::default(), 0, 0).0 > 0 { - TranslateMessage(&msg); + TranslateMessage(&msg).unwrap(); DispatchMessageW(&msg); } - UnhookWinEvent(fg_event); - UnhookWinEvent(min_event); + UnhookWinEvent(fg_event).unwrap(); + UnhookWinEvent(min_event).unwrap(); } } diff --git a/mute.txt b/mute.txt index 2caf36a..c0d69aa 100644 --- a/mute.txt +++ b/mute.txt @@ -14,4 +14,6 @@ sm64.us.f3dex2e.exe teardown.exe underrail.exe valheim.exe -Spotify.exe \ No newline at end of file +Spotify.exe +Balatro.exe +Tactical Breach Wizards.exe \ No newline at end of file diff --git a/res/muted.ico b/res/muted.ico new file mode 100644 index 0000000000000000000000000000000000000000..e86447335b69b89b75bc358d9d5b46873ca22cac GIT binary patch literal 4158 zcmchZJ#yPH5QR5Ai&U9mWsfQsuH*wSg|3h*&pe{3Mlgh^+vTwmh z0!x6V6eaM$Ao0WR?ZbkU$UFVJzZd+MhxZ~MMC3uMcF9Mr=&zUXDiVU$V|~u8N5C>B z+2H>t4I`V(=Yh@pf9OMr4R6C*4XRPnip48Sjm_mn4Jj+^cDu0O@55%Zv8pRM&WBXm zx7b|fG_)_hF*agcun&iW={TKEb`32yCu-q?l6EcImguvN%Cub6YqY9i;3IzWas3oN z2RX=sAFJ6hhMoF}`s6e;FFj&sr3N|0`Oq@=1Ky=^z}sSpOmH=pu~sxN2cW^`>N@nL z8k*+oS~dg)iz8+8`mXK+c;wR$^mX0ujNLR}^j;aUg6GSe|4HYg!jpEcf%!l_^K!fW zk+Hk(R}XD(oR^88a=~V;XyE>X-?rZ~cH4gIxhHI?MGb%-EHPHbOQvs28ixF{Gm_-m z+dE>)bFkqDc-)s%2hIt`H24tC=a?6aBW2>6+_XQ} zka;eR=8C>6m>)|zY~HjFxd$aKG{pJZT2AI{>x*n^SkjU5GaqVRfXy6np6gIA`i>f( zIe1Xg0Z+#MDgG%JwGaEn+_p1-dGG}M5}Ub~YQWrrj;wFapXNd#557@_Y!H z571E4QD;*F+9^M`1vc}tqycL=P91Fd+>}(m4uW$=kI{n1XS4Mh@ZIDX+sn9vq6Ieg z1bfWqUNPS8(kKmzY*ag0IJ*yY$%UF+2qu!5Wn5Xlv oEaU$B^)(-E7Pki$?n@eO6nBAE?wV=%Ie34)=Vj1B@2KJR4=B%5JlIM!bO@)inK7U(&qvxe1%*gSD=K_N6GjUIRJ+srwA3B{gQvYmTd^& z48sg!)+@`h-rp}7k<5Pcx!@`v4D+I>__+&A5n$PYu*T zzTXr0kZL(_KKgue;RzzqKpo_BPrQy)!yZ3ce##|(L<9Gqehlf@;|IUlSRdG)H`J#- z?niU};4j$wbfkVXdjbuy{vjU6cqVvH9gfd4a!3dL09V)R_}y_GuFsruInIpd=(}&^ zuR6j!ycb*7gE4NLA9?6gw;$);Gd}?WRU=BGcpWZNg4mIE%KhFL*n;MYgUZ2XR zE@<$@h|EB<@f)R)n6T3efv_~$x^p6(~ac1k__L{(qd+jTijV> h7NM=|ir83eZG2~8FXR?8dwHp!nd&At!gmra^ap7$7*GHJ literal 0 HcmV?d00001 diff --git a/todo.txt b/todo.txt index 03e23ef..7f0e2f5 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,2 @@ -- Add the ability to reload/restart the mute list - must essentially restart/refresh all sessions if this occurs? - - can we simply release everything in this case? Should work given the way the windows-rs COM wrapper works I think. - Tray icon - Simple GUI to select from open windows and add to the list