|
|
|
@ -1,9 +1,7 @@
|
|
|
|
|
use windows::Win32::Graphics::Gdi::ClientToScreen;
|
|
|
|
|
use windows::Win32::System::Com::VT_I4;
|
|
|
|
|
use windows::Win32::System::Ole::{VariantClear, VariantInit};
|
|
|
|
|
use windows::Win32::UI::Accessibility::{
|
|
|
|
|
AccessibleObjectFromEvent, IAccessible,
|
|
|
|
|
};
|
|
|
|
|
use windows::Win32::UI::Accessibility::{AccessibleObjectFromEvent, IAccessible};
|
|
|
|
|
|
|
|
|
|
use std::sync::atomic::AtomicPtr;
|
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
@ -14,9 +12,10 @@ use windows::Win32::Foundation::{
|
|
|
|
|
use windows::Win32::UI::WindowsAndMessaging::{
|
|
|
|
|
DispatchMessageW, GetClientRect, GetForegroundWindow, GetMessageW, GetWindowTextW,
|
|
|
|
|
GetWindowThreadProcessId, IsHungAppWindow, PostMessageW, RegisterWindowMessageW,
|
|
|
|
|
TranslateMessage, CHILDID_SELF, EVENT_OBJECT_DESTROY, EVENT_OBJECT_LOCATIONCHANGE,
|
|
|
|
|
EVENT_OBJECT_NAMECHANGE, EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_MINIMIZEEND, MSG,
|
|
|
|
|
OBJECT_IDENTIFIER, OBJID_WINDOW, STATE_SYSTEM_FOCUSED, WINEVENT_OUTOFCONTEXT, SetTimer,
|
|
|
|
|
SetForegroundWindow, SetTimer, TranslateMessage, CHILDID_SELF, EVENT_OBJECT_DESTROY,
|
|
|
|
|
EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_NAMECHANGE, EVENT_SYSTEM_FOREGROUND,
|
|
|
|
|
EVENT_SYSTEM_MINIMIZEEND, MSG, OBJECT_IDENTIFIER, OBJID_WINDOW, STATE_SYSTEM_FOCUSED,
|
|
|
|
|
WINEVENT_OUTOFCONTEXT,
|
|
|
|
|
};
|
|
|
|
|
use windows::Win32::{
|
|
|
|
|
Foundation::HWND,
|
|
|
|
@ -25,9 +24,21 @@ use windows::Win32::{
|
|
|
|
|
|
|
|
|
|
use crate::{Bounds, UnderlayEvent};
|
|
|
|
|
|
|
|
|
|
static GLOBAL_CALLBACK_SENDER: AtomicPtr<Arc<Mutex<Runtime>>> =
|
|
|
|
|
static GLOBAL_RUNTIME: AtomicPtr<Arc<Mutex<Runtime>>> =
|
|
|
|
|
AtomicPtr::new(std::ptr::null_mut());
|
|
|
|
|
|
|
|
|
|
pub fn focus_target() {
|
|
|
|
|
unsafe {
|
|
|
|
|
if let Ok(runtime) =
|
|
|
|
|
(*GLOBAL_RUNTIME.load(std::sync::atomic::Ordering::Relaxed)).lock()
|
|
|
|
|
{
|
|
|
|
|
if runtime.target.hwnd.is_valid() {
|
|
|
|
|
SetForegroundWindow(runtime.target.hwnd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn constant_name(value: u32) -> String {
|
|
|
|
|
match value {
|
|
|
|
|
EVENT_OBJECT_DESTROY => "EVENT_OBJECT_DESTROY".into(),
|
|
|
|
@ -171,7 +182,7 @@ unsafe extern "system" fn global_hook(
|
|
|
|
|
_dwmseventtime: u32,
|
|
|
|
|
) {
|
|
|
|
|
if let Ok(mut runtime) =
|
|
|
|
|
(*GLOBAL_CALLBACK_SENDER.load(std::sync::atomic::Ordering::Relaxed)).lock()
|
|
|
|
|
(*GLOBAL_RUNTIME.load(std::sync::atomic::Ordering::Relaxed)).lock()
|
|
|
|
|
{
|
|
|
|
|
runtime.on_event(Event::from_data(
|
|
|
|
|
event,
|
|
|
|
@ -189,7 +200,7 @@ unsafe extern "system" fn global_timer_hook(
|
|
|
|
|
_dwms_event_time: u32,
|
|
|
|
|
) {
|
|
|
|
|
if let Ok(mut runtime) =
|
|
|
|
|
(*GLOBAL_CALLBACK_SENDER.load(std::sync::atomic::Ordering::Relaxed)).lock()
|
|
|
|
|
(*GLOBAL_RUNTIME.load(std::sync::atomic::Ordering::Relaxed)).lock()
|
|
|
|
|
{
|
|
|
|
|
let system_foreground_window = GetForegroundWindow();
|
|
|
|
|
if runtime.foreground_window != system_foreground_window
|
|
|
|
@ -373,7 +384,11 @@ impl Runtime {
|
|
|
|
|
|
|
|
|
|
if let Some(bounds) = self.get_content_bounds() {
|
|
|
|
|
self.underlay_tx
|
|
|
|
|
.send(UnderlayEvent::Attach { bounds, has_access: Some(has_access), is_fullscreen: None })
|
|
|
|
|
.send(UnderlayEvent::Attach {
|
|
|
|
|
bounds,
|
|
|
|
|
has_access: Some(has_access),
|
|
|
|
|
is_fullscreen: None,
|
|
|
|
|
})
|
|
|
|
|
.ok();
|
|
|
|
|
|
|
|
|
|
self.target.is_focused = true;
|
|
|
|
@ -381,7 +396,6 @@ impl Runtime {
|
|
|
|
|
} else {
|
|
|
|
|
self.target.hwnd = Default::default();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn msaa_check_window_focused_state(&mut self, hwnd: HWND) -> bool {
|
|
|
|
@ -497,9 +511,16 @@ pub fn init(
|
|
|
|
|
};
|
|
|
|
|
runtime.foreground_change.bind();
|
|
|
|
|
runtime.unminimize_change.bind();
|
|
|
|
|
unsafe { SetTimer(HWND::default(), 0, OW_FOREGROUND_TIMER_MS, Some(global_timer_hook)) };
|
|
|
|
|
unsafe {
|
|
|
|
|
SetTimer(
|
|
|
|
|
HWND::default(),
|
|
|
|
|
0,
|
|
|
|
|
OW_FOREGROUND_TIMER_MS,
|
|
|
|
|
Some(global_timer_hook),
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GLOBAL_CALLBACK_SENDER.store(
|
|
|
|
|
GLOBAL_RUNTIME.store(
|
|
|
|
|
Box::into_raw(Box::new(Arc::new(Mutex::new(runtime)))),
|
|
|
|
|
std::sync::atomic::Ordering::Relaxed,
|
|
|
|
|
);
|
|
|
|
|