Release v4.3: speak status line (Tolk) + Logging tab with housekeeping
- New screen-reader hotkey "Speak the RemSound status information" (issue #13): reads the status line aloud through the active screen reader via Tolk, fires from anywhere (system-wide), unset by default. Built behind an IScreenReaderOutput seam so a future build can swap Tolk for Prism on Windows 10+ without touching callers. Tolk DLLs vendored under tolk/ and shipped next to the exe. - New Logging tab in Preferences: Enable logs + Write logs now moved there, plus opt-in startup "warn if logs folder exceeds N MB" and "delete logs older than N days", and a "Delete all logs" button (Yes/No confirm). New LogMaintenance helper + AppConfig settings drive it. - Manual (readme.html + regenerated MANUAL.md), About changelog and RELEASE_NOTES updated in plain English; csproj <Version> bumped to 4.3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
034a7de632
commit
fd5c31740a
@@ -128,6 +128,25 @@ public sealed class AppConfig
|
||||
/// ticks <em>Enable logs</em> in the Preferences dialog.</summary>
|
||||
public bool LoggingEnabled { get; set; }
|
||||
|
||||
/// <summary>If true, RemSound checks the total size of the <c>logs\</c> folder at startup and,
|
||||
/// when it exceeds <see cref="LogsFolderWarnThresholdMb"/> megabytes, shows a one-time warning so
|
||||
/// the user can prune or clear it. Off by default (opt-in, like the other behaviour toggles).
|
||||
/// Machine-local — a "watch my disk on this box" decision, not a per-profile audio setting.</summary>
|
||||
public bool WarnIfLogsFolderExceeds { get; set; }
|
||||
|
||||
/// <summary>The size threshold in megabytes for <see cref="WarnIfLogsFolderExceeds"/>. Default
|
||||
/// 100 MB. Only consulted when that flag is on.</summary>
|
||||
public int LogsFolderWarnThresholdMb { get; set; } = 100;
|
||||
|
||||
/// <summary>If true, RemSound deletes log files older than <see cref="PruneOldLogsDays"/> days
|
||||
/// from the <c>logs\</c> folder at startup. Off by default (opt-in). The currently-open log file
|
||||
/// is never a candidate (it's today's). Machine-local.</summary>
|
||||
public bool PruneOldLogs { get; set; }
|
||||
|
||||
/// <summary>Age in days for <see cref="PruneOldLogs"/>: log files last written more than this many
|
||||
/// days ago are deleted at startup. Range 1–30, default 14. Only consulted when that flag is on.</summary>
|
||||
public int PruneOldLogsDays { get; set; } = 14;
|
||||
|
||||
/// <summary>If non-null and a profile with this title exists, RemSound skips the
|
||||
/// startup profile picker and loads this profile directly. Combine with
|
||||
/// <see cref="StartMinimised"/> + the Windows auto-start registry entry
|
||||
|
||||
@@ -212,6 +212,9 @@ public sealed class Profile
|
||||
/// <summary>Global hotkey that opens the Quick profile switch popup — a list of all profiles you
|
||||
/// can arrow through and press Enter to switch to, from anywhere in Windows. Unset by default.</summary>
|
||||
public HotkeyRecord? QuickProfileSwitchHotkey { get; set; }
|
||||
/// <summary>Optional global hotkey that speaks the connection status line aloud through the active
|
||||
/// screen reader (issue #13). Unset by default. Screen-reader specific.</summary>
|
||||
public HotkeyRecord? SpeakStatusLineHotkey { get; set; }
|
||||
/// <summary>When true, this machine honours incoming Control packets from connected
|
||||
/// peers — adjusts the local volume slider or toggles mute. Default false: receiving
|
||||
/// remote control is opt-in even though the audio allow-list already gates who's
|
||||
|
||||
@@ -144,6 +144,16 @@ public sealed class RemSoundSettingsStore
|
||||
Save(s);
|
||||
}
|
||||
|
||||
public HotkeyInfo LoadSpeakStatusLineHotkey() =>
|
||||
Try(() => Load()?.SpeakStatusLineHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
|
||||
|
||||
public void SaveSpeakStatusLineHotkey(HotkeyInfo hotkey)
|
||||
{
|
||||
var s = Load() ?? new Settings();
|
||||
s.SpeakStatusLineHotkey = HotkeySetting.From(hotkey);
|
||||
Save(s);
|
||||
}
|
||||
|
||||
public bool LoadAcceptRemoteVolumeCommands(bool defaultValue = false) =>
|
||||
Try(() => Load()?.AcceptRemoteVolumeCommands) ?? defaultValue;
|
||||
|
||||
@@ -593,6 +603,7 @@ public sealed class RemSoundSettingsStore
|
||||
SystemVolumeDownHotkey = profile.SystemVolumeDownHotkey is null ? null : HotkeySettingFromRecord(profile.SystemVolumeDownHotkey),
|
||||
SystemMuteToggleHotkey = profile.SystemMuteToggleHotkey is null ? null : HotkeySettingFromRecord(profile.SystemMuteToggleHotkey),
|
||||
QuickProfileSwitchHotkey = profile.QuickProfileSwitchHotkey is null ? null : HotkeySettingFromRecord(profile.QuickProfileSwitchHotkey),
|
||||
SpeakStatusLineHotkey = profile.SpeakStatusLineHotkey is null ? null : HotkeySettingFromRecord(profile.SpeakStatusLineHotkey),
|
||||
AcceptRemoteVolumeCommands = profile.AcceptRemoteVolumeCommands,
|
||||
MaxLatencyMs = profile.MaxLatencyMs,
|
||||
Codec = profile.Codec,
|
||||
@@ -649,6 +660,7 @@ public sealed class RemSoundSettingsStore
|
||||
profile.SystemVolumeDownHotkey = s.SystemVolumeDownHotkey is null ? null : HotkeyRecordFromSetting(s.SystemVolumeDownHotkey);
|
||||
profile.SystemMuteToggleHotkey = s.SystemMuteToggleHotkey is null ? null : HotkeyRecordFromSetting(s.SystemMuteToggleHotkey);
|
||||
profile.QuickProfileSwitchHotkey = s.QuickProfileSwitchHotkey is null ? null : HotkeyRecordFromSetting(s.QuickProfileSwitchHotkey);
|
||||
profile.SpeakStatusLineHotkey = s.SpeakStatusLineHotkey is null ? null : HotkeyRecordFromSetting(s.SpeakStatusLineHotkey);
|
||||
if (s.AcceptRemoteVolumeCommands is bool arvc) profile.AcceptRemoteVolumeCommands = arvc;
|
||||
if (s.MaxLatencyMs is int ml) profile.MaxLatencyMs = ml;
|
||||
if (s.Codec is AudioTransportCodec c) profile.Codec = c;
|
||||
@@ -716,6 +728,7 @@ public sealed class RemSoundSettingsStore
|
||||
public HotkeySetting? SystemVolumeDownHotkey { get; set; }
|
||||
public HotkeySetting? SystemMuteToggleHotkey { get; set; }
|
||||
public HotkeySetting? QuickProfileSwitchHotkey { get; set; }
|
||||
public HotkeySetting? SpeakStatusLineHotkey { get; set; }
|
||||
public bool? AcceptRemoteVolumeCommands { get; set; }
|
||||
public int? MaxLatencyMs { get; set; }
|
||||
public AudioTransportCodec? Codec { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user