Skip to content

Commit

Permalink
fix(taskbar): no hidding taskbar and xamlisland
Browse files Browse the repository at this point in the history
  • Loading branch information
eythaann committed Aug 16, 2024
1 parent 844059f commit a2f9fbe
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/apps/seelenweg/modules/bar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export function SeelenWeg() {

function ItemByType(item: SwItem) {
if (item.type === SpecialItemType.PinnedApp || item.type === SpecialItemType.TemporalApp) {
return <UserApplication key={item.exe} item={item} />;
return <UserApplication key={item.exe || item.opens[0] || item.title} item={item} />;
}

if (item.type === SpecialItemType.Media) {
Expand Down
33 changes: 7 additions & 26 deletions src/background/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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<Mutex<HashMap<isize, Instant>>> = Arc::new(Mutex::new(HashMap::new()));
}
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/background/modules/tray/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;
Expand Down Expand Up @@ -108,6 +109,7 @@ pub fn ensure_tray_overflow_creation() -> Result<()> {
}

pub fn get_tray_icons() -> Result<Vec<TrayIcon>> {
ensure_tray_overflow_creation()?;
let tray_from_registry = TrayIcon::enum_from_registry().unwrap_or_default();

Com::run_with_context(|| unsafe {
Expand Down
4 changes: 2 additions & 2 deletions src/background/seelen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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();
Expand Down
60 changes: 57 additions & 3 deletions src/background/seelen_weg/hook.rs
Original file line number Diff line number Diff line change
@@ -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<()> {
Expand Down Expand Up @@ -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(())
}
}
38 changes: 20 additions & 18 deletions src/background/seelen_weg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
};

Expand All @@ -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},
Expand Down Expand Up @@ -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! {
Expand Down
6 changes: 4 additions & 2 deletions src/background/windows_api/app_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AppBarDataState> for LPARAM {
Expand All @@ -37,9 +38,10 @@ impl From<AppBarDataState> for LPARAM {
impl From<u32> 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!(),
}
}
Expand Down
18 changes: 11 additions & 7 deletions src/background/windows_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
},
Expand Down Expand Up @@ -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<String> {
let mut len = 512_u32;
let mut path: Vec<u16> = vec![0; len as usize];
Expand Down

0 comments on commit a2f9fbe

Please sign in to comment.