Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/localization/dutch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Open Antigravity en meld je opnieuw aan. Ververs of herstart de app daarna.",
codex_window_title: "Codex-gebruiksmonitor",
antigravity_window_title: "Antigravity-gebruiksmonitor",
display_on: "Weergeven op",
monitor: "Monitor",
primary: "Primair",
second_suffix: "s",
};
3 changes: 3 additions & 0 deletions src/localization/english.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Open Antigravity and sign in again. After that, refresh or restart this app.",
codex_window_title: "Codex Usage Monitor",
antigravity_window_title: "Antigravity Usage Monitor",
display_on: "Display on",
monitor: "Monitor",
primary: "Primary",
second_suffix: "s",
};
3 changes: 3 additions & 0 deletions src/localization/french.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Ouvrez Antigravity et reconnectez-vous. Ensuite, actualisez ou redemarrez cette application.",
codex_window_title: "Moniteur d'utilisation Codex",
antigravity_window_title: "Moniteur d'utilisation Antigravity",
display_on: "Afficher sur",
monitor: "Moniteur",
primary: "Principal",
second_suffix: "s",
};
3 changes: 3 additions & 0 deletions src/localization/german.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Offnen Sie Antigravity und melden Sie sich erneut an. Aktualisieren oder starten Sie diese App anschliessend neu.",
codex_window_title: "Codex-Nutzungsmonitor",
antigravity_window_title: "Antigravity-Nutzungsmonitor",
display_on: "Anzeigen auf",
monitor: "Monitor",
primary: "Primär",
second_suffix: "s",
};
3 changes: 3 additions & 0 deletions src/localization/japanese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Antigravity を開いて再度サインインしてください。その後、このアプリを更新するか再起動してください。",
codex_window_title: "Codex 使用量モニター",
antigravity_window_title: "Antigravity 使用量モニター",
display_on: "表示するモニター",
monitor: "モニター",
primary: "プライマリ",
second_suffix: "秒",
};
3 changes: 3 additions & 0 deletions src/localization/korean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Antigravity를 열고 다시 로그인하세요. 그런 다음 이 앱을 새로 고치거나 다시 시작하세요.",
codex_window_title: "Codex 사용량 모니터",
antigravity_window_title: "Antigravity 사용량 모니터",
display_on: "표시할 모니터",
monitor: "모니터",
primary: "기본",
second_suffix: "초",
};
3 changes: 3 additions & 0 deletions src/localization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ pub struct Strings {
pub antigravity_token_expired_body: &'static str,
pub codex_window_title: &'static str,
pub antigravity_window_title: &'static str,
pub display_on: &'static str,
pub monitor: &'static str,
pub primary: &'static str,
}

pub fn resolve_language(language_override: Option<LanguageId>) -> LanguageId {
Expand Down
3 changes: 3 additions & 0 deletions src/localization/portuguese_brazil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Abra o Antigravity e entre novamente. Depois disso, atualize ou reinicie este aplicativo.",
codex_window_title: "Monitor de uso do Codex",
antigravity_window_title: "Monitor de uso do Antigravity",
display_on: "Exibir em",
monitor: "Monitor",
primary: "Principal",
};
3 changes: 3 additions & 0 deletions src/localization/russian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Откройте Antigravity и войдите снова. После этого обновите или перезапустите приложение.",
codex_window_title: "Монитор использования Codex",
antigravity_window_title: "Монитор использования Antigravity",
display_on: "Показывать на",
monitor: "Монитор",
primary: "Основной",
};
3 changes: 3 additions & 0 deletions src/localization/simplified_chinese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "请打开 Antigravity 并重新登录。完成后,请刷新或重新启动此应用程序。",
codex_window_title: "Codex 使用量监控",
antigravity_window_title: "Antigravity 使用量监控",
display_on: "显示于",
monitor: "显示器",
primary: "主要",
second_suffix: "秒",
};
3 changes: 3 additions & 0 deletions src/localization/spanish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "Abre Antigravity e inicia sesion otra vez. Despues, actualiza o reinicia esta aplicacion.",
codex_window_title: "Monitor de uso de Codex",
antigravity_window_title: "Monitor de uso de Antigravity",
display_on: "Mostrar en",
monitor: "Monitor",
primary: "Principal",
second_suffix: "s",
};
3 changes: 3 additions & 0 deletions src/localization/traditional_chinese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ pub(super) const STRINGS: Strings = Strings {
antigravity_token_expired_body: "請開啟 Antigravity 並重新登入。完成後,請重新整理或重新啟動此應用程式。",
codex_window_title: "Codex 使用量監控",
antigravity_window_title: "Antigravity 使用量監控",
display_on: "顯示於",
monitor: "螢幕",
primary: "主要",
second_suffix: "秒",
};
50 changes: 48 additions & 2 deletions src/native_interop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use windows::core::PCWSTR;
use windows::Win32::Foundation::{BOOL, HWND, LPARAM, RECT};
use windows::Win32::Graphics::Gdi::{
GetMonitorInfoW, MonitorFromRect, MONITORINFO, MONITORINFOEXW, MONITOR_DEFAULTTONEAREST,
};
use windows::Win32::UI::Accessibility::{SetWinEventHook, UnhookWinEvent, HWINEVENTHOOK};
use windows::Win32::UI::Shell::{SHAppBarMessage, ABM_GETTASKBARPOS, APPBARDATA};
use windows::Win32::UI::WindowsAndMessaging::*;
Expand All @@ -24,10 +27,47 @@ pub const WM_APP: u32 = 0x8000;
pub const WM_APP_USAGE_UPDATED: u32 = WM_APP + 1;
pub const WM_APP_TRAY: u32 = WM_APP + 3;

#[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
pub struct TaskbarWindow {
pub hwnd: HWND,
pub rect: RECT,
pub is_primary: bool,
/// Stable identity of the monitor this taskbar sits on (e.g. "\\.\DISPLAY2").
/// Unlike the taskbar's position in `find_taskbars()`, this does not change
/// when another monitor's taskbar is hidden/recreated (e.g. by fullscreen
/// video), so it is what we persist and re-attach against.
pub monitor_device: String,
}

/// Query the monitor containing `rect`: whether it is the primary display and
/// its stable device name (`szDevice`, e.g. "\\.\DISPLAY1"). The device name is
/// empty only if the monitor cannot be resolved.
fn monitor_info_for_rect(rect: &RECT) -> (bool, String) {
unsafe {
let hmon = MonitorFromRect(rect as *const RECT, MONITOR_DEFAULTTONEAREST);
if hmon.is_invalid() {
return (false, String::new());
}
let mut info = MONITORINFOEXW {
monitorInfo: MONITORINFO {
cbSize: std::mem::size_of::<MONITORINFOEXW>() as u32,
..Default::default()
},
..Default::default()
};
if GetMonitorInfoW(hmon, &mut info.monitorInfo as *mut MONITORINFO).as_bool() {
let is_primary = (info.monitorInfo.dwFlags & MONITORINFOF_PRIMARY) != 0;
let len = info
.szDevice
.iter()
.position(|&c| c == 0)
.unwrap_or(info.szDevice.len());
let device = String::from_utf16_lossy(&info.szDevice[..len]);
(is_primary, device)
} else {
(false, String::new())
}
}
}

pub fn find_taskbars() -> Vec<TaskbarWindow> {
Expand All @@ -39,7 +79,13 @@ pub fn find_taskbars() -> Vec<TaskbarWindow> {
let class_name = String::from_utf16_lossy(&class_name[..len as usize]);
if class_name == "Shell_TrayWnd" || class_name == "Shell_SecondaryTrayWnd" {
if let Some(rect) = get_taskbar_rect(hwnd).or_else(|| get_window_rect_safe(hwnd)) {
taskbars.push(TaskbarWindow { hwnd, rect });
let (is_primary, monitor_device) = monitor_info_for_rect(&rect);
taskbars.push(TaskbarWindow {
hwnd,
rect,
is_primary,
monitor_device,
});
}
}
}
Expand Down
Loading