From a2f9fbeb2a945b5cacbfe32ec8d12751bffcddec Mon Sep 17 00:00:00 2001 From: eythaann Date: Fri, 16 Aug 2024 04:32:57 -0500 Subject: [PATCH] fix(taskbar): no hidding taskbar and xamlisland --- src/apps/seelenweg/modules/bar/index.tsx | 2 +- src/background/hook.rs | 33 +++--------- src/background/modules/tray/application.rs | 2 + src/background/seelen.rs | 4 +- src/background/seelen_weg/hook.rs | 60 ++++++++++++++++++++-- src/background/seelen_weg/mod.rs | 38 +++++++------- src/background/windows_api/app_bar.rs | 6 ++- src/background/windows_api/mod.rs | 18 ++++--- 8 files changed, 104 insertions(+), 59 deletions(-) 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];