Compare commits
1 Commits
master
...
ignore-old
Author | SHA1 | Date |
---|---|---|
LGUG2Z | cf7108de94 |
|
@ -794,6 +794,7 @@ dependencies = [
|
|||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
@ -2304,6 +2305,7 @@ name = "komorebi"
|
|||
version = "0.1.27-dev.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"chrono",
|
||||
"clap",
|
||||
"color-eyre",
|
||||
"crossbeam-channel",
|
||||
|
@ -3734,6 +3736,7 @@ version = "0.8.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dyn-clone",
|
||||
"schemars_derive",
|
||||
"serde",
|
||||
|
|
|
@ -40,5 +40,7 @@ features = [
|
|||
"Win32_UI_Shell",
|
||||
"Win32_UI_Shell_Common",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
"Win32_System_SystemServices"
|
||||
"Win32_System",
|
||||
"Win32_System_SystemServices",
|
||||
"Win32_System_SystemInformation"
|
||||
]
|
||||
|
|
|
@ -19,6 +19,7 @@ color-eyre = { workspace = true }
|
|||
crossbeam-channel = "0.5"
|
||||
crossbeam-utils = "0.8"
|
||||
ctrlc = { version = "3", features = ["termination"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
dirs = { workspace = true }
|
||||
getset = "0.1"
|
||||
hex_color = { version = "3", features = ["serde"] }
|
||||
|
@ -31,7 +32,7 @@ os_info = "3.8"
|
|||
parking_lot = "0.12"
|
||||
paste = "1"
|
||||
regex = "1"
|
||||
schemars = "0.8"
|
||||
schemars = { version = "0.8", features = ["chrono"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
use std::fs::OpenOptions;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
@ -70,6 +72,13 @@ impl WindowManager {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let now: DateTime<Utc> = Utc::now();
|
||||
let difference = now - event.timestamp();
|
||||
if difference > chrono::Duration::seconds(2) {
|
||||
tracing::warn!("ignoring event more than two seconds old: {}", event);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut rule_debug = RuleDebug::default();
|
||||
|
||||
let should_manage = event.window().should_manage(Some(event), &mut rule_debug)?;
|
||||
|
@ -119,9 +128,9 @@ impl WindowManager {
|
|||
|
||||
// Make sure we have the most recently focused monitor from any event
|
||||
match event {
|
||||
WindowManagerEvent::FocusChange(_, window)
|
||||
| WindowManagerEvent::Show(_, window)
|
||||
| WindowManagerEvent::MoveResizeEnd(_, window) => {
|
||||
WindowManagerEvent::FocusChange(_, window, _)
|
||||
| WindowManagerEvent::Show(_, window, _)
|
||||
| WindowManagerEvent::MoveResizeEnd(_, window, _) => {
|
||||
if let Some(monitor_idx) = self.monitor_idx_from_window(window) {
|
||||
// This is a hidden window apparently associated with COM support mechanisms (based
|
||||
// on a post from http://www.databaseteam.org/1-ms-sql-server/a5bb344836fb889c.htm)
|
||||
|
@ -151,7 +160,7 @@ impl WindowManager {
|
|||
|
||||
for monitor in self.monitors_mut() {
|
||||
for workspace in monitor.workspaces_mut() {
|
||||
if let WindowManagerEvent::FocusChange(_, window) = event {
|
||||
if let WindowManagerEvent::FocusChange(_, window, _) = event {
|
||||
let _ = workspace.focus_changed(window.hwnd);
|
||||
}
|
||||
}
|
||||
|
@ -167,11 +176,11 @@ impl WindowManager {
|
|||
}
|
||||
|
||||
match event {
|
||||
WindowManagerEvent::Raise(window) => {
|
||||
WindowManagerEvent::Raise(window, _) => {
|
||||
window.focus(false)?;
|
||||
self.has_pending_raise_op = false;
|
||||
}
|
||||
WindowManagerEvent::Destroy(_, window) | WindowManagerEvent::Unmanage(window) => {
|
||||
WindowManagerEvent::Destroy(_, window, _) | WindowManagerEvent::Unmanage(window, _) => {
|
||||
if self.focused_workspace()?.contains_window(window.hwnd) {
|
||||
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
|
||||
self.update_focused_workspace(false, false)?;
|
||||
|
@ -181,7 +190,7 @@ impl WindowManager {
|
|||
already_moved_window_handles.remove(&window.hwnd);
|
||||
}
|
||||
}
|
||||
WindowManagerEvent::Minimize(_, window) => {
|
||||
WindowManagerEvent::Minimize(_, window, _) => {
|
||||
let mut hide = false;
|
||||
|
||||
{
|
||||
|
@ -196,7 +205,7 @@ impl WindowManager {
|
|||
self.update_focused_workspace(false, false)?;
|
||||
}
|
||||
}
|
||||
WindowManagerEvent::Hide(_, window) => {
|
||||
WindowManagerEvent::Hide(_, window, _) => {
|
||||
let mut hide = false;
|
||||
// Some major applications unfortunately send the HIDE signal when they are being
|
||||
// minimized or destroyed. Applications that close to the tray also do the same,
|
||||
|
@ -242,7 +251,7 @@ impl WindowManager {
|
|||
|
||||
already_moved_window_handles.remove(&window.hwnd);
|
||||
}
|
||||
WindowManagerEvent::FocusChange(_, window) => {
|
||||
WindowManagerEvent::FocusChange(_, window, _) => {
|
||||
self.update_focused_workspace(self.mouse_follows_focus, false)?;
|
||||
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
|
@ -267,9 +276,9 @@ impl WindowManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
WindowManagerEvent::Show(_, window)
|
||||
| WindowManagerEvent::Manage(window)
|
||||
| WindowManagerEvent::Uncloak(_, window) => {
|
||||
WindowManagerEvent::Show(_, window, _)
|
||||
| WindowManagerEvent::Manage(window, _)
|
||||
| WindowManagerEvent::Uncloak(_, window, _) => {
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
let focused_workspace_idx =
|
||||
self.focused_workspace_idx_for_monitor_idx(focused_monitor_idx)?;
|
||||
|
@ -366,7 +375,7 @@ impl WindowManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
WindowManagerEvent::MoveResizeStart(_, window) => {
|
||||
WindowManagerEvent::MoveResizeStart(_, window, _) => {
|
||||
if *self.focused_workspace()?.tile() {
|
||||
let monitor_idx = self.focused_monitor_idx();
|
||||
let workspace_idx = self
|
||||
|
@ -386,7 +395,7 @@ impl WindowManager {
|
|||
Option::from((monitor_idx, workspace_idx, container_idx));
|
||||
}
|
||||
}
|
||||
WindowManagerEvent::MoveResizeEnd(_, window) => {
|
||||
WindowManagerEvent::MoveResizeEnd(_, window, _) => {
|
||||
// We need this because if the event ends on a different monitor,
|
||||
// that monitor will already have been focused and updated in the state
|
||||
let pending = self.pending_move_op;
|
||||
|
@ -599,7 +608,7 @@ impl WindowManager {
|
|||
};
|
||||
|
||||
// If we unmanaged a window, it shouldn't be immediately hidden behind managed windows
|
||||
if let WindowManagerEvent::Unmanage(window) = event {
|
||||
if let WindowManagerEvent::Unmanage(window, _) = event {
|
||||
window.center(&self.focused_monitor_work_area()?)?;
|
||||
}
|
||||
|
||||
|
@ -637,7 +646,7 @@ impl WindowManager {
|
|||
// Too many spammy OBJECT_NAMECHANGE events from JetBrains IDEs
|
||||
if !matches!(
|
||||
event,
|
||||
WindowManagerEvent::Show(WinEvent::ObjectNameChange, _)
|
||||
WindowManagerEvent::Show(WinEvent::ObjectNameChange, _, _)
|
||||
) {
|
||||
tracing::info!("processed: {}", event.window().to_string());
|
||||
} else {
|
||||
|
|
|
@ -367,7 +367,7 @@ impl Window {
|
|||
if let Some(event) = event {
|
||||
if matches!(
|
||||
event,
|
||||
WindowManagerEvent::Hide(_, _) | WindowManagerEvent::Cloak(_, _)
|
||||
WindowManagerEvent::Hide(_, _, _) | WindowManagerEvent::Cloak(_, _, _)
|
||||
) {
|
||||
allow_cloaked = true;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use chrono::Utc;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
|
@ -598,14 +599,14 @@ impl WindowManager {
|
|||
#[tracing::instrument(skip(self))]
|
||||
pub fn manage_focused_window(&mut self) -> Result<()> {
|
||||
let hwnd = WindowsApi::foreground_window()?;
|
||||
let event = WindowManagerEvent::Manage(Window::from(hwnd));
|
||||
let event = WindowManagerEvent::Manage(Window::from(hwnd), Utc::now());
|
||||
Ok(winevent_listener::event_tx().send(event)?)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn unmanage_focused_window(&mut self) -> Result<()> {
|
||||
let hwnd = WindowsApi::foreground_window()?;
|
||||
let event = WindowManagerEvent::Unmanage(Window::from(hwnd));
|
||||
let event = WindowManagerEvent::Unmanage(Window::from(hwnd), Utc::now());
|
||||
Ok(winevent_listener::event_tx().send(event)?)
|
||||
}
|
||||
|
||||
|
@ -662,7 +663,7 @@ impl WindowManager {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let event = WindowManagerEvent::Raise(Window::from(hwnd));
|
||||
let event = WindowManagerEvent::Raise(Window::from(hwnd), Utc::now());
|
||||
self.has_pending_raise_op = true;
|
||||
winevent_listener::event_tx().send(event)?;
|
||||
} else {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
use std::fmt::Display;
|
||||
use std::fmt::Formatter;
|
||||
|
||||
|
@ -14,68 +16,68 @@ use crate::REGEX_IDENTIFIERS;
|
|||
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum WindowManagerEvent {
|
||||
Destroy(WinEvent, Window),
|
||||
FocusChange(WinEvent, Window),
|
||||
Hide(WinEvent, Window),
|
||||
Cloak(WinEvent, Window),
|
||||
Minimize(WinEvent, Window),
|
||||
Show(WinEvent, Window),
|
||||
Uncloak(WinEvent, Window),
|
||||
MoveResizeStart(WinEvent, Window),
|
||||
MoveResizeEnd(WinEvent, Window),
|
||||
MouseCapture(WinEvent, Window),
|
||||
Manage(Window),
|
||||
Unmanage(Window),
|
||||
Raise(Window),
|
||||
TitleUpdate(WinEvent, Window),
|
||||
Destroy(WinEvent, Window, DateTime<Utc>),
|
||||
FocusChange(WinEvent, Window, DateTime<Utc>),
|
||||
Hide(WinEvent, Window, DateTime<Utc>),
|
||||
Cloak(WinEvent, Window, DateTime<Utc>),
|
||||
Minimize(WinEvent, Window, DateTime<Utc>),
|
||||
Show(WinEvent, Window, DateTime<Utc>),
|
||||
Uncloak(WinEvent, Window, DateTime<Utc>),
|
||||
MoveResizeStart(WinEvent, Window, DateTime<Utc>),
|
||||
MoveResizeEnd(WinEvent, Window, DateTime<Utc>),
|
||||
MouseCapture(WinEvent, Window, DateTime<Utc>),
|
||||
Manage(Window, DateTime<Utc>),
|
||||
Unmanage(Window, DateTime<Utc>),
|
||||
Raise(Window, DateTime<Utc>),
|
||||
TitleUpdate(WinEvent, Window, DateTime<Utc>),
|
||||
}
|
||||
|
||||
impl Display for WindowManagerEvent {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Manage(window) => {
|
||||
Self::Manage(window, _) => {
|
||||
write!(f, "Manage (Window: {window})")
|
||||
}
|
||||
Self::Unmanage(window) => {
|
||||
Self::Unmanage(window, _) => {
|
||||
write!(f, "Unmanage (Window: {window})")
|
||||
}
|
||||
Self::Destroy(winevent, window) => {
|
||||
Self::Destroy(winevent, window, _) => {
|
||||
write!(f, "Destroy (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::FocusChange(winevent, window) => {
|
||||
Self::FocusChange(winevent, window, _) => {
|
||||
write!(f, "FocusChange (WinEvent: {winevent}, Window: {window})",)
|
||||
}
|
||||
Self::Hide(winevent, window) => {
|
||||
Self::Hide(winevent, window, _) => {
|
||||
write!(f, "Hide (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::Cloak(winevent, window) => {
|
||||
Self::Cloak(winevent, window, _) => {
|
||||
write!(f, "Cloak (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::Minimize(winevent, window) => {
|
||||
Self::Minimize(winevent, window, _) => {
|
||||
write!(f, "Minimize (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::Show(winevent, window) => {
|
||||
Self::Show(winevent, window, _) => {
|
||||
write!(f, "Show (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::Uncloak(winevent, window) => {
|
||||
Self::Uncloak(winevent, window, _) => {
|
||||
write!(f, "Uncloak (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
Self::MoveResizeStart(winevent, window) => {
|
||||
Self::MoveResizeStart(winevent, window, _) => {
|
||||
write!(
|
||||
f,
|
||||
"MoveResizeStart (WinEvent: {winevent}, Window: {window})",
|
||||
)
|
||||
}
|
||||
Self::MoveResizeEnd(winevent, window) => {
|
||||
Self::MoveResizeEnd(winevent, window, _) => {
|
||||
write!(f, "MoveResizeEnd (WinEvent: {winevent}, Window: {window})",)
|
||||
}
|
||||
Self::MouseCapture(winevent, window) => {
|
||||
Self::MouseCapture(winevent, window, _) => {
|
||||
write!(f, "MouseCapture (WinEvent: {winevent}, Window: {window})",)
|
||||
}
|
||||
Self::Raise(window) => {
|
||||
Self::Raise(window, _) => {
|
||||
write!(f, "Raise (Window: {window})")
|
||||
}
|
||||
Self::TitleUpdate(winevent, window) => {
|
||||
Self::TitleUpdate(winevent, window, _) => {
|
||||
write!(f, "TitleUpdate (WinEvent: {winevent}, Window: {window})")
|
||||
}
|
||||
}
|
||||
|
@ -83,47 +85,75 @@ impl Display for WindowManagerEvent {
|
|||
}
|
||||
|
||||
impl WindowManagerEvent {
|
||||
pub const fn timestamp(self) -> DateTime<Utc> {
|
||||
match self {
|
||||
WindowManagerEvent::Destroy(_, _, timestamp)
|
||||
| WindowManagerEvent::FocusChange(_, _, timestamp)
|
||||
| WindowManagerEvent::Hide(_, _, timestamp)
|
||||
| WindowManagerEvent::Cloak(_, _, timestamp)
|
||||
| WindowManagerEvent::Minimize(_, _, timestamp)
|
||||
| WindowManagerEvent::Show(_, _, timestamp)
|
||||
| WindowManagerEvent::Uncloak(_, _, timestamp)
|
||||
| WindowManagerEvent::MoveResizeStart(_, _, timestamp)
|
||||
| WindowManagerEvent::MoveResizeEnd(_, _, timestamp)
|
||||
| WindowManagerEvent::MouseCapture(_, _, timestamp)
|
||||
| WindowManagerEvent::Manage(_, timestamp)
|
||||
| WindowManagerEvent::Unmanage(_, timestamp)
|
||||
| WindowManagerEvent::Raise(_, timestamp)
|
||||
| WindowManagerEvent::TitleUpdate(_, _, timestamp) => timestamp,
|
||||
}
|
||||
}
|
||||
pub const fn window(self) -> Window {
|
||||
match self {
|
||||
Self::Destroy(_, window)
|
||||
| Self::FocusChange(_, window)
|
||||
| Self::Hide(_, window)
|
||||
| Self::Cloak(_, window)
|
||||
| Self::Minimize(_, window)
|
||||
| Self::Show(_, window)
|
||||
| Self::Uncloak(_, window)
|
||||
| Self::MoveResizeStart(_, window)
|
||||
| Self::MoveResizeEnd(_, window)
|
||||
| Self::MouseCapture(_, window)
|
||||
| Self::Raise(window)
|
||||
| Self::Manage(window)
|
||||
| Self::Unmanage(window)
|
||||
| Self::TitleUpdate(_, window) => window,
|
||||
Self::Destroy(_, window, _)
|
||||
| Self::FocusChange(_, window, _)
|
||||
| Self::Hide(_, window, _)
|
||||
| Self::Cloak(_, window, _)
|
||||
| Self::Minimize(_, window, _)
|
||||
| Self::Show(_, window, _)
|
||||
| Self::Uncloak(_, window, _)
|
||||
| Self::MoveResizeStart(_, window, _)
|
||||
| Self::MoveResizeEnd(_, window, _)
|
||||
| Self::MouseCapture(_, window, _)
|
||||
| Self::Raise(window, _)
|
||||
| Self::Manage(window, _)
|
||||
| Self::Unmanage(window, _)
|
||||
| Self::TitleUpdate(_, window, _) => window,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_win_event(winevent: WinEvent, window: Window) -> Option<Self> {
|
||||
pub fn from_win_event(
|
||||
winevent: WinEvent,
|
||||
window: Window,
|
||||
timestamp: DateTime<Utc>,
|
||||
) -> Option<Self> {
|
||||
match winevent {
|
||||
WinEvent::ObjectDestroy => Option::from(Self::Destroy(winevent, window)),
|
||||
WinEvent::ObjectDestroy => Option::from(Self::Destroy(winevent, window, timestamp)),
|
||||
|
||||
WinEvent::ObjectHide => Option::from(Self::Hide(winevent, window)),
|
||||
WinEvent::ObjectCloaked => Option::from(Self::Cloak(winevent, window)),
|
||||
WinEvent::ObjectHide => Option::from(Self::Hide(winevent, window, timestamp)),
|
||||
WinEvent::ObjectCloaked => Option::from(Self::Cloak(winevent, window, timestamp)),
|
||||
|
||||
WinEvent::SystemMinimizeStart => Option::from(Self::Minimize(winevent, window)),
|
||||
WinEvent::SystemMinimizeStart => {
|
||||
Option::from(Self::Minimize(winevent, window, timestamp))
|
||||
}
|
||||
|
||||
WinEvent::ObjectShow | WinEvent::SystemMinimizeEnd => {
|
||||
Option::from(Self::Show(winevent, window))
|
||||
Option::from(Self::Show(winevent, window, timestamp))
|
||||
}
|
||||
|
||||
WinEvent::ObjectUncloaked => Option::from(Self::Uncloak(winevent, window)),
|
||||
WinEvent::ObjectUncloaked => Option::from(Self::Uncloak(winevent, window, timestamp)),
|
||||
|
||||
WinEvent::ObjectFocus | WinEvent::SystemForeground => {
|
||||
Option::from(Self::FocusChange(winevent, window))
|
||||
Option::from(Self::FocusChange(winevent, window, timestamp))
|
||||
}
|
||||
WinEvent::SystemMoveSizeStart => {
|
||||
Option::from(Self::MoveResizeStart(winevent, window, timestamp))
|
||||
}
|
||||
WinEvent::SystemMoveSizeEnd => {
|
||||
Option::from(Self::MoveResizeEnd(winevent, window, timestamp))
|
||||
}
|
||||
WinEvent::SystemMoveSizeStart => Option::from(Self::MoveResizeStart(winevent, window)),
|
||||
WinEvent::SystemMoveSizeEnd => Option::from(Self::MoveResizeEnd(winevent, window)),
|
||||
WinEvent::SystemCaptureStart | WinEvent::SystemCaptureEnd => {
|
||||
Option::from(Self::MouseCapture(winevent, window))
|
||||
Option::from(Self::MouseCapture(winevent, window, timestamp))
|
||||
}
|
||||
WinEvent::ObjectNameChange => {
|
||||
// Some apps like Firefox don't send ObjectCreate or ObjectShow on launch
|
||||
|
@ -152,9 +182,9 @@ impl WindowManagerEvent {
|
|||
.is_some();
|
||||
|
||||
if should_trigger_show {
|
||||
Option::from(Self::Show(winevent, window))
|
||||
Option::from(Self::Show(winevent, window, timestamp))
|
||||
} else {
|
||||
Option::from(Self::TitleUpdate(winevent, window))
|
||||
Option::from(Self::TitleUpdate(winevent, window, timestamp))
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
@ -1061,4 +1061,8 @@ impl WindowsApi {
|
|||
pub fn wts_register_session_notification(hwnd: isize) -> Result<()> {
|
||||
unsafe { WTSRegisterSessionNotification(HWND(hwnd), 1) }.process()
|
||||
}
|
||||
|
||||
pub fn tick_count() -> u64 {
|
||||
unsafe { windows::Win32::System::SystemInformation::GetTickCount64() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
use chrono::TimeZone;
|
||||
use chrono::Utc;
|
||||
use std::collections::VecDeque;
|
||||
use std::ops::Sub;
|
||||
use std::time::Duration;
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
use windows::Win32::Foundation::HWND;
|
||||
|
@ -67,13 +72,25 @@ pub extern "system" fn win_event_hook(
|
|||
id_object: i32,
|
||||
_id_child: i32,
|
||||
_id_event_thread: u32,
|
||||
_dwms_event_time: u32,
|
||||
dwms_event_time: u32,
|
||||
) {
|
||||
// OBJID_WINDOW
|
||||
if id_object != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let millis_since_boot = WindowsApi::tick_count();
|
||||
let system_time_now = std::time::SystemTime::now();
|
||||
|
||||
let boot_time = system_time_now
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.sub(Duration::from_millis(millis_since_boot))
|
||||
.as_secs();
|
||||
|
||||
let boot_time_utc = Utc.timestamp_opt(boot_time as i64, 0).unwrap();
|
||||
let timestamp = boot_time_utc + Duration::from_millis(dwms_event_time as u64);
|
||||
|
||||
let window = Window::from(hwnd);
|
||||
|
||||
let winevent = match WinEvent::try_from(event) {
|
||||
|
@ -81,7 +98,7 @@ pub extern "system" fn win_event_hook(
|
|||
Err(_) => return,
|
||||
};
|
||||
|
||||
let event_type = match WindowManagerEvent::from_win_event(winevent, window) {
|
||||
let event_type = match WindowManagerEvent::from_win_event(winevent, window, timestamp) {
|
||||
None => {
|
||||
tracing::trace!(
|
||||
"Unhandled WinEvent: {winevent} (hwnd: {}, exe: {}, title: {}, class: {})",
|
||||
|
|
Loading…
Reference in New Issue