fix(desktop): fall back to top-right when tray click has no usable coords

The GNOME AppIndicator extension delivers Activate with (0, 0) instead of
real screen coordinates, which made the popover land in the top-left corner
because the centering math treated the bogus origin as a legitimate anchor.
Treat (0, 0) as no-anchor and reuse the top-right fallback the non-Linux
path already uses, so the popover lands near the StatusNotifier area on
hosts that don't pass coordinates.

Also cfg-gate the Emitter import since it is only used in the non-Linux
tray menu path.
This commit is contained in:
AgentSeal 2026-04-18 04:03:02 -07:00
parent ea5e311d4a
commit 5281a08e06

View file

@ -6,7 +6,9 @@ mod tray_linux;
use std::sync::Mutex;
use tauri::{AppHandle, Emitter, Manager, WindowEvent};
use tauri::{AppHandle, Manager, WindowEvent};
#[cfg(not(target_os = "linux"))]
use tauri::Emitter;
#[cfg(target_os = "linux")]
use tauri::Listener;
@ -190,7 +192,9 @@ fn position_popover(window: &tauri::WebviewWindow, anchor: Option<(i32, i32)>) {
let screen_w = screen.width as i32;
let screen_h = screen.height as i32;
let (x, y) = match anchor {
let usable_anchor = anchor.filter(|(ax, ay)| *ax > 0 || *ay > 0);
let (x, y) = match usable_anchor {
Some((click_x, click_y)) => {
// Center horizontally on the click, drop the popover just below it. Clamp to
// the screen so it doesn't fall off the edge on multi-monitor setups.
@ -202,6 +206,9 @@ fn position_popover(window: &tauri::WebviewWindow, anchor: Option<(i32, i32)>) {
(clamped_x, clamped_y)
}
None => {
// No usable anchor. Some SNI hosts (notably the GNOME AppIndicator extension)
// send (0, 0) instead of real screen coordinates. Fall back to the top-right
// corner where the StatusNotifier area lives on GNOME, KDE, and Unity.
let x = (screen_w - pop_w - margin).max(0);
(x, panel)
}