Tray: minimize-to-tray is opt-in via config
Make ui.minimize_to_tray default-off so users on desktops without a working StatusNotifier host (GNOME sans AppIndicator extension being the common case) don't get stuck — without an opt-in, clicking X would hide an invisible window with no obvious way back. The tray menu's Show/Hide/Quit and Ctrl+Q still work regardless of the flag; the toggle only affects what happens when the user clicks the window's close button. Added a settings-screen checkbox for the flag with a tooltip explaining the SNI dependency. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
abe7d63794
commit
615bc0cd4b
2 changed files with 27 additions and 9 deletions
16
src/app.rs
16
src/app.rs
|
|
@ -2126,6 +2126,11 @@ impl App {
|
||||||
});
|
});
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("Minimize to tray:");
|
||||||
|
ui.checkbox(&mut self.config.ui.minimize_to_tray, "hide window on close instead of quitting")
|
||||||
|
.on_hover_text("Requires a working StatusNotifier host (KDE native, GNOME with AppIndicator extension). Ctrl+Q always quits.");
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Auto-check channels:");
|
ui.label("Auto-check channels:");
|
||||||
ui.checkbox(&mut self.config.scheduler.enabled, "enabled");
|
ui.checkbox(&mut self.config.scheduler.enabled, "enabled");
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
@ -3082,16 +3087,19 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Minimize-to-tray: if the user clicked the close button but
|
// Minimize-to-tray: only intercept the close button when the
|
||||||
// hasn't explicitly chosen Quit, cancel the close and hide
|
// user has opted in via config. Default-off because users on
|
||||||
// the window instead. Without a tray we fall through to the
|
// desktops without a working StatusNotifier host (e.g. GNOME
|
||||||
// normal close flow so the app actually exits.
|
// sans AppIndicator extension) would otherwise lose access
|
||||||
|
// to the window entirely. Ctrl+Q is always an escape.
|
||||||
|
if self.config.ui.minimize_to_tray {
|
||||||
let close_requested = ctx.input(|i| i.viewport().close_requested());
|
let close_requested = ctx.input(|i| i.viewport().close_requested());
|
||||||
if close_requested && !self.quitting {
|
if close_requested && !self.quitting {
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::CancelClose);
|
ctx.send_viewport_cmd(egui::ViewportCommand::CancelClose);
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::Visible(false));
|
ctx.send_viewport_cmd(egui::ViewportCommand::Visible(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.downloader.poll();
|
self.downloader.poll();
|
||||||
// Snapshot the previous-frame running state BEFORE check_notifications
|
// Snapshot the previous-frame running state BEFORE check_notifications
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,21 @@ impl Default for PlayerSection {
|
||||||
pub struct UiSection {
|
pub struct UiSection {
|
||||||
#[serde(default = "default_theme")]
|
#[serde(default = "default_theme")]
|
||||||
pub theme: String,
|
pub theme: String,
|
||||||
|
/// When true, clicking the window close button hides the window
|
||||||
|
/// into the system tray instead of exiting. The tray menu's Quit
|
||||||
|
/// item (or Ctrl+Q) still terminates the app. Off by default so
|
||||||
|
/// users without a working SNI host don't get stuck in an invisible
|
||||||
|
/// hidden window.
|
||||||
|
#[serde(default)]
|
||||||
|
pub minimize_to_tray: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UiSection {
|
impl Default for UiSection {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { theme: default_theme() }
|
Self {
|
||||||
|
theme: default_theme(),
|
||||||
|
minimize_to_tray: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue