diff --git a/src/apps/seelenweg/modules/bar/index.tsx b/src/apps/seelenweg/modules/bar/index.tsx
index c501734d..0d4e1037 100644
--- a/src/apps/seelenweg/modules/bar/index.tsx
+++ b/src/apps/seelenweg/modules/bar/index.tsx
@@ -163,7 +163,7 @@ export function SeelenWeg() {
function ItemByType(item: SwItem) {
if (item.type === SpecialItemType.PinnedApp || item.type === SpecialItemType.TemporalApp) {
- return ;
+ return ;
}
if (item.type === SpecialItemType.Media) {
diff --git a/src/background/hook.rs b/src/background/hook.rs
index 238a18a3..fbb44ce7 100644
--- a/src/background/hook.rs
+++ b/src/background/hook.rs
@@ -25,8 +25,8 @@ use winvd::{listen_desktop_events, DesktopEvent};
use crate::{
error_handler::Result,
log_error,
- seelen::{Seelen, SEELEN},
- seelen_weg::{SeelenWeg, TASKBAR_CLASS},
+ seelen::SEELEN,
+ seelen_weg::SeelenWeg,
state::{application::FULL_STATE, domain::AppExtraFlag},
trace_lock,
utils::{constants::IGNORE_FOCUS, is_windows_11},
@@ -128,8 +128,6 @@ impl HookManager {
}
let mut seelen = trace_lock!(SEELEN);
- log_error!(seelen.process_win_event(event, origin));
-
if seelen.state().is_weg_enabled() {
log_error!(SeelenWeg::process_global_win_event(event, origin));
}
@@ -204,28 +202,6 @@ pub fn process_vd_event(event: DesktopEvent) -> Result<()> {
Ok(())
}
-impl Seelen {
- pub fn process_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> {
- match event {
- WinEvent::ObjectShow | WinEvent::ObjectCreate => {
- // ensure that the taskbar is always hidden
- if self.state().is_weg_enabled() {
- let class = WindowsApi::get_class(origin)?;
- let parent_class =
- WindowsApi::get_class(WindowsApi::get_parent(origin)).unwrap_or_default();
- if TASKBAR_CLASS.contains(&class.as_str())
- || TASKBAR_CLASS.contains(&parent_class.as_str())
- {
- SeelenWeg::hide_taskbar(true);
- }
- }
- }
- _ => {}
- }
- Ok(())
- }
-}
-
lazy_static! {
static ref DICT: Arc>> = Arc::new(Mutex::new(HashMap::new()));
}
@@ -270,6 +246,11 @@ pub extern "system" fn win_event_hook(
return;
}
+ if FULL_STATE.load().is_weg_enabled() {
+ // raw events should be only used for a fastest and immediately processing
+ log_error!(SeelenWeg::process_raw_win_event(event, hwnd));
+ }
+
let event = match WinEvent::try_from(event) {
Ok(event) => event,
Err(_) => return,
diff --git a/src/background/modules/tray/application.rs b/src/background/modules/tray/application.rs
index 398d50bf..77612a43 100644
--- a/src/background/modules/tray/application.rs
+++ b/src/background/modules/tray/application.rs
@@ -79,6 +79,7 @@ pub fn ensure_tray_overflow_creation() -> Result<()> {
let tray_bar_state = tray_bar.state();
// This function will fail if taskbar is hidden
tray_bar.set_state(AppBarDataState::AlwaysOnTop);
+ WindowsApi::show_window(tray_hwnd, SW_SHOW)?;
let automation: IUIAutomation = Com::create_instance(&CUIAutomation)?;
let condition = automation.CreateTrueCondition()?;
@@ -108,6 +109,7 @@ pub fn ensure_tray_overflow_creation() -> Result<()> {
}
pub fn get_tray_icons() -> Result> {
+ ensure_tray_overflow_creation()?;
let tray_from_registry = TrayIcon::enum_from_registry().unwrap_or_default();
Com::run_with_context(|| unsafe {
diff --git a/src/background/seelen.rs b/src/background/seelen.rs
index 8d555c6c..4ead94e4 100644
--- a/src/background/seelen.rs
+++ b/src/background/seelen.rs
@@ -150,7 +150,7 @@ impl Seelen {
declare_system_events_handlers()?;
if self.state().is_weg_enabled() {
- SeelenWeg::hide_taskbar(true);
+ SeelenWeg::hide_taskbar();
}
log::trace!("Enumerating Monitors");
@@ -169,7 +169,7 @@ impl Seelen {
pub fn stop(&self) {
release_system_events_handlers();
if self.state().is_weg_enabled() {
- log_error!(SeelenWeg::hide_taskbar(false).join());
+ log_error!(SeelenWeg::show_taskbar());
}
if self.state().is_ahk_enabled() {
Self::kill_ahk_shortcuts();
diff --git a/src/background/seelen_weg/hook.rs b/src/background/seelen_weg/hook.rs
index 562cf0b7..99a93d0e 100644
--- a/src/background/seelen_weg/hook.rs
+++ b/src/background/seelen_weg/hook.rs
@@ -1,8 +1,11 @@
-use windows::Win32::Foundation::HWND;
+use windows::Win32::{
+ Foundation::HWND,
+ UI::WindowsAndMessaging::{FindWindowExA, EVENT_OBJECT_CREATE, EVENT_OBJECT_SHOW, SW_HIDE},
+};
-use crate::{error_handler::Result, windows_api::WindowsApi, winevent::WinEvent};
+use crate::{error_handler::Result, pcstr, windows_api::WindowsApi, winevent::WinEvent};
-use super::SeelenWeg;
+use super::{SeelenWeg, TASKBAR_CLASS};
impl SeelenWeg {
pub fn process_global_win_event(event: WinEvent, origin: HWND) -> Result<()> {
@@ -72,4 +75,55 @@ impl SeelenWeg {
};
Ok(())
}
+
+ pub fn process_raw_win_event(event: u32, origin_hwnd: HWND) -> Result<()> {
+ match event {
+ EVENT_OBJECT_SHOW | EVENT_OBJECT_CREATE => {
+ let class = WindowsApi::get_class(origin_hwnd)?;
+ let parent_class =
+ WindowsApi::get_class(WindowsApi::get_parent(origin_hwnd)).unwrap_or_default();
+
+ if TASKBAR_CLASS
+ .iter()
+ .any(|t| t == &class || t == &parent_class)
+ {
+ Self::hide_taskbar();
+ return Ok(());
+ }
+
+ if class.eq("XamlExplorerHostIslandWindow")
+ && WindowsApi::get_window_text(origin_hwnd).is_empty()
+ {
+ let content_hwnd = unsafe {
+ FindWindowExA(
+ origin_hwnd,
+ HWND(0),
+ pcstr!("Windows.UI.Composition.DesktopWindowContentBridge"),
+ pcstr!("DesktopWindowXamlSource"),
+ )
+ };
+
+ if content_hwnd.0 != 0 {
+ let input_hwnd = unsafe {
+ FindWindowExA(
+ content_hwnd,
+ HWND(0),
+ pcstr!("Windows.UI.Input.InputSite.WindowClass"),
+ None,
+ )
+ };
+ if input_hwnd.0 != 0 {
+ // can fail on volume window island
+ let _ = WindowsApi::show_window(input_hwnd, SW_HIDE);
+ }
+ // can fail on volume window island
+ let _ = WindowsApi::show_window(content_hwnd, SW_HIDE);
+ }
+ WindowsApi::show_window(origin_hwnd, SW_HIDE)?;
+ }
+ }
+ _ => {}
+ }
+ Ok(())
+ }
}
diff --git a/src/background/seelen_weg/mod.rs b/src/background/seelen_weg/mod.rs
index 5b673067..f056b6c8 100644
--- a/src/background/seelen_weg/mod.rs
+++ b/src/background/seelen_weg/mod.rs
@@ -16,7 +16,7 @@ use windows::Win32::{
Foundation::{BOOL, HWND, LPARAM, RECT},
UI::WindowsAndMessaging::{
EnumWindows, GetParent, HWND_TOPMOST, SWP_NOACTIVATE, SW_HIDE, SW_SHOWNOACTIVATE,
- SW_SHOWNORMAL, WS_EX_APPWINDOW, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW,
+ WS_EX_APPWINDOW, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW,
},
};
@@ -26,6 +26,7 @@ use crate::{
modules::uwp::UWP_MANAGER,
seelen::{get_app_handle, SEELEN},
seelen_bar::FancyToolbar,
+ state::application::FULL_STATE,
trace_lock,
utils::{are_overlaped, sleep_millis},
windows_api::{AppBarData, AppBarDataState, WindowsApi},
@@ -410,29 +411,30 @@ impl SeelenWeg {
Ok((window, hitbox))
}
- pub fn hide_taskbar(hide: bool) -> JoinHandle<()> {
- std::thread::spawn(move || {
- let (state, cmdshow) = if hide {
- (AppBarDataState::AutoHide, SW_HIDE)
- } else {
- (AppBarDataState::AlwaysOnTop, SW_SHOWNORMAL)
- };
-
- match get_taskbars_handles() {
- Ok(handles) => {
+ pub fn hide_taskbar() -> JoinHandle<()> {
+ std::thread::spawn(move || match get_taskbars_handles() {
+ Ok(handles) => {
+ let mut attempts = 0;
+ while attempts < 10 && FULL_STATE.load().is_weg_enabled() {
for handle in &handles {
- AppBarData::from_handle(*handle).set_state(state);
- }
- // wait for taskbar animation before hiding it
- sleep_millis(1200);
- for handle in handles {
- log_error!(WindowsApi::show_window(handle, cmdshow));
+ AppBarData::from_handle(*handle).set_state(AppBarDataState::AutoHide);
+ let _ = WindowsApi::show_window(*handle, SW_HIDE);
}
+ attempts += 1;
+ sleep_millis(50);
}
- Err(err) => log::error!("Failed to get taskbars handles: {:?}", err),
}
+ Err(err) => log::error!("Failed to get taskbars handles: {:?}", err),
})
}
+
+ pub fn show_taskbar() -> Result<()> {
+ for hwnd in get_taskbars_handles()? {
+ AppBarData::from_handle(hwnd).set_state(AppBarDataState::AlwaysOnTop);
+ WindowsApi::show_window(hwnd, SW_SHOWNOACTIVATE)?;
+ }
+ Ok(())
+ }
}
lazy_static! {
diff --git a/src/background/windows_api/app_bar.rs b/src/background/windows_api/app_bar.rs
index 0fbc24c9..86039736 100644
--- a/src/background/windows_api/app_bar.rs
+++ b/src/background/windows_api/app_bar.rs
@@ -23,9 +23,10 @@ pub enum AppBarDataEdge {
/// https://learn.microsoft.com/en-us/windows/win32/shell/abm-setstate#parameters
#[derive(Debug, Clone, Copy)]
pub enum AppBarDataState {
- Both = 0,
+ BothOff = 0,
AutoHide = ABS_AUTOHIDE as isize,
AlwaysOnTop = ABS_ALWAYSONTOP as isize,
+ BothOn = 3,
}
impl From for LPARAM {
@@ -37,9 +38,10 @@ impl From for LPARAM {
impl From for AppBarDataState {
fn from(state: u32) -> Self {
match state {
- 0 => AppBarDataState::Both,
+ 0 => AppBarDataState::BothOff,
ABS_AUTOHIDE => AppBarDataState::AutoHide,
ABS_ALWAYSONTOP => AppBarDataState::AlwaysOnTop,
+ 3 => AppBarDataState::BothOn,
_ => unreachable!(),
}
}
diff --git a/src/background/windows_api/mod.rs b/src/background/windows_api/mod.rs
index 46718fe9..7c60da16 100644
--- a/src/background/windows_api/mod.rs
+++ b/src/background/windows_api/mod.rs
@@ -56,13 +56,13 @@ use windows::{
},
WindowsAndMessaging::{
EnumWindows, GetClassNameW, GetDesktopWindow, GetForegroundWindow, GetParent,
- GetWindowLongW, GetWindowRect, GetWindowTextW, GetWindowThreadProcessId, IsIconic,
- IsWindow, IsWindowVisible, IsZoomed, SetWindowPos, ShowWindow, ShowWindowAsync,
- SystemParametersInfoW, ANIMATIONINFO, EVENT_SYSTEM_FOREGROUND, GWL_EXSTYLE,
- GWL_STYLE, SET_WINDOW_POS_FLAGS, SHOW_WINDOW_CMD, SPIF_SENDCHANGE,
- SPIF_UPDATEINIFILE, SPI_GETANIMATION, SPI_GETDESKWALLPAPER, SPI_SETANIMATION,
- SPI_SETDESKWALLPAPER, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE,
- SWP_NOZORDER, SW_MINIMIZE, SW_NORMAL, SW_RESTORE,
+ GetWindow, GetWindowLongW, GetWindowRect, GetWindowTextW, GetWindowThreadProcessId,
+ IsIconic, IsWindow, IsWindowVisible, IsZoomed, SetWindowPos, ShowWindow,
+ ShowWindowAsync, SystemParametersInfoW, ANIMATIONINFO, EVENT_SYSTEM_FOREGROUND,
+ GWL_EXSTYLE, GWL_STYLE, GW_OWNER, SET_WINDOW_POS_FLAGS, SHOW_WINDOW_CMD,
+ SPIF_SENDCHANGE, SPIF_UPDATEINIFILE, SPI_GETANIMATION, SPI_GETDESKWALLPAPER,
+ SPI_SETANIMATION, SPI_SETDESKWALLPAPER, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE,
+ SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, SW_MINIMIZE, SW_NORMAL, SW_RESTORE,
SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, WINDOW_EX_STYLE, WINDOW_STYLE, WNDENUMPROC,
},
},
@@ -348,6 +348,10 @@ impl WindowsApi {
unsafe { GetParent(hwnd) }
}
+ pub fn get_owner(hwnd: HWND) -> HWND {
+ unsafe { GetWindow(hwnd, GW_OWNER) }
+ }
+
pub fn exe_path_by_process(process_id: u32) -> Result {
let mut len = 512_u32;
let mut path: Vec = vec![0; len as usize];