|
1 | 1 | use std::path::PathBuf; |
2 | 2 | use std::sync::atomic::{AtomicU32, Ordering}; |
3 | 3 | use std::sync::{Mutex, MutexGuard}; |
4 | | -use std::time::{Duration, SystemTime, UNIX_EPOCH}; |
| 4 | +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; |
5 | 5 |
|
6 | 6 | use serde::{Deserialize, Serialize}; |
7 | 7 | use windows::core::PCWSTR; |
@@ -118,6 +118,9 @@ const DIVIDER_HIT_ZONE: i32 = 13; // LEFT_DIVIDER_W + DIVIDER_RIGHT_MARGIN |
118 | 118 |
|
119 | 119 | const WM_DPICHANGED_MSG: u32 = 0x02E0; |
120 | 120 | const WM_APP_UPDATE_CHECK_COMPLETE: u32 = WM_APP + 2; |
| 121 | +const TRAY_ICON_UPDATE_REPOSITION_SUPPRESS_MS: u64 = 750; |
| 122 | + |
| 123 | +static SUPPRESS_TRAY_REPOSITION_UNTIL: Mutex<Option<Instant>> = Mutex::new(None); |
121 | 124 |
|
122 | 125 | /// Current system DPI (96 = 100% scaling, 144 = 150%, 192 = 200%, etc.) |
123 | 126 | static CURRENT_DPI: AtomicU32 = AtomicU32::new(96); |
@@ -1448,6 +1451,29 @@ fn update_display() { |
1448 | 1451 | refresh_usage_texts(s); |
1449 | 1452 | } |
1450 | 1453 |
|
| 1454 | +fn suppress_tray_reposition_for(duration: Duration) { |
| 1455 | + let mut until = SUPPRESS_TRAY_REPOSITION_UNTIL |
| 1456 | + .lock() |
| 1457 | + .unwrap_or_else(|e| e.into_inner()); |
| 1458 | + *until = Some(Instant::now() + duration); |
| 1459 | +} |
| 1460 | + |
| 1461 | +fn tray_reposition_is_suppressed() -> bool { |
| 1462 | + let now = Instant::now(); |
| 1463 | + let mut until = SUPPRESS_TRAY_REPOSITION_UNTIL |
| 1464 | + .lock() |
| 1465 | + .unwrap_or_else(|e| e.into_inner()); |
| 1466 | + |
| 1467 | + match *until { |
| 1468 | + Some(deadline) if now < deadline => true, |
| 1469 | + Some(_) => { |
| 1470 | + *until = None; |
| 1471 | + false |
| 1472 | + } |
| 1473 | + None => false, |
| 1474 | + } |
| 1475 | +} |
| 1476 | + |
1451 | 1477 | fn position_at_taskbar() { |
1452 | 1478 | refresh_dpi(); |
1453 | 1479 | // Drop the app-state lock before any Win32 call that may synchronously |
@@ -1543,6 +1569,10 @@ unsafe extern "system" fn on_tray_location_changed( |
1543 | 1569 | }; |
1544 | 1570 |
|
1545 | 1571 | if is_tray { |
| 1572 | + if tray_reposition_is_suppressed() { |
| 1573 | + return; |
| 1574 | + } |
| 1575 | + |
1546 | 1576 | let should_reposition = { |
1547 | 1577 | let mut last = LAST_REPOSITION.lock().unwrap_or_else(|e| e.into_inner()); |
1548 | 1578 | let now = std::time::Instant::now(); |
@@ -1681,6 +1711,9 @@ unsafe extern "system" fn wnd_proc( |
1681 | 1711 | render_layered(); |
1682 | 1712 | schedule_countdown_timer(); |
1683 | 1713 | let (pct, tooltip) = tray_icon_data_from_state(); |
| 1714 | + suppress_tray_reposition_for(Duration::from_millis( |
| 1715 | + TRAY_ICON_UPDATE_REPOSITION_SUPPRESS_MS, |
| 1716 | + )); |
1684 | 1717 | tray_icon::update(hwnd, pct, &tooltip); |
1685 | 1718 | LRESULT(0) |
1686 | 1719 | } |
|
0 commit comments