-
-
Notifications
You must be signed in to change notification settings - Fork 51
feat(gui): "Show in menu bar" setting + ⌘W to close windows #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -322,6 +322,31 @@ impl AppState { | |
| crate::platform::launch_agent::reconcile(enabled); | ||
| } | ||
|
|
||
| /// Toggle the macOS menu-bar (status item) icon, persist it, and apply it | ||
| /// live. Turning it off hides the item *and* pins the app to Regular | ||
| /// activation, so it stays an ordinary Dock app rather than being left with | ||
| /// neither a window, a Dock icon, nor a menu-bar icon. No-op when unchanged. | ||
| /// | ||
| /// macOS-only: the toggle that calls it exists only there, so gating avoids | ||
| /// an unused-method warning on other platforms. | ||
| #[cfg(target_os = "macos")] | ||
| pub fn set_show_in_menu_bar(&mut self, enabled: bool) { | ||
| if self.config.app_settings.show_in_menu_bar == enabled { | ||
| return; | ||
| } | ||
| self.config.app_settings.show_in_menu_bar = enabled; | ||
| if let Err(e) = self.config.save_atomic() { | ||
| warn!(error = %e, "could not persist show-in-menu-bar setting"); | ||
| } | ||
| #[cfg(target_os = "macos")] | ||
| { | ||
| crate::platform::tray::set_visible(enabled); | ||
| if !enabled { | ||
| crate::platform::tray::show_in_dock(); | ||
| } | ||
| } | ||
|
Comment on lines
+341
to
+347
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant |
||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth a short comment on the asymmetry: disabling restores |
||
|
|
||
| /// Toggle the opt-in update check and persist it. No immediate side | ||
| /// effect beyond the next launch reading the new value. No-op when | ||
| /// unchanged. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,63 @@ impl Render for SettingsView { | |
| (a.launch_at_login, a.check_for_updates, a.language.clone()) | ||
| }); | ||
|
|
||
| let general = GroupBox::new() | ||
| .title(group_title(IconName::Settings, tr!("General"))) | ||
| .child(setting_row( | ||
| Switch::new("launch-at-login") | ||
| .checked(launch) | ||
| .on_click(cx.listener(|_, checked: &bool, _, cx| { | ||
| let enabled = *checked; | ||
| cx.update_global::<AppState, _>(move |s, _| { | ||
| s.set_launch_at_login(enabled); | ||
| }); | ||
| cx.notify(); | ||
| })), | ||
| tr!("Launch at login"), | ||
| tr!("Automatically start OpenLogi when you log in to macOS."), | ||
| pal, | ||
| )) | ||
| .child(setting_row( | ||
| Switch::new("check-for-updates") | ||
| .checked(updates) | ||
| .on_click(cx.listener(|_, checked: &bool, _, cx| { | ||
| let enabled = *checked; | ||
| cx.update_global::<AppState, _>(move |s, _| { | ||
| s.set_check_for_updates(enabled); | ||
| }); | ||
| cx.notify(); | ||
| })), | ||
| tr!("Check for updates"), | ||
| tr!( | ||
| "Check once per launch for a new version (query only — no automatic download)." | ||
| ), | ||
| pal, | ||
| )); | ||
|
|
||
| // The menu-bar (status item) is macOS-only, so its toggle is too. | ||
| #[cfg(target_os = "macos")] | ||
| let general = { | ||
| let in_menu_bar = cx | ||
| .try_global::<AppState>() | ||
| .is_some_and(|s| s.app_settings().show_in_menu_bar); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: this re-reads |
||
| general.child(setting_row( | ||
| Switch::new("show-in-menu-bar") | ||
| .checked(in_menu_bar) | ||
| .on_click(cx.listener(|_, checked: &bool, _, cx| { | ||
| let enabled = *checked; | ||
| cx.update_global::<AppState, _>(move |s, _| { | ||
| s.set_show_in_menu_bar(enabled); | ||
| }); | ||
| cx.notify(); | ||
| })), | ||
| tr!("Show in menu bar"), | ||
| tr!( | ||
| "Keep OpenLogi's icon in the menu bar. When off, it stays in the Dock instead." | ||
| ), | ||
| pal, | ||
| )) | ||
| }; | ||
|
|
||
| v_flex() | ||
| .size_full() | ||
| .bg(pal.bg) | ||
|
|
@@ -70,38 +127,7 @@ impl Render for SettingsView { | |
| .font_weight(FontWeight::SEMIBOLD) | ||
| .child(tr!("Settings")), | ||
| ) | ||
| .child( | ||
| GroupBox::new() | ||
| .title(group_title(IconName::Settings, tr!("General"))) | ||
| .child(setting_row( | ||
| Switch::new("launch-at-login") | ||
| .checked(launch) | ||
| .on_click(cx.listener(|_, checked: &bool, _, cx| { | ||
| let enabled = *checked; | ||
| cx.update_global::<AppState, _>(move |s, _| { | ||
| s.set_launch_at_login(enabled); | ||
| }); | ||
| cx.notify(); | ||
| })), | ||
| tr!("Launch at login"), | ||
| tr!("Automatically start OpenLogi when you log in to macOS."), | ||
| pal, | ||
| )) | ||
| .child(setting_row( | ||
| Switch::new("check-for-updates") | ||
| .checked(updates) | ||
| .on_click(cx.listener(|_, checked: &bool, _, cx| { | ||
| let enabled = *checked; | ||
| cx.update_global::<AppState, _>(move |s, _| { | ||
| s.set_check_for_updates(enabled); | ||
| }); | ||
| cx.notify(); | ||
| })), | ||
| tr!("Check for updates"), | ||
| tr!("Check once per launch for a new version (query only — no automatic download)."), | ||
| pal, | ||
| )), | ||
| ) | ||
| .child(general) | ||
| .child( | ||
| GroupBox::new() | ||
| .title(group_title(IconName::Globe, tr!("Language"))) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try_global::<AppState>()here means: ifAppStateever isn't installed when a window closes,tray_onsilently becomesfalseand the app stays in Regular — the opposite of the default behavior. AppState is set before any window opens in this run, so it's safe today, butcx.global::<AppState>()would panic loudly on a regression instead of degrading silently. Consider switching unless you have a specific reason to expect it can be absent.