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
1 change: 1 addition & 0 deletions src/localization/dutch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Instellingen",
start_with_windows: "Opstarten met Windows",
reset_position: "Positie herstellen",
monitor: "Beeldscherm",
language: "Taal",
system_default: "Systeemstandaard",
check_for_updates: "Controleren op updates",
Expand Down
1 change: 1 addition & 0 deletions src/localization/english.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Settings",
start_with_windows: "Start with Windows",
reset_position: "Reset Position",
monitor: "Monitor",
language: "Language",
system_default: "System Default",
check_for_updates: "Check for Updates",
Expand Down
1 change: 1 addition & 0 deletions src/localization/french.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Paramètres",
start_with_windows: "Démarrer avec Windows",
reset_position: "Réinitialiser la position",
monitor: "Écran",
language: "Langue",
system_default: "Par défaut du système",
check_for_updates: "Vérifier les mises à jour",
Expand Down
1 change: 1 addition & 0 deletions src/localization/german.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Einstellungen",
start_with_windows: "Mit Windows starten",
reset_position: "Position zurücksetzen",
monitor: "Monitor",
language: "Sprache",
system_default: "Systemstandard",
check_for_updates: "Nach Updates suchen",
Expand Down
1 change: 1 addition & 0 deletions src/localization/japanese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "設定",
start_with_windows: "Windows と同時に開始",
reset_position: "位置をリセット",
monitor: "モニター",
language: "言語",
system_default: "システム既定",
check_for_updates: "更新を確認",
Expand Down
1 change: 1 addition & 0 deletions src/localization/korean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "설정",
start_with_windows: "Windows 시작 시 자동 실행",
reset_position: "위치 초기화",
monitor: "모니터",
language: "언어",
system_default: "시스템 기본값",
check_for_updates: "업데이트 확인",
Expand Down
1 change: 1 addition & 0 deletions src/localization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub struct Strings {
pub settings: &'static str,
pub start_with_windows: &'static str,
pub reset_position: &'static str,
pub monitor: &'static str,
pub language: &'static str,
pub system_default: &'static str,
pub check_for_updates: &'static str,
Expand Down
1 change: 1 addition & 0 deletions src/localization/portuguese_brazil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Configurações",
start_with_windows: "Iniciar com o Windows",
reset_position: "Redefinir Posição",
monitor: "Monitor",
language: "Idioma",
system_default: "Padrão do Sistema",
check_for_updates: "Busca atualizações",
Expand Down
1 change: 1 addition & 0 deletions src/localization/russian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Настройки",
start_with_windows: "Запускать вместе с Windows",
reset_position: "Сбросить позицию",
monitor: "Монитор",
language: "Язык",
system_default: "Системный по умолчанию",
check_for_updates: "Проверить обновления",
Expand Down
1 change: 1 addition & 0 deletions src/localization/spanish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "Configuración",
start_with_windows: "Iniciar con Windows",
reset_position: "Restablecer posición",
monitor: "Monitor",
language: "Idioma",
system_default: "Predeterminado del sistema",
check_for_updates: "Buscar actualizaciones",
Expand Down
1 change: 1 addition & 0 deletions src/localization/traditional_chinese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(super) const STRINGS: Strings = Strings {
settings: "設定",
start_with_windows: "開機時啟動",
reset_position: "重置位置",
monitor: "螢幕",
language: "語言",
system_default: "系統預設",
check_for_updates: "檢查更新",
Expand Down
50 changes: 48 additions & 2 deletions src/native_interop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use windows::core::PCWSTR;
use windows::Win32::Foundation::{BOOL, HWND, LPARAM, RECT};
use windows::Win32::Graphics::Gdi::{
GetMonitorInfoW, MonitorFromWindow, MONITORINFOEXW, MONITOR_DEFAULTTONEAREST,
};

/// `MONITORINFOF_PRIMARY` — not re-exported by this `windows` crate version.
const MONITORINFOF_PRIMARY: u32 = 0x0000_0001;
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 +30,40 @@ 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,
/// Stable monitor identity (e.g. "\\\\.\\DISPLAY1"). Used to keep the widget
/// anchored to the same physical monitor across topology changes, where the
/// geometric ordering (and therefore the index) of taskbars can shift.
pub device: String,
/// True if this taskbar lives on the primary monitor. Used as the fallback
/// anchor when the remembered device is gone, so we never re-trigger the
/// "widget jumps to the topmost (often secondary) taskbar" bug (#43).
pub is_primary: bool,
}

/// Stable identity of the monitor a window currently lives on: its device name
/// and whether it is the primary monitor.
pub fn monitor_identity(hwnd: HWND) -> (String, bool) {
unsafe {
let monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
let mut info = MONITORINFOEXW::default();
info.monitorInfo.cbSize = std::mem::size_of::<MONITORINFOEXW>() as u32;
if GetMonitorInfoW(monitor, &mut info as *mut _ as *mut _).as_bool() {
let len = info
.szDevice
.iter()
.position(|&c| c == 0)
.unwrap_or(info.szDevice.len());
let device = String::from_utf16_lossy(&info.szDevice[..len]);
let is_primary = info.monitorInfo.dwFlags & MONITORINFOF_PRIMARY != 0;
(device, is_primary)
} else {
(String::new(), false)
}
}
}

pub fn find_taskbars() -> Vec<TaskbarWindow> {
Expand All @@ -39,7 +75,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 (device, is_primary) = monitor_identity(hwnd);
taskbars.push(TaskbarWindow {
hwnd,
rect,
device,
is_primary,
});
}
}
}
Expand Down Expand Up @@ -169,6 +211,10 @@ pub fn get_window_thread_id(hwnd: HWND) -> u32 {
unsafe { GetWindowThreadProcessId(hwnd, None) }
}

pub fn window_exists(hwnd: HWND) -> bool {
unsafe { IsWindow(hwnd).as_bool() }
}

/// Unhook a WinEvent hook
pub fn unhook_win_event(hook: HWINEVENTHOOK) {
unsafe {
Expand Down
Loading