From afaf74a6da757a257243d104f4188baa3a43a68e Mon Sep 17 00:00:00 2001 From: Somei Tanoue <113166576+somei-san@users.noreply.github.com> Date: Wed, 19 Aug 2026 10:40:28 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E3=83=A1=E3=83=8B=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E3=83=90=E3=83=BC=E3=81=AE=E3=82=A2=E3=82=A4=E3=82=B3?= =?UTF-8?q?=E3=83=B3=E3=82=92=E9=9D=9E=E8=A1=A8=E7=A4=BA=E3=81=AB=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 設定 `[display] show_menu_bar_icon` を正とし、NSStatusItem の表示をその派生物にする。 非表示にするとメニューから開く設定・一時停止・終了に届かなくなるため、設定ウィンドウの トグルで消したときだけ、復帰方法(アプリをもう一度起動すると設定ウィンドウが開く)を ダイアログで案内する。 トグルの表示同期に null ガードが無く、設定ウィンドウを一度も開かずに設定ファイルを 手編集するとアボートしていた。自動起動のトグルも同じ形だったのであわせて塞ぐ。 VRT に設定タブの行スタック全体(NSScrollView の documentView)を撮るケースを足す。 ペインの撮影は可視域だけを写すため、スクロールしないと見えない行を検証できない。 Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 2 +- README.ja.md | 2 + README.md | 2 + docs/development.md | 3 + scripts/visual_regression.sh | 18 +++++- src/app/config_reload.rs | 17 +++++ src/app/mod.rs | 71 ++++++++++++++++++++- src/app/panels.rs | 27 ++++++++ src/cli.rs | 20 +++++- src/config/parse.rs | 61 +++++++++++++++--- src/config/settings.rs | 17 ++++- src/config/types.rs | 7 +- src/i18n.rs | 15 +++++ src/menu.rs | 10 +++ src/png.rs | 65 +++++++++++++++---- src/settings_window/build.rs | 31 +++++++-- src/settings_window/mod.rs | 30 +++++++-- src/settings_window/rows.rs | 46 +++++++++---- src/settings_window/sync.rs | 70 ++++++++++++++++++-- tests/visual/baseline/settings_rows_en.png | Bin 0 -> 44981 bytes tests/visual/baseline/settings_rows_ja.png | Bin 0 -> 47635 bytes 21 files changed, 448 insertions(+), 66 deletions(-) create mode 100644 tests/visual/baseline/settings_rows_en.png create mode 100644 tests/visual/baseline/settings_rows_ja.png diff --git a/CLAUDE.md b/CLAUDE.md index 146f251..ac13300 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,7 +30,7 @@ HUD を実機で見るなら `./scripts/local_check.sh`(オプションは `do ```bash ./scripts/visual_regression.sh --update ``` -- VRT が撮るのは HUD の contentView と設定ウィンドウの各ペイン(`run_settings_case`。タブバーは contentView の外なので写らない)。メニューバーと About パネルは対象外(システム所有の表面で view を PNG 化できない。About は渡す中身を UT で固定している) +- VRT が撮るのは HUD の contentView、設定ウィンドウの各ペイン、設定タブの行スタック全体(`run_settings_case`。ペインはタブバーが contentView の外なので写らず、行スタック全体は `NSScrollView` の documentView を可視域でクリップせず撮る)。メニューバーと About パネルは対象外(システム所有の表面で view を PNG 化できない。About は渡す中身を UT で固定している) - VRT のケースは `CLIIP_SHOW_*` 環境変数で設定を上書きして作る(`scripts/visual_regression.sh` の `run_case`)。設定ウィンドウのケースは `CLIIP_SHOW_LANGUAGE` を必ず明示する(`auto` は実行マシンの言語に依存し、ローカルと CI でベースラインが食い違う) - `Cargo.toml` の `edition` を変えたら `.claude/settings.json` の rustfmt フック(`--edition` を直書き)も同期する。ズレるとフックの整形結果を CI の `cargo fmt --check` が拒否する diff --git a/README.ja.md b/README.ja.md index 9f62687..b7d2062 100644 --- a/README.ja.md +++ b/README.ja.md @@ -47,6 +47,8 @@ Apple の Developer ID で署名していないため、cask のインストー 起動中にもう一度起動すると、2 つ目は立ち上がらず設定ウィンドウが開きます。 +設定ウィンドウの「メニューバーにアイコンを表示」でメニューバーのアイコンを非表示にできます。非表示にするとメニュー(設定・一時停止・終了)にも触れなくなりますが、アプリをもう一度起動すると設定ウィンドウが前面に出るので、そこから再び表示できます。 + ### formula から乗り換える formula は cask に置き換わったので、先にアンインストールします。 diff --git a/README.md b/README.md index a9bb57c..d6bf68a 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ Launching it shows "Cliip Show started" in the HUD. It stays quiet when launched Launching it again while it is running opens the settings window instead of starting a second copy. +You can hide the menu bar icon from "Show icon in menu bar" in the settings window. If you do, that also cuts off the menu (settings, pause, quit); launch the app again to bring the settings window to the front and show the icon again. + ### Coming from the formula The formula is replaced by the cask, so uninstall it first: diff --git a/docs/development.md b/docs/development.md index 814c121..06b49c1 100644 --- a/docs/development.md +++ b/docs/development.md @@ -55,6 +55,7 @@ cliip-show --config-show - `hud_emoji`(既定値: `📋`、任意の絵文字。空でアイコンなし) - `hud_image_max_height`(既定値: `160`、`40` - `240`)画像サムネイルの高さ上限(px)。実際の上限は `hud_scale` 倍され、元画像より大きくは表示しません - `language`(既定値: `auto`、`auto` / `ja` / `en`)メニューバーと設定ウィンドウの表示言語。`auto` は macOS の優先言語に従います +- `show_menu_bar_icon`(既定値: `true`)メニューバーアイコンの表示。`false` にすると、メニューから開く設定・一時停止・終了に触れなくなります。アプリをもう一度起動すると設定ウィンドウが前面に出るので、そこから表示に戻せます 設定キー(`[startup]` 節): - `start_at_login`(既定値: `false`)設定ウィンドウの「ログイン時に自動起動」と同じ値です。LaunchAgent の plist はこの値から書き出すため、plist を手で消してもこの値が残っていれば次の起動で書き直します @@ -72,6 +73,7 @@ CLIIP_SHOW_HUD_BACKGROUND_OPACITY=0.6 \ CLIIP_SHOW_HUD_EMOJI=🍣 \ CLIIP_SHOW_HUD_IMAGE_MAX_HEIGHT=120 \ CLIIP_SHOW_LANGUAGE=en \ +CLIIP_SHOW_SHOW_MENU_BAR_ICON=true \ cargo run ``` @@ -137,6 +139,7 @@ HUDと設定ウィンドウの各ペインの描画結果をPNGで比較しま - デフォルト設定での表示 - 設定プロファイルごとの表示(例: `max_lines=2`, `max_chars_per_line=24`) - 設定ウィンドウのペイン(設定・寄付 × 日本語・英語。タブバーはウィンドウのツールバー領域にあるため写りません) +- 設定タブの行スタック全体(`NSScrollView` の documentView。可視域でクリップされず全行が1枚に収まります。フッターのボタン列は documentView の外にあるため写りません) ### 生成物 diff --git a/scripts/visual_regression.sh b/scripts/visual_regression.sh index 8db41fc..6b51613 100755 --- a/scripts/visual_regression.sh +++ b/scripts/visual_regression.sh @@ -57,6 +57,7 @@ render_and_compare() { -u CLIIP_SHOW_HUD_IMAGE_MAX_HEIGHT -u CLIIP_SHOW_HUD_EMOJI -u CLIIP_SHOW_LANGUAGE + -u CLIIP_SHOW_SHOW_MENU_BAR_ICON "CLIIP_SHOW_CONFIG_PATH=$VRT_CONFIG_PATH" ) if [[ $# -gt 0 ]]; then @@ -143,8 +144,9 @@ run_image_case() { render_and_compare "$id" --render-hud-png --image-fixture "$size" "$@" } -# 設定ウィンドウのペイン(settings | support)。タブバーは contentView の外なので写らない。 -# 言語は必ず CLIIP_SHOW_LANGUAGE で固定して呼ぶこと(auto は実行マシンの言語に依存する) +# 設定ウィンドウのペイン(settings | settings-rows | support)。タブバーは contentView の外 +# なので写らない。言語は必ず CLIIP_SHOW_LANGUAGE で固定して呼ぶこと(auto は実行マシンの +# 言語に依存する) run_settings_case() { local id="$1" local pane="$2" @@ -365,6 +367,18 @@ run_settings_case \ "settings" \ "CLIIP_SHOW_LANGUAGE=en" +# Settings tab document view: full row stack (NSScrollView documentView), unclipped by the +# visible scroll area, so rows below the fold are captured too. +run_settings_case \ + "settings_rows_ja" \ + "settings-rows" \ + "CLIIP_SHOW_LANGUAGE=ja" + +run_settings_case \ + "settings_rows_en" \ + "settings-rows" \ + "CLIIP_SHOW_LANGUAGE=en" + run_settings_case \ "support_pane_ja" \ "support" \ diff --git a/src/app/config_reload.rs b/src/app/config_reload.rs index d1228cb..df63cb1 100644 --- a/src/app/config_reload.rs +++ b/src/app/config_reload.rs @@ -140,9 +140,26 @@ pub(crate) unsafe fn apply_settings_now(state: &mut AppState, new_settings: Disp super::schedule_poll_timer(state.delegate, new_settings.poll_interval_secs); } + let menu_bar_icon_changed = + new_settings.show_menu_bar_icon != state.settings.show_menu_bar_icon; let language_changed = new_settings.language != state.settings.language; state.settings = new_settings; + // show_menu_bar_icon が変わったら status item の表示と設定ウィンドウのトグルを即時更新。 + // 手編集・環境変数・GUI のトグル操作のいずれもここを通るため、更新箇所は一箇所で済む。 + if menu_bar_icon_changed { + crate::menu::apply_menu_bar_icon_visibility( + state.menu_handles.status.status_item, + state.settings.show_menu_bar_icon, + ); + crate::settings_window::sync_menu_bar_icon_toggle( + &state.settings_controls, + state.settings.show_menu_bar_icon, + ); + // draft は「保存」で丸ごと書き戻されるため、古い値で上書きしないようここでも揃える。 + state.settings_controls.draft.show_menu_bar_icon = state.settings.show_menu_bar_icon; + } + // language が変わったら設定ウィンドウとメニューの文言を即時更新。 // ファイル監視の再読み込みと設定ウィンドウの言語ポップアップのどちらの経路もここを // 通るため、更新箇所は一箇所で済む。 diff --git a/src/app/mod.rs b/src/app/mod.rs index 3365f4b..0833fc8 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -111,6 +111,10 @@ pub fn get_delegate_class() -> &'static AnyClass { sel!(toggleLoginItem:), toggle_login_item as extern "C" fn(_, _, _), ); + builder.add_method( + sel!(toggleMenuBarIcon:), + toggle_menu_bar_icon as extern "C" fn(_, _, _), + ); builder.add_method( sel!(showEmojiHelp:), show_emoji_help as extern "C" fn(_, _, _), @@ -155,6 +159,12 @@ extern "C" fn application_did_finish_launching(this: &AnyObject, _: Sel, _: *mut } let status_handles = crate::menu::create_status_item(this, lang); + // NSStatusItem.visible は AppKit 側が永続化するため、差分判定なしで毎回設定を当てる + // (前回の残骸で消えたままになるのを防ぐ)。 + crate::menu::apply_menu_bar_icon_visibility( + status_handles.status_item, + settings.show_menu_bar_icon, + ); let menu_handles = MenuHandles { status: status_handles, edit: edit_handles, @@ -302,8 +312,14 @@ extern "C" fn open_settings(this: &AnyObject, _: Sel, _: *mut AnyObject) { if state.settings_controls.window.is_null() { let lang = i18n::resolve(state.settings.language); - state.settings_controls = - crate::settings_window::build_settings_window(this, lang, state.start_at_login); + state.settings_controls = crate::settings_window::build_settings_window( + this, + lang, + crate::settings_window::InitialToggles { + start_at_login: state.start_at_login, + show_menu_bar_icon: state.settings.show_menu_bar_icon, + }, + ); } // 既に開いているウィンドウは前面に出すだけにする。他のインスタンスの起動でも @@ -413,6 +429,56 @@ fn persist_start_at_login(state: &mut AppState, value: bool) -> bool { true } +/// メニューバーアイコン表示トグルの `toggleMenuBarIcon:`。ログイン項目トグルと同じく下書きを +/// 経由せず、チェックした瞬間に設定ファイルへ保存し `apply_settings_now` で status item・ +/// 設定ウィンドウへ即時反映する。非表示にした場合だけ、復帰方法(アプリを再起動すると +/// 設定ウィンドウが開く)を知らせるダイアログを出す。 +extern "C" fn toggle_menu_bar_icon(_: &AnyObject, _: Sel, sender: *mut AnyObject) { + unsafe { + let hidden_dialog_lang = { + // AppKit メインスレッドからのみ呼ばれるため、Mutex が poison されるケースは実質発生しない + let mut guard = APP_STATE.lock().expect("APP_STATE lock poisoned"); + let Some(state) = guard.as_mut() else { + return; + }; + + let checked: isize = msg_send![sender, state]; + let desired = checked != 0; + let was_visible = state.settings.show_menu_bar_icon; + + match crate::settings_window::save_show_menu_bar_icon(state, desired) { + Ok(new_settings) => { + apply_settings_now(state, new_settings); + // 環境変数が show_menu_bar_icon を固定していると、設定ファイルへ保存しても + // 実効値は動かない。トグルの表示を実効値へ揃え、ダイアログも実際に + // アイコンが消えたときだけ出す。 + let visible = state.settings.show_menu_bar_icon; + crate::settings_window::sync_menu_bar_icon_toggle( + &state.settings_controls, + visible, + ); + (was_visible && !visible).then(|| i18n::resolve(state.settings.language)) + } + Err(error) => { + eprintln!("warning: {error}"); + // 失敗したのにチェックだけ付いた状態を避け、実際の状態に表示を戻す。 + crate::settings_window::sync_menu_bar_icon_toggle( + &state.settings_controls, + state.settings.show_menu_bar_icon, + ); + None + } + } + }; + + // runModal は実行ループを止めるため、APP_STATE のロックを手放した後に呼ぶ + // (prompt_login_item_if_needed と同じ理由)。 + if let Some(lang) = hidden_dialog_lang { + panels::prompt_menu_bar_icon_hidden(lang); + } + } +} + // NSRectEdge: maxX。ボタン/フィールドの右側に popover を出す(`show_emoji_help_popover`・ // `show_range_hint_popover` で共用)。 const NS_RECT_EDGE_MAX_X: usize = 2; @@ -831,6 +897,7 @@ mod tests { sel!(previewSettings:), sel!(saveSettings:), sel!(toggleLoginItem:), + sel!(toggleMenuBarIcon:), sel!(showEmojiHelp:), sel!(closeRangeHintPopover:), sel!(windowWillClose:), diff --git a/src/app/panels.rs b/src/app/panels.rs index f7743f7..9cd10ce 100644 --- a/src/app/panels.rs +++ b/src/app/panels.rs @@ -97,6 +97,33 @@ pub(super) unsafe fn prompt_login_item_if_needed(lang: Lang, start_at_login: boo } } +/// メニューバーのアイコンを非表示にした直後に出す、復帰方法の案内ダイアログ。 +/// ボタンは追加しない(NSAlert の既定である「OK」1つで足りる)。抑止チェックボックスも +/// 持たない。この経路は「今しがた非表示にした」操作の直後にしか出ないため、 +/// `prompt_login_item_if_needed` のように繰り返し表示を避ける仕組みは不要。 +/// +/// # Safety +/// - `APP_STATE` のロックを保持したまま呼ばないこと。`runModal` が実行ループを止めるため、 +/// 他の経路がロック待ちで固まる。 +/// - AppKit のメインスレッドから呼ぶこと。 +pub(super) unsafe fn prompt_menu_bar_icon_hidden(lang: Lang) { + // accessory アプリ(setActivationPolicy: 1)はこれを呼ばないとダイアログが前面に来ない + let app: *mut AnyObject = msg_send![class!(NSApplication), sharedApplication]; + let () = msg_send![app, activateIgnoringOtherApps: true]; + + let alert: *mut AnyObject = msg_send![class!(NSAlert), alloc]; + let alert: *mut AnyObject = msg_send![alert, init]; + + let message = NSString::from_str(i18n::text(lang, Msg::MenuBarIconHiddenMessage)); + let () = msg_send![alert, setMessageText: &*message]; + + let informative = NSString::from_str(i18n::text(lang, Msg::MenuBarIconHiddenDetail)); + let () = msg_send![alert, setInformativeText: &*informative]; + + let _: isize = msg_send![alert, runModal]; + let () = msg_send![alert, release]; +} + /// macOS 標準の About パネルを出す。バンドルを持たないので、表示内容は options で渡す。 pub(super) extern "C" fn show_about_panel(_: &AnyObject, _: Sel, _: *mut AnyObject) { unsafe { diff --git a/src/cli.rs b/src/cli.rs index 47dce21..21ed6cb 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -106,10 +106,12 @@ fn parse_settings_png_args(args: impl Iterator) -> Result SettingsPane::Settings, + "settings-rows" => SettingsPane::SettingsRows, "support" => SettingsPane::Support, unknown => { return Err(format!( - "Invalid value for --pane: {unknown} (expected settings or support)" + "Invalid value for --pane: {unknown} \ + (expected settings, settings-rows, or support)" )); } }); @@ -225,7 +227,7 @@ pub fn handle_cli_flags() -> bool { ); let _ = writeln!( help, - " --render-settings-png --pane --output Render settings window pane PNG and exit" + " --render-settings-png --pane --output Render settings window pane PNG and exit" ); let _ = writeln!( help, @@ -305,6 +307,10 @@ pub fn handle_cli_flags() -> bool { help, " CLIIP_SHOW_LANGUAGE UI language (auto|ja|en)" ); + let _ = writeln!( + help, + " CLIIP_SHOW_SHOW_MENU_BAR_ICON Show the menu bar icon (true|false)" + ); print!("{help}"); true } @@ -605,13 +611,21 @@ mod tests { .map(|parsed| parsed.pane), Ok(SettingsPane::Settings) ); + assert_eq!( + parse_settings_png_args(args(&["--pane", "settings-rows", "--output", "/tmp/s.png"])) + .map(|parsed| parsed.pane), + Ok(SettingsPane::SettingsRows) + ); } #[test] fn settings_args_reject_invalid_or_missing_options() { assert_eq!( parse_settings_png_args(args(&["--pane", "about", "--output", "/tmp/s.png"])), - Err("Invalid value for --pane: about (expected settings or support)".to_string()) + Err( + "Invalid value for --pane: about (expected settings, settings-rows, or support)" + .to_string() + ) ); assert_eq!( parse_settings_png_args(args(&["--output", "/tmp/s.png"])), diff --git a/src/config/parse.rs b/src/config/parse.rs index 05b9cf0..0fe79ce 100644 --- a/src/config/parse.rs +++ b/src/config/parse.rs @@ -48,6 +48,15 @@ pub fn parse_hud_background_color(raw: &str) -> Option { } } +/// `"true"`/`"false"`(前後空白は trim)以外は `None`。 +pub fn parse_bool(raw: &str) -> Option { + match raw.trim() { + "true" => Some(true), + "false" => Some(false), + _ => None, + } +} + pub fn parse_language(raw: &str) -> Option { let normalized = raw.trim().to_ascii_lowercase().replace('-', "_"); match normalized.as_str() { @@ -193,6 +202,10 @@ pub(crate) fn parse_language_setting(raw: &str, default: LanguageSetting) -> Lan parse_language(raw).unwrap_or(default) } +pub(crate) fn parse_bool_setting(raw: &str, default: bool) -> bool { + parse_bool(raw).unwrap_or(default) +} + pub fn set_config_value( config: &mut AppConfigFile, key: ConfigKey, @@ -335,18 +348,20 @@ pub fn set_config_value( ))); } } + ConfigKey::ShowMenuBarIcon => { + let raw = value.trim(); + let parsed = parse_bool(raw).ok_or_else(|| AppError::InvalidValue { + key: "show_menu_bar_icon", + message: format!("{raw} (allowed: true, false)"), + })?; + config.display.show_menu_bar_icon = Some(parsed); + } ConfigKey::StartAtLogin => { let raw = value.trim(); - let parsed = match raw { - "true" => true, - "false" => false, - _ => { - return Err(AppError::InvalidValue { - key: "start_at_login", - message: format!("{raw} (allowed: true, false)"), - }) - } - }; + let parsed = parse_bool(raw).ok_or_else(|| AppError::InvalidValue { + key: "start_at_login", + message: format!("{raw} (allowed: true, false)"), + })?; config.startup.start_at_login = Some(parsed); } } @@ -542,6 +557,16 @@ mod tests { assert_eq!(hud_emoji_validation_error("あ"), Some(Msg::EmojiNotEmoji)); } + #[test] + fn parse_bool_accepts_true_and_false_only() { + assert_eq!(parse_bool("true"), Some(true)); + assert_eq!(parse_bool("false"), Some(false)); + assert_eq!(parse_bool(" true "), Some(true)); + assert_eq!(parse_bool("True"), None); + assert_eq!(parse_bool("1"), None); + assert_eq!(parse_bool(""), None); + } + #[test] fn parse_language_accepts_valid_values() { assert_eq!(parse_language("auto"), Some(LanguageSetting::Auto)); @@ -564,6 +589,22 @@ mod tests { assert!(err.to_string().contains("language")); } + #[test] + fn set_config_value_accepts_show_menu_bar_icon() { + let mut config = AppConfigFile::default(); + let warning = + set_config_value(&mut config, ConfigKey::ShowMenuBarIcon, "false").expect("set value"); + assert_eq!(config.display.show_menu_bar_icon, Some(false)); + assert!(warning.is_none()); + + set_config_value(&mut config, ConfigKey::ShowMenuBarIcon, "true").expect("set value"); + assert_eq!(config.display.show_menu_bar_icon, Some(true)); + + let err = set_config_value(&mut config, ConfigKey::ShowMenuBarIcon, "maybe") + .expect_err("reject invalid value"); + assert!(err.to_string().contains("show_menu_bar_icon")); + } + #[test] fn set_config_value_accepts_start_at_login() { let mut config = AppConfigFile::default(); diff --git a/src/config/settings.rs b/src/config/settings.rs index a038535..407236d 100644 --- a/src/config/settings.rs +++ b/src/config/settings.rs @@ -1,8 +1,8 @@ use super::io::{config_file_path, load_config_file}; use super::parse::{ - parse_f64_config_value, parse_f64_setting, parse_hud_background_color_setting, parse_hud_emoji, - parse_hud_position_setting, parse_language_setting, parse_usize_config_value, - parse_usize_setting, + parse_bool_setting, parse_f64_config_value, parse_f64_setting, + parse_hud_background_color_setting, parse_hud_emoji, parse_hud_position_setting, + parse_language_setting, parse_usize_config_value, parse_usize_setting, }; use super::types::HudBackgroundColor; use super::types::{ @@ -33,6 +33,7 @@ pub fn default_display_settings() -> DisplaySettings { hud_emoji: "📋".to_string(), hud_image_max_height: DEFAULT_HUD_IMAGE_MAX_HEIGHT, language: LanguageSetting::default(), + show_menu_bar_icon: true, } } @@ -137,6 +138,9 @@ pub fn apply_config_file(base: DisplaySettings, config: &AppConfigFile) -> Displ if let Some(value) = config.display.language { settings.language = value; } + if let Some(value) = config.display.show_menu_bar_icon { + settings.show_menu_bar_icon = value; + } settings } @@ -226,6 +230,9 @@ fn apply_env_overrides_with( if let Some(value) = read_env_option("CLIIP_SHOW_LANGUAGE") { settings.language = parse_language_setting(&value, settings.language); } + if let Some(value) = read_env_option("CLIIP_SHOW_SHOW_MENU_BAR_ICON") { + settings.show_menu_bar_icon = parse_bool_setting(&value, settings.show_menu_bar_icon); + } settings } @@ -256,6 +263,7 @@ fn saved_value(config: &AppConfigFile, key: ConfigKey) -> Option { ConfigKey::HudEmoji => display.hud_emoji.clone(), ConfigKey::HudImageMaxHeight => display.hud_image_max_height.map(|v| v.to_string()), ConfigKey::Language => display.language.map(|v| v.as_str().to_string()), + ConfigKey::ShowMenuBarIcon => display.show_menu_bar_icon.map(|v| v.to_string()), ConfigKey::StartAtLogin => config.startup.start_at_login.map(|v| v.to_string()), } } @@ -282,6 +290,7 @@ pub fn print_effective_settings(settings: DisplaySettings, start_at_login: bool) println!("hud_emoji = {}", settings.hud_emoji); println!("hud_image_max_height = {}", settings.hud_image_max_height); println!("language = {}", settings.language.as_str()); + println!("show_menu_bar_icon = {}", settings.show_menu_bar_icon); println!("start_at_login = {start_at_login}"); } @@ -307,6 +316,7 @@ pub fn settings_to_config_file(settings: DisplaySettings) -> AppConfigFile { hud_emoji: Some(settings.hud_emoji.clone()), hud_image_max_height: Some(settings.hud_image_max_height), language: Some(settings.language), + show_menu_bar_icon: Some(settings.show_menu_bar_icon), }, // `DisplaySettings` は自動起動の値を持たないため、ここは常に未設定 // (`StartupConfigFile::default()`)。`Some(false)` を返すと、この関数の @@ -499,6 +509,7 @@ mod tests { ConfigKey::HudEmoji => "🍺", ConfigKey::HudImageMaxHeight => "80", ConfigKey::Language => "ja", + ConfigKey::ShowMenuBarIcon => "false", ConfigKey::StartAtLogin => continue, }; let env_name = format!("CLIIP_SHOW_{}", key.as_str().to_uppercase()); diff --git a/src/config/types.rs b/src/config/types.rs index cf026fa..08f86bb 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -77,6 +77,7 @@ pub struct DisplaySettings { pub hud_emoji: String, pub hud_image_max_height: usize, pub language: LanguageSetting, + pub show_menu_bar_icon: bool, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -101,6 +102,7 @@ pub struct DisplayConfigFile { pub hud_emoji: Option, pub hud_image_max_height: Option, pub language: Option, + pub show_menu_bar_icon: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -122,12 +124,13 @@ pub enum ConfigKey { HudEmoji, HudImageMaxHeight, Language, + ShowMenuBarIcon, StartAtLogin, } impl ConfigKey { /// 設定ファイルに並ぶ順。キーを網羅して回りたい箇所はここを使う。 - pub const ALL: [ConfigKey; 13] = [ + pub const ALL: [ConfigKey; 14] = [ ConfigKey::PollIntervalSecs, ConfigKey::HudDurationSecs, ConfigKey::HudFadeDurationSecs, @@ -140,6 +143,7 @@ impl ConfigKey { ConfigKey::HudEmoji, ConfigKey::HudImageMaxHeight, ConfigKey::Language, + ConfigKey::ShowMenuBarIcon, ConfigKey::StartAtLogin, ]; @@ -157,6 +161,7 @@ impl ConfigKey { ConfigKey::HudEmoji => "hud_emoji", ConfigKey::HudImageMaxHeight => "hud_image_max_height", ConfigKey::Language => "language", + ConfigKey::ShowMenuBarIcon => "show_menu_bar_icon", ConfigKey::StartAtLogin => "start_at_login", } } diff --git a/src/i18n.rs b/src/i18n.rs index d5baf70..983420c 100644 --- a/src/i18n.rs +++ b/src/i18n.rs @@ -45,10 +45,14 @@ pub enum Msg { LoginPromptLater, LoginPromptSuppress, + MenuBarIconHiddenMessage, + MenuBarIconHiddenDetail, + SettingsTitle, TabSettings, TabSupport, SettingsStartAtLogin, + SettingsShowMenuBarIcon, LabelPollInterval, LabelHudDuration, LabelHudFadeDuration, @@ -115,10 +119,20 @@ pub fn text(lang: Lang, msg: Msg) -> &'static str { Msg::LoginPromptLater => ("あとで", "Not Now"), Msg::LoginPromptSuppress => ("今後表示しない", "Don’t ask again"), + Msg::MenuBarIconHiddenMessage => ( + "メニューバーのアイコンを非表示にしました", + "The menu bar icon is now hidden", + ), + Msg::MenuBarIconHiddenDetail => ( + "Cliip Show をもう一度起動すると設定ウィンドウが開きます。アイコンはそこから表示に戻せます。", + "Launch Cliip Show again to open the settings window, where you can show the icon again.", + ), + Msg::SettingsTitle => ("Cliip Show 設定", "Cliip Show Settings"), Msg::TabSettings => ("設定", "Settings"), Msg::TabSupport => ("寄付", "Support"), Msg::SettingsStartAtLogin => ("ログイン時に自動起動", "Start at login"), + Msg::SettingsShowMenuBarIcon => ("メニューバーにアイコンを表示", "Show icon in menu bar"), Msg::LabelPollInterval => ("ポーリング間隔(秒)", "Polling interval (sec)"), Msg::LabelHudDuration => ("表示時間(秒)", "Display duration (sec)"), Msg::LabelHudFadeDuration => ("フェード時間(秒)", "Fade duration (sec)"), @@ -345,6 +359,7 @@ mod tests { Msg::MenuAbout, Msg::MenuQuit, Msg::LoginPromptMessage, + Msg::MenuBarIconHiddenDetail, Msg::SettingsTitle, Msg::SupportMessage, Msg::LaunchNotice, diff --git a/src/menu.rs b/src/menu.rs index 80db4a6..099db23 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -245,6 +245,16 @@ pub unsafe fn apply_paused_state( let () = msg_send![button, setAlphaValue: alpha]; } +/// メニューバー常駐アイコンの表示/非表示を切り替える。status item 自体は作り直さない +/// (設定ファイルを正とし、表示状態はその派生物という設計のため)。 +/// +/// # Safety +/// - `status_item` は `create_status_item` が返した有効なポインタであること。 +/// - AppKit のメインスレッドから呼ぶこと。 +pub unsafe fn apply_menu_bar_icon_visibility(status_item: *mut AnyObject, visible: bool) { + let () = msg_send![status_item, setVisible: visible]; +} + /// 言語切り替えで、メニューバー常駐アイコンのメニューとメインメニューの「編集」サブメニューの /// タイトルをすべて差し替える。 /// diff --git a/src/png.rs b/src/png.rs index 596f79c..19a53c2 100644 --- a/src/png.rs +++ b/src/png.rs @@ -102,6 +102,9 @@ pub fn render_hud_image_png( #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SettingsPane { Settings, + /// 設定タブの行スタック全体(`NSScrollView` の documentView)。可視域でクリップされず、 + /// スクロール位置に関わらず全行が1枚に収まる。 + SettingsRows, Support, } @@ -116,8 +119,14 @@ pub enum SettingsPane { /// - 実ウィンドウの背景(ここでは決定性のために不透明背景を合成しており、 /// 実アプリの背景まわりの退行はこのスナップショットでは検出できない) /// +/// `SettingsRows` は設定タブの行スタック全体(documentView)を撮る。`Settings` と違い +/// スクロール位置に関わらず全行が写るが、documentView の外にあるフッターのボタン列 +/// (「デフォルトに戻す」「お試し表示」「保存」)は写らない。 +/// /// 自動起動トグルは環境依存の値(LaunchAgent の有無・設定ファイルの内容)に触れず、 -/// ベースラインが環境非依存になるよう OFF 固定で渡す。 +/// ベースラインが環境非依存になるよう OFF 固定で渡す。メニューバーアイコン表示トグルは +/// `sync_controls_from_settings` が実効設定の値で上書きするため、渡す初期値自体は +/// 描画結果に影響しない。 pub fn render_settings_png(pane: SettingsPane, output_path: &str) -> Result<(), AppError> { unsafe { let _app: *mut AnyObject = msg_send![class!(NSApplication), sharedApplication]; @@ -126,7 +135,14 @@ pub fn render_settings_png(pane: SettingsPane, output_path: &str) -> Result<(), // アクションは一切発火させないので、AppState 未初期化の素の delegate でよい let delegate: *mut AnyObject = msg_send![crate::app::get_delegate_class(), new]; - let mut controls = crate::settings_window::build_settings_window(&*delegate, lang, false); + let mut controls = crate::settings_window::build_settings_window( + &*delegate, + lang, + crate::settings_window::InitialToggles { + start_at_login: false, + show_menu_bar_icon: true, + }, + ); if controls.window.is_null() { let () = msg_send![delegate, release]; return Err(AppError::RenderFailed( @@ -137,7 +153,9 @@ pub fn render_settings_png(pane: SettingsPane, output_path: &str) -> Result<(), crate::settings_window::sync_controls_from_settings(&mut controls, &settings); let tab_index: isize = match pane { - SettingsPane::Settings => crate::settings_window::TAB_INDEX_SETTINGS, + SettingsPane::Settings | SettingsPane::SettingsRows => { + crate::settings_window::TAB_INDEX_SETTINGS + } SettingsPane::Support => crate::settings_window::TAB_INDEX_SUPPORT, }; let tab_controller: *mut AnyObject = msg_send![controls.window, contentViewController]; @@ -157,20 +175,25 @@ pub fn render_settings_png(pane: SettingsPane, output_path: &str) -> Result<(), } let () = msg_send![controls.window, setAppearance: aqua]; - // contentView は透明で、ウィンドウ背景は contentView の外にあるため PNG に写らない。 - // ラベルの黒文字が読めるよう、不透明な明色を背景に敷く - let content_view: *mut AnyObject = msg_send![controls.window, contentView]; - let () = msg_send![content_view, setWantsLayer: true]; - let layer: *mut AnyObject = msg_send![content_view, layer]; + // 撮る view(ペインは contentView、行スタック全体は documentView)は透明で、実ウィンドウの + // 背景はその外にあるため PNG に写らない。ラベルの黒文字が読めるよう、不透明な明色を背景に敷く + let target_view: *mut AnyObject = match pane { + SettingsPane::SettingsRows => controls.document_view, + SettingsPane::Settings | SettingsPane::Support => { + msg_send![controls.window, contentView] + } + }; + let () = msg_send![target_view, setWantsLayer: true]; + let layer: *mut AnyObject = msg_send![target_view, layer]; let bg: *mut AnyObject = msg_send![class!(NSColor), colorWithCalibratedWhite: 0.93f64 alpha: 1.0f64]; let cg_color: *mut std::ffi::c_void = msg_send![bg, CGColor]; let () = msg_send![layer, setBackgroundColor: cg_color]; // ウィンドウを画面に出さないため、レイアウトを明示的に確定させる - let () = msg_send![content_view, layoutSubtreeIfNeeded]; + let () = msg_send![target_view, layoutSubtreeIfNeeded]; - let result = write_window_png(controls.window, output_path); + let result = write_view_png(controls.window, target_view, output_path); let () = msg_send![delegate, release]; result } @@ -294,7 +317,7 @@ unsafe fn draw_preview_sample_label(canvas_width: f64, canvas_height: f64) { let () = msg_send![shadow, release]; } -/// ウィンドウの contentView を PNG にして書き出す(HUD・設定ウィンドウ共用)。 +/// ウィンドウの contentView を PNG にして書き出す(HUD・設定ウィンドウのペイン撮影共用)。 /// /// # Safety /// - `window` は有効な NSWindow であること。呼び出し後にクローズされる。 @@ -308,7 +331,23 @@ unsafe fn write_window_png(window: *mut AnyObject, output_path: &str) -> Result< )); } - let bounds: NSRect = msg_send![content_view, bounds]; + write_view_png(window, content_view, output_path) +} + +/// 指定した `view` を PNG にして書き出し、`window` をクローズする。`write_window_png` の +/// 実装本体で、documentView など contentView 以外を撮る撮影(`render_settings_png` の +/// `SettingsRows`)とも共有する。 +/// +/// # Safety +/// - `window` は有効な NSWindow、`view` はその中の有効な NSView であること。 +/// 呼び出し後 `window` はクローズされる。 +/// - AppKit のメインスレッドから呼ぶこと。 +unsafe fn write_view_png( + window: *mut AnyObject, + view: *mut AnyObject, + output_path: &str, +) -> Result<(), AppError> { + let bounds: NSRect = msg_send![view, bounds]; let bitmap = match create_bitmap_rep_for_bounds(bounds) { Ok(b) => b, Err(e) => { @@ -317,7 +356,7 @@ unsafe fn write_window_png(window: *mut AnyObject, output_path: &str) -> Result< } }; - let () = msg_send![content_view, cacheDisplayInRect: bounds toBitmapImageRep: bitmap]; + let () = msg_send![view, cacheDisplayInRect: bounds toBitmapImageRep: bitmap]; let properties: *mut AnyObject = msg_send![class!(NSDictionary), dictionary]; let data: *mut AnyObject = msg_send![ bitmap, diff --git a/src/settings_window/build.rs b/src/settings_window/build.rs index e1226af..49431d0 100644 --- a/src/settings_window/build.rs +++ b/src/settings_window/build.rs @@ -16,12 +16,12 @@ use crate::i18n::{self, Lang, Msg}; use crate::objc_helpers::template_image_from_png; use super::rows::{ - add_button_row, add_divider_row, add_field_row, add_language_row, add_login_item_row, - add_popup_row, add_slider_row, add_stepper_row, document_height, make_button, make_label, + add_button_row, add_divider_row, add_field_row, add_language_row, add_popup_row, + add_slider_row, add_stepper_row, add_toggle_row, document_height, make_button, make_label, make_pane_view, make_range_hint_popover, make_scroll_view, SETTINGS_PANE_HEIGHT, SETTINGS_STYLE_MASK, SETTINGS_TOTAL_ROW_COUNT, SETTINGS_WINDOW_WIDTH, }; -use super::{LocalizedControl, LocalizedKind, SettingsControls}; +use super::{InitialToggles, LocalizedControl, LocalizedKind, SettingsControls}; const GEAR_TEMPLATE_PNG: &[u8] = include_bytes!("../../assets/gear-template.png"); const BEER_TEMPLATE_PNG: &[u8] = include_bytes!("../../assets/beer-template.png"); @@ -230,7 +230,7 @@ unsafe fn add_pane_tab( pub unsafe fn build_settings_window( delegate: &AnyObject, lang: Lang, - start_at_login: bool, + toggles: InitialToggles, ) -> SettingsControls { let placeholder = default_display_settings(); let mut localized: Vec = Vec::new(); @@ -404,7 +404,8 @@ pub unsafe fn build_settings_window( placeholder.hud_image_max_height, &mut localized, ); - // 区切りから下(言語・ログイン項目)は下書き→保存のモデルに乗らず、操作した瞬間に保存・反映する + // 区切りから下(言語・ログイン項目・メニューバーアイコン表示)は下書き→保存のモデルに + // 乗らず、操作した瞬間に保存・反映する add_divider_row(document_view, row.next()); let language_popup = add_language_row( document_view, @@ -414,12 +415,26 @@ pub unsafe fn build_settings_window( placeholder.language, &mut localized, ); - let login_item_toggle = add_login_item_row( + let login_item_toggle = add_toggle_row( document_view, delegate, row.next(), lang, - start_at_login, + Msg::SettingsStartAtLogin, + ConfigKey::StartAtLogin, + sel!(toggleLoginItem:), + toggles.start_at_login, + &mut localized, + ); + let show_menu_bar_icon_toggle = add_toggle_row( + document_view, + delegate, + row.next(), + lang, + Msg::SettingsShowMenuBarIcon, + ConfigKey::ShowMenuBarIcon, + sel!(toggleMenuBarIcon:), + toggles.show_menu_bar_icon, &mut localized, ); // 行数が定数からずれると document_height と row_bottom_y の前提が崩れ、行がはみ出す @@ -473,6 +488,7 @@ pub unsafe fn build_settings_window( SettingsControls { window, + document_view, poll_interval_slider, poll_interval_value_label, hud_duration_slider, @@ -500,6 +516,7 @@ pub unsafe fn build_settings_window( hud_emoji_shadow: placeholder.hud_emoji.clone(), language_popup, login_item_toggle, + show_menu_bar_icon_toggle, draft: placeholder, preview_sample_index: 0, localized, diff --git a/src/settings_window/mod.rs b/src/settings_window/mod.rs index 10e807f..6c37b9b 100644 --- a/src/settings_window/mod.rs +++ b/src/settings_window/mod.rs @@ -16,7 +16,8 @@ pub use build::build_settings_window; pub(crate) use build::{TAB_INDEX_SETTINGS, TAB_INDEX_SUPPORT}; pub use sync::{ apply_language, apply_setting_change, handle_text_change, preview_settings, reset_settings, - save_settings, sync_controls_from_settings, sync_language_popup, sync_login_item_toggle, + save_settings, save_show_menu_bar_icon, sync_controls_from_settings, sync_language_popup, + sync_login_item_toggle, sync_menu_bar_icon_toggle, }; /// 言語切り替えで表示テキストを差し替える対象コントロール。 @@ -46,10 +47,21 @@ pub struct RangeHint { /// popover 本文(言語・接頭辞込みで解決済み)。 pub text: String, } + +/// `build_settings_window` へ渡す、下書きモデルの対象外なトグル行の初期表示値。 +/// bool を並べて渡すと引数の取り違えでもコンパイルが通ってしまうため、 +/// 意味のある名前を持つ struct にまとめる。 +pub struct InitialToggles { + pub start_at_login: bool, + pub show_menu_bar_icon: bool, +} /// 設定ウィンドウを構成するコントロールへのポインタ。`AppState` に保持し、 /// `openSettings:` で使い回す(ウィンドウは初回だけ生成する)。 pub struct SettingsControls { pub window: *mut AnyObject, + /// 行スタック全体(`NSScrollView` の documentView)。VRT が可視域の外の行まで撮るために持つ + /// (`render_settings_png` の `SettingsRows`)。 + pub document_view: *mut AnyObject, pub poll_interval_slider: *mut AnyObject, pub poll_interval_value_label: *mut AnyObject, pub hud_duration_slider: *mut AnyObject, @@ -98,12 +110,16 @@ pub struct SettingsControls { /// 設定ファイルへ保存し、`login_item::enable`/`disable` で plist をそれに合わせる /// (`toggleLoginItem:`)。 pub login_item_toggle: *mut AnyObject, + /// メニューバーアイコン表示のトグル。下書き→保存のモデルには乗らず、チェックした瞬間に + /// 設定ファイルへ保存し、`menu::apply_menu_bar_icon_visibility` で status item をそれに + /// 合わせる(`toggleMenuBarIcon:`)。 + pub show_menu_bar_icon_toggle: *mut AnyObject, /// ウィンドウ内で編集中の下書き。「保存」(`saveSettings:`)を押すまで設定ファイルには /// 反映しない。`settingChanged:` はこの下書きだけを更新する。 /// - /// `language` はこの下書きの対象外だが、フィールド自体は `DisplaySettings` の一部として - /// 常に持つ。「保存」時に古い言語で上書きしないよう、言語が変わるたびに - /// `apply_settings_now`/`reset_settings` の側でここも一緒に同期すること。 + /// `language`・`show_menu_bar_icon` はこの下書きの対象外だが、フィールド自体は + /// `DisplaySettings` の一部として常に持つ。「保存」時に古い値で上書きしないよう、 + /// 値が変わるたびに `apply_settings_now`/`reset_settings` の側でここも一緒に同期すること。 pub draft: DisplaySettings, /// 「お試し表示」を押すたびに進める、次に表示するサンプルの番号(`PREVIEW_SAMPLES` を巡回)。 pub preview_sample_index: usize, @@ -118,6 +134,7 @@ impl Default for SettingsControls { hud_emoji_shadow: draft.hud_emoji.clone(), draft, window: ptr::null_mut(), + document_view: ptr::null_mut(), poll_interval_slider: ptr::null_mut(), poll_interval_value_label: ptr::null_mut(), hud_duration_slider: ptr::null_mut(), @@ -144,6 +161,7 @@ impl Default for SettingsControls { range_hint_close_timer: ptr::null_mut(), language_popup: ptr::null_mut(), login_item_toggle: ptr::null_mut(), + show_menu_bar_icon_toggle: ptr::null_mut(), preview_sample_index: 0, localized: Vec::new(), } @@ -165,6 +183,7 @@ pub fn config_key_to_tag(key: ConfigKey) -> isize { ConfigKey::Language => 10, ConfigKey::HudBackgroundOpacity => 11, ConfigKey::StartAtLogin => 12, + ConfigKey::ShowMenuBarIcon => 13, } } @@ -183,6 +202,7 @@ pub fn tag_to_config_key(tag: isize) -> Option { 10 => Some(ConfigKey::Language), 11 => Some(ConfigKey::HudBackgroundOpacity), 12 => Some(ConfigKey::StartAtLogin), + 13 => Some(ConfigKey::ShowMenuBarIcon), _ => None, } } @@ -202,7 +222,7 @@ mod tests { #[test] fn tag_to_config_key_rejects_unknown_tags() { assert_eq!(tag_to_config_key(-1), None); - assert_eq!(tag_to_config_key(13), None); + assert_eq!(tag_to_config_key(14), None); assert_eq!(tag_to_config_key(9999), None); } } diff --git a/src/settings_window/rows.rs b/src/settings_window/rows.rs index 764ecbb..4900a57 100644 --- a/src/settings_window/rows.rs +++ b/src/settings_window/rows.rs @@ -18,9 +18,9 @@ pub(super) const SETTINGS_STYLE_MASK: usize = 1 | 2; pub(super) const SETTINGS_WINDOW_WIDTH: f64 = 520.0; const SETTINGS_ROW_HEIGHT: f64 = 34.0; const SETTINGS_ROW_COUNT: usize = 11; -// HUD の見た目を決める上記 11 行とは別に、区切り行・言語・ログイン項目の 3 行を末尾に置く。 -// 各行の番号は build_settings_window が出現順に払い出す。 -pub(super) const SETTINGS_TOTAL_ROW_COUNT: usize = SETTINGS_ROW_COUNT + 3; +// HUD の見た目を決める上記 11 行とは別に、区切り行・言語・自動起動・メニューバーアイコン +// 表示の 4 行を末尾に置く。各行の番号は build_settings_window が出現順に払い出す。 +pub(super) const SETTINGS_TOTAL_ROW_COUNT: usize = SETTINGS_ROW_COUNT + 4; const SETTINGS_TOP_MARGIN: f64 = 20.0; const SETTINGS_BOTTOM_MARGIN: f64 = 20.0; // ウィンドウ下部、行の並びとは別に「デフォルトに戻す」「お試し表示」「保存」ボタンを置くための領域 @@ -879,13 +879,19 @@ pub(super) unsafe fn add_divider_row(document_view: *mut AnyObject, index: usize let () = msg_send![document_view, addSubview: divider]; } -/// ログイン時の自動起動の行。`enabled` は表示専用の初期値で、 -/// 実際の値はウィンドウを開くたびに `sync_login_item_toggle` が上書きする。 -pub(super) unsafe fn add_login_item_row( +/// NSSwitch トグル行の組み立て。下書きモデルの対象外で、操作した瞬間に専用アクションへ +/// 保存・反映が飛ぶ設定行(自動起動・メニューバーアイコン表示)はどちらもこの形。 +/// `enabled` は表示専用の初期値で、実際の値はウィンドウを開くたびに呼び出し側の +/// `sync_login_item_toggle`/`sync_menu_bar_icon_toggle` が上書きする。 +#[allow(clippy::too_many_arguments)] +pub(super) unsafe fn add_toggle_row( document_view: *mut AnyObject, delegate: &AnyObject, index: usize, lang: Lang, + label_msg: Msg, + key: ConfigKey, + action: Sel, enabled: bool, localized: &mut Vec, ) -> *mut AnyObject { @@ -896,7 +902,7 @@ pub(super) unsafe fn add_login_item_row( SETTINGS_LABEL_HEIGHT, row_bottom, ); - let label = make_label(i18n::text(lang, Msg::SettingsStartAtLogin), label_rect); + let label = make_label(i18n::text(lang, label_msg), label_rect); let toggle: *mut AnyObject = msg_send![class!(NSSwitch), alloc]; let toggle: *mut AnyObject = msg_send![toggle, init]; let () = msg_send![toggle, setControlSize: NS_CONTROL_SIZE_SMALL]; @@ -910,24 +916,24 @@ pub(super) unsafe fn add_login_item_row( row_bottom, ); let () = msg_send![toggle, setFrame: toggle_rect]; - let () = msg_send![toggle, setState: login_item_control_state(enabled)]; - let () = msg_send![toggle, setTag: config_key_to_tag(ConfigKey::StartAtLogin)]; + let () = msg_send![toggle, setState: toggle_control_state(enabled)]; + let () = msg_send![toggle, setTag: config_key_to_tag(key)]; let () = msg_send![toggle, setTarget: delegate]; - let () = msg_send![toggle, setAction: sel!(toggleLoginItem:)]; + let () = msg_send![toggle, setAction: action]; let () = msg_send![document_view, addSubview: label]; let () = msg_send![document_view, addSubview: toggle]; localized.push(LocalizedControl { control: label, - msg: Msg::SettingsStartAtLogin, + msg: label_msg, kind: LocalizedKind::StringValue, }); toggle } -pub(super) fn login_item_control_state(enabled: bool) -> isize { +fn toggle_control_state(enabled: bool) -> isize { if enabled { NS_CONTROL_STATE_VALUE_ON } else { @@ -935,6 +941,18 @@ pub(super) fn login_item_control_state(enabled: bool) -> isize { } } +/// トグル行のスイッチの表示を合わせる。設定ウィンドウを一度も開いていないとコントロールは +/// null で、ファイル監視の再読み込みはその状態でもここへ来る(`select_language_item` と同じ)。 +/// +/// # Safety +/// AppKit のメインスレッドから呼ぶこと。 +pub(super) unsafe fn set_toggle_state(toggle: *mut AnyObject, enabled: bool) { + if toggle.is_null() { + return; + } + let () = msg_send![toggle, setState: toggle_control_state(enabled)]; +} + /// タブ 1 枚分のビュー。余白クリックでテキストフィールドの編集を確定させる動きを /// タブごとに保つため、どのペインも `background_view_class` で作る。 pub(super) unsafe fn make_pane_view(height: f64) -> *mut AnyObject { @@ -1088,7 +1106,7 @@ mod tests { // 下の行を見せる(ウィンドウは伸ばさない)。 #[test] fn document_height_exceeds_scroll_height() { - assert_eq!(document_height(), 496.0); + assert_eq!(document_height(), 530.0); assert!(document_height() > SETTINGS_SCROLL_HEIGHT); } @@ -1096,7 +1114,7 @@ mod tests { // 起きるとここで落ちる #[test] fn row_bottom_y_pins_the_first_row() { - assert_eq!(row_bottom_y(0), 442.0); + assert_eq!(row_bottom_y(0), 476.0); } // 最終行はちょうど documentView の下端に載る(負なら下へはみ出して見えなくなる) diff --git a/src/settings_window/sync.rs b/src/settings_window/sync.rs index 4098cbc..1c89ea1 100644 --- a/src/settings_window/sync.rs +++ b/src/settings_window/sync.rs @@ -18,8 +18,8 @@ use crate::png::create_preview_sample_image; use super::input_filter::filter_digits; use super::range_hint::range_hint_text; use super::rows::{ - login_item_control_state, resize_help_popover_to_fit_label, select_language_item, - select_popup_item, set_string_value, + resize_help_popover_to_fit_label, select_language_item, select_popup_item, set_string_value, + set_toggle_state, }; use super::tooltip::tooltip_text; use super::{tag_to_config_key, LocalizedKind, RangeHint, SettingsControls}; @@ -151,6 +151,7 @@ pub unsafe fn sync_controls_from_settings( settings.hud_background_color.as_str(), ); select_language_item(controls.language_popup, settings.language); + sync_menu_bar_icon_toggle(controls, settings.show_menu_bar_icon); set_emoji_field(controls, &settings.hud_emoji); } @@ -162,8 +163,17 @@ pub unsafe fn sync_controls_from_settings( /// # Safety /// AppKit のメインスレッドから呼ぶこと。 pub unsafe fn sync_login_item_toggle(controls: &SettingsControls, start_at_login: bool) { - let state = login_item_control_state(start_at_login); - let () = msg_send![controls.login_item_toggle, setState: state]; + set_toggle_state(controls.login_item_toggle, start_at_login); +} + +/// メニューバーアイコン表示トグルの表示を `show_menu_bar_icon` に合わせる。下書きモデルの +/// 対象外のため、`sync_controls_from_settings`・ファイル監視の再読み込み・ +/// `toggleMenuBarIcon:` が保存に失敗したときの巻き戻しの各経路から呼ぶ。 +/// +/// # Safety +/// AppKit のメインスレッドから呼ぶこと。 +pub unsafe fn sync_menu_bar_icon_toggle(controls: &SettingsControls, show_menu_bar_icon: bool) { + set_toggle_state(controls.show_menu_bar_icon_toggle, show_menu_bar_icon); } /// 言語ポップアップの選択を、いま効いている設定値に合わせる。 @@ -509,6 +519,37 @@ unsafe fn save_language_setting( crate::app::display_settings_from_file(&path).map_err(|error| error.to_string()) } +/// メニューバーアイコン表示の設定を保存し、保存後のファイル内容から `DisplaySettings` を +/// 組み直す。`show_menu_bar_icon` だけ差し替えると、外部エディタでの変更を取り込まないまま +/// `config_mtime` だけ進み、ファイル監視がその変更を二度と拾わなくなるため、 +/// `display_settings_from_file` でファイルから組み直す。`toggleMenuBarIcon:` から呼ぶ。 +/// +/// # Safety +/// - `APP_STATE` をロックしないこと(呼び出し側が既にロックを保持している)。 +/// - AppKit のメインスレッドから呼ぶこと。 +pub unsafe fn save_show_menu_bar_icon( + state: &mut AppState, + value: bool, +) -> Result { + let Some(path) = state.config_path.clone() else { + return Err( + "config path is not resolved; cannot save show_menu_bar_icon setting".to_string(), + ); + }; + let (mut config, _) = load_config_file(&path).map_err(|error| error.to_string())?; + let start_at_login = start_at_login_from_config(&config); + let raw = if value { "true" } else { "false" }; + set_config_value(&mut config, ConfigKey::ShowMenuBarIcon, raw) + .map_err(|error| error.to_string())?; + save_config_file(&path, &config).map_err(|error| error.to_string())?; + state.config_mtime = std::fs::metadata(&path) + .ok() + .and_then(|m| m.modified().ok()); + apply_start_at_login_if_changed(state, start_at_login); + + crate::app::display_settings_from_file(&path).map_err(|error| error.to_string()) +} + /// 言語切り替えで、設定ウィンドウ内の静的なラベル・タイトル・ツールチップをすべて差し替える。 /// /// `APP_STATE` のロックを保持したまま呼んでよい: `NSTextField` ラベル・`NSButton`/`NSWindow` @@ -558,15 +599,17 @@ pub unsafe fn apply_language(controls: &SettingsControls, lang: Lang) { } /// 下書きを既定値に戻し、コントロール表示を同期する。保存も HUD への適用もしない。 -/// 言語は下書きモデルの対象外のため、既定値へは戻さず現在値を保つ。 +/// 言語・メニューバーアイコン表示は下書きモデルの対象外のため、既定値へは戻さず現在値を保つ。 /// /// # Safety /// - `APP_STATE` をロックしないこと(呼び出し側が既にロックを保持している)。 /// - AppKit のメインスレッドから呼ぶこと。 pub unsafe fn reset_settings(state: &mut AppState) { let language = state.settings_controls.draft.language; + let show_menu_bar_icon = state.settings_controls.draft.show_menu_bar_icon; state.settings_controls.draft = default_display_settings(); state.settings_controls.draft.language = language; + state.settings_controls.draft.show_menu_bar_icon = show_menu_bar_icon; let draft = state.settings_controls.draft.clone(); sync_controls_from_settings(&mut state.settings_controls, &draft); } @@ -703,6 +746,7 @@ fn control_for_key(controls: &SettingsControls, key: ConfigKey) -> *mut AnyObjec ConfigKey::HudBackgroundOpacity => controls.hud_background_opacity_slider, ConfigKey::HudEmoji => controls.hud_emoji_field, ConfigKey::Language => controls.language_popup, + ConfigKey::ShowMenuBarIcon => controls.show_menu_bar_icon_toggle, ConfigKey::StartAtLogin => controls.login_item_toggle, } } @@ -736,6 +780,8 @@ unsafe fn raw_value_for_key(key: ConfigKey, control: *mut AnyObject) -> Option None, + // メニューバーアイコン表示トグルも専用の toggleMenuBarIcon: を持ち、同じ理由で対象外 + ConfigKey::ShowMenuBarIcon => None, } } @@ -799,6 +845,9 @@ unsafe fn resync_controls_after_apply( // 自動起動も下書きモデルの対象外(専用の toggleLoginItem: が設定ファイルへ保存し、 // plist はその派生物として合わせる)。 ConfigKey::StartAtLogin => {} + // メニューバーアイコン表示も下書きモデルの対象外(専用の toggleMenuBarIcon: が + // 設定ファイルへ保存し、status item の表示はその派生物として合わせる)。 + ConfigKey::ShowMenuBarIcon => {} } } @@ -818,4 +867,15 @@ mod tests { assert!(class!(NSTextView).responds_to(sel!(string))); assert!(class!(NSString).responds_to(sel!(length))); } + + /// 設定ウィンドウを一度も開いていないとトグルのコントロールは null。設定ファイルの + /// 手編集はその状態でもトグルの同期まで来るため、null へ `setState:` を送らないこと。 + #[test] + fn syncing_toggles_without_a_settings_window_does_not_message_nil() { + let controls = super::SettingsControls::default(); + unsafe { + super::sync_login_item_toggle(&controls, true); + super::sync_menu_bar_icon_toggle(&controls, false); + } + } } diff --git a/tests/visual/baseline/settings_rows_en.png b/tests/visual/baseline/settings_rows_en.png new file mode 100644 index 0000000000000000000000000000000000000000..71bfe956c46a71f6e71843c9abf0803466f3c395 GIT binary patch literal 44981 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