simplify: only IsWindowVisible + non-empty title, no complex filters

This commit is contained in:
Helios 2026-03-06 02:33:18 +01:00
parent 15e177087b
commit bc8ffa191d
No known key found for this signature in database
GPG key ID: C8259547CD8309B5

View file

@ -8,9 +8,9 @@ mod win_impl {
use super::*;
use windows::Win32::Foundation::{BOOL, HWND, LPARAM};
use windows::Win32::UI::WindowsAndMessaging::{
BringWindowToTop, EnumWindows, GetAncestor, GetWindowLongA, GetWindowTextW,
IsIconic, IsWindowVisible, SetForegroundWindow, ShowWindow, GA_ROOT,
GWL_EXSTYLE, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, WS_EX_TOOLWINDOW,
BringWindowToTop, EnumWindows, GetWindowTextW,
IsWindowVisible, SetForegroundWindow, ShowWindow,
SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE,
};
use windows::Win32::UI::Input::KeyboardAndMouse::{
keybd_event, KEYEVENTF_KEYUP, VK_MENU,
@ -21,8 +21,6 @@ mod win_impl {
};
use windows::Win32::System::ProcessStatus::GetModuleBaseNameW;
// No broad blocklists — only explorer's "Program Manager" is filtered.
unsafe extern "system" fn enum_callback(hwnd: HWND, lparam: LPARAM) -> BOOL {
let list = &mut *(lparam.0 as *mut Vec<HWND>);
list.push(hwnd);
@ -90,29 +88,11 @@ mod win_impl {
.to_string()
}
/// Filter out ghost/invisible windows. Works even without a process name.
fn is_ghost_window(title: &str, process_name: &str) -> bool {
let t = title.trim();
if t.is_empty() {
return true;
}
if t.eq_ignore_ascii_case("program manager") {
return true;
}
// Block explorer when title is empty or "Program Manager"
if !process_name.is_empty() && process_name.to_lowercase() == "explorer" {
if t.is_empty() || t.eq_ignore_ascii_case("program manager") {
return true;
}
}
false
}
pub fn list_windows() -> Result<Vec<WindowInfo>, String> {
let hwnds = get_all_hwnds();
// First pass: collect valid windows with their process names
let mut raw_windows: Vec<(HWND, String, String)> = Vec::new(); // (hwnd, title, process_name)
// Collect visible windows with non-empty titles
let mut raw_windows: Vec<(HWND, String, String)> = Vec::new();
for hwnd in &hwnds {
let visible = unsafe { IsWindowVisible(*hwnd).as_bool() };
if !visible {
@ -122,42 +102,11 @@ mod win_impl {
if title.is_empty() {
continue;
}
// Skip minimized windows
let iconic = unsafe { IsIconic(*hwnd).as_bool() };
if iconic {
continue;
}
// Skip tool windows
let ex_style = unsafe { GetWindowLongA(*hwnd, GWL_EXSTYLE) } as u32;
if ex_style & WS_EX_TOOLWINDOW.0 != 0 {
continue;
}
// Only keep top-level windows
let root = unsafe { GetAncestor(*hwnd, GA_ROOT) };
if root != *hwnd {
continue;
}
let process_name = hwnd_process_name(*hwnd).unwrap_or_default();
if is_ghost_window(&title, &process_name) {
continue;
}
raw_windows.push((*hwnd, title, process_name));
}
// Second pass: generate labels from process names with dedup numbering
let mut label_counts: HashMap<String, usize> = HashMap::new();
// First count how many of each label base we have
for (_, title, proc_name) in &raw_windows {
let base = if proc_name.is_empty() {
sanitize_label(title)
} else {
sanitize_label(proc_name)
};
if !base.is_empty() {
*label_counts.entry(base).or_insert(0) += 1;
}
}
// Generate labels with dedup numbering
let mut label_index: HashMap<String, usize> = HashMap::new();
let mut windows = Vec::new();
for (hwnd, title, proc_name) in raw_windows {