Skip to content

Commit 3a5aaf6

Browse files
committed
fix: conflicting classname issue
1 parent eb6852c commit 3a5aaf6

File tree

4 files changed

+66
-38
lines changed

4 files changed

+66
-38
lines changed

src/app_state.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,28 @@ pub struct AppState {
1717
config: Arc<RwLock<Config>>,
1818
config_path: PathBuf,
1919
enabled: Arc<RwLock<bool>>,
20+
pub shutdown: Arc<tokio::sync::Notify>,
2021
}
2122

2223
impl AppState {
2324
pub fn new(config: Config, config_path: PathBuf) -> Self {
24-
let (tx, _) = broadcast::channel(16);
25-
let (txe, _) = broadcast::channel(16);
25+
let (tx, _) = broadcast::channel(2);
26+
let (txe, _) = broadcast::channel(2);
27+
2628
Self {
2729
config_tx: tx,
2830
enabled_tx: txe,
2931
config: Arc::new(RwLock::new(config)),
3032
config_path,
3133
enabled: Arc::new(RwLock::new(true)),
34+
shutdown: Arc::new(tokio::sync::Notify::new()),
3235
}
3336
}
3437

38+
pub async fn quit(&self) {
39+
self.shutdown.notify_waiters();
40+
}
41+
3542
pub fn spawn_update_config(&self, value: WindowConfig) {
3643
let app_state = Arc::new(self.clone());
3744

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async fn main() -> Result<()> {
4040
if let Some(event) = rx.recv().await {
4141
match event {
4242
Message::Quit => {
43+
app_state.quit().await;
4344
return Ok(());
4445
}
4546
Message::Rules => {

src/monitor.rs

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::{app_state::AppState, util::Config, win_utils::make_window_transparent};
22

33
use core::time::Duration;
4-
use std::{os::raw::c_void, sync::Arc, thread::sleep, time::Instant};
4+
use std::{os::raw::c_void, sync::Arc};
55

6-
use rustc_hash::FxHashMap;
6+
use std::collections::HashMap;
77
use windows::Win32::{Foundation::HWND, UI::WindowsAndMessaging::IsWindow};
8-
98
#[derive(Eq, PartialEq, Clone, Debug)]
109
struct WindowHandleState {
1110
handle: isize,
@@ -49,47 +48,40 @@ impl WindowHandleState {
4948
*/
5049
#[inline(always)]
5150
pub async fn monitor_windows(app_state: Arc<AppState>) {
52-
let mut window_cache = FxHashMap::with_capacity_and_hasher(8, Default::default());
53-
54-
let refresh_interval = Duration::from_secs(1);
55-
let sleep_duration = Duration::from_millis(250);
56-
57-
let mut last_refresh = Instant::now();
58-
let mut last_state = app_state.is_enabled().await;
51+
let mut window_cache = HashMap::with_capacity(8);
52+
let refresh_interval = Duration::from_millis(120);
5953
let mut config = app_state.get_config().await;
6054
let mut is_enabled = app_state.is_enabled().await;
61-
6255
let mut config_rx = app_state.subscribe_config_updates();
6356
let mut enabled_rx = app_state.subscribe_enabled_updates();
6457

6558
loop {
66-
if let Ok(new_config) = config_rx.try_recv() {
67-
config = new_config;
68-
}
69-
70-
if let Ok(state) = enabled_rx.try_recv() {
71-
is_enabled = state;
72-
}
73-
74-
if is_enabled {
75-
let now = Instant::now();
76-
if now.duration_since(last_refresh) > refresh_interval {
77-
refresh_window_cache(&config, &mut window_cache);
78-
last_refresh = now;
59+
tokio::select! {
60+
_ = app_state.shutdown.notified() => {
61+
break;
7962
}
80-
81-
update_windows(&config, &mut window_cache);
82-
} else if last_state != is_enabled {
83-
reset_windows(&mut window_cache);
63+
Ok(new_config) = config_rx.recv() => {
64+
config = new_config;
65+
}
66+
Ok(state) = enabled_rx.recv() => {
67+
if state != is_enabled && is_enabled {
68+
reset_windows(&mut window_cache);
69+
}
70+
is_enabled = state;
71+
}
72+
_ = tokio::time::sleep(refresh_interval) => {
73+
if is_enabled {
74+
refresh_window_cache(&config, &mut window_cache);
75+
update_windows(&config, &mut window_cache);
76+
}
77+
}
78+
else => break
8479
}
85-
86-
last_state = is_enabled;
87-
sleep(sleep_duration);
8880
}
8981
}
9082

9183
#[inline(always)]
92-
fn refresh_window_cache(config: &Config, cache: &mut FxHashMap<String, Vec<WindowHandleState>>) {
84+
fn refresh_window_cache(config: &Config, cache: &mut HashMap<String, Vec<WindowHandleState>>) {
9385
for cfg in config.get_windows_non_mut().values() {
9486
let handles = cfg.get_window_hwnds();
9587
if handles.is_empty() {
@@ -115,7 +107,7 @@ fn refresh_window_cache(config: &Config, cache: &mut FxHashMap<String, Vec<Windo
115107
}
116108

117109
#[inline(always)]
118-
fn update_windows(config: &Config, window_cache: &mut FxHashMap<String, Vec<WindowHandleState>>) {
110+
fn update_windows(config: &Config, window_cache: &mut HashMap<String, Vec<WindowHandleState>>) {
119111
for window_config in config.get_windows_non_mut().values() {
120112
if let Some(handle_states) = window_cache.get_mut(&window_config.get_cache_key()) {
121113
let mut new_transparency = window_config.get_transparency();
@@ -138,7 +130,7 @@ fn update_windows(config: &Config, window_cache: &mut FxHashMap<String, Vec<Wind
138130
}
139131

140132
#[inline(always)]
141-
fn reset_windows(window_cache: &mut FxHashMap<String, Vec<WindowHandleState>>) {
133+
fn reset_windows(window_cache: &mut HashMap<String, Vec<WindowHandleState>>) {
142134
window_cache
143135
.values_mut()
144136
.flat_map(|handles| handles.iter_mut())

src/window_config.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
use std::path::Path;
2+
13
use serde::{Deserialize, Serialize};
24

35
use windows::core::PCWSTR;
46

7+
use windows::Win32::Foundation::CloseHandle;
8+
use windows::Win32::System::ProcessStatus::GetProcessImageFileNameA;
9+
use windows::Win32::System::Threading::{OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION};
10+
use windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId;
511
use windows::Win32::{
612
Foundation::{BOOL, HWND, LPARAM, MAX_PATH},
713
UI::WindowsAndMessaging::{
@@ -150,8 +156,30 @@ impl WindowConfig {
150156
unsafe {
151157
if let Ok(mut hwnd) = FindWindowW(class_ptr, None) {
152158
while !hwnd.is_invalid() {
153-
handles.push(std::mem::transmute(hwnd));
154-
159+
let mut process_id = 0;
160+
GetWindowThreadProcessId(hwnd, Some(&mut process_id));
161+
162+
if let Ok(process_handle) =
163+
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_id)
164+
{
165+
let mut buffer = [0u8; 260];
166+
let len = GetProcessImageFileNameA(process_handle, &mut buffer);
167+
let _ = CloseHandle(process_handle);
168+
169+
if len > 0 {
170+
let path_str =
171+
String::from_utf8_lossy(&buffer[..len as usize]).to_string();
172+
if let Some(name) = Path::new(&path_str)
173+
.file_name()
174+
.and_then(|n| n.to_str())
175+
.map(|s| s.split('.').next().unwrap_or(s))
176+
{
177+
if name == self.process_name {
178+
handles.push(std::mem::transmute(hwnd));
179+
}
180+
}
181+
}
182+
}
155183
hwnd = match FindWindowExW(None, Some(hwnd), class_ptr, None) {
156184
Ok(next_hwnd) if !next_hwnd.is_invalid() => next_hwnd,
157185
_ => break,

0 commit comments

Comments
 (0)