Release v4.4: keyboard shortcuts are now machine-wide, not per-profile

Fixes issue #14: shortcuts were stored on each Profile, so one set on profile A
didn't apply on profile B and seemed to vanish on switch. They now live in
AppConfig (one set shared by every profile). RemSoundSettingsStore's Load*/Save*
hotkey methods re-point to AppConfig (callers unchanged); the per-profile cache
fields, profile load/save plumbing, and the HotkeySetting helper class are removed.
Profile's HotkeyRecord fields stay only for back-compat deserialization.

On upgrade, shortcuts reset to defaults (there's no single correct set to carry over
since profiles could hold different/partial sets). A one-time startup notice tells
upgraders to re-set them; fresh installs are silently marked done (nothing to reset).

Manual, About changelog and RELEASE_NOTES updated; csproj <Version> 4.4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-06-19 23:11:53 +01:00
co-authored by Claude Opus 4.8
parent 32be3426e7
commit 8a1bc0c813
8 changed files with 153 additions and 199 deletions
+14
View File
@@ -20,6 +20,20 @@ internal sealed class AboutDialog : Form
/// updates" path.</summary>
private const string ReleaseNotes =
"""
RemSound v4.4
Keyboard shortcuts are now shared across all
your profiles, instead of being saved separately
in each one. Set a shortcut once and it works on
every profile, and stays put when you switch
which is what people asked for.
Because of this change, your shortcuts have gone
back to their defaults. If you'd set up any of
your own, please set them again in Options
Keyboard shortcuts (Ctrl+K). You only need to do
this once.
RemSound v4.3.1
A gentler update sound. The cue that plays when
+51
View File
@@ -1380,6 +1380,8 @@ public sealed class MainForm : Form
/// </summary>
private void RunStartupNotices()
{
if (IsDisposed) return;
MaybeShowKeyboardShortcutsGlobalNotice();
if (IsDisposed) return;
MaybeShowWhatsNewAfterUpdate();
if (IsDisposed) return;
@@ -1431,6 +1433,55 @@ public sealed class MainForm : Form
}
}
/// <summary>One-time notice (v4.4) telling upgraders that keyboard shortcuts have moved from
/// per-profile to machine-wide storage (issue #14), so their shortcuts have reset to defaults and
/// need re-setting. Shown once to anyone who ran an earlier version; on a brand-new install (which
/// has nothing to reset) it's silently marked done and never shown. Must run BEFORE
/// <see cref="MaybeShowWhatsNewAfterUpdate"/>, which overwrites the LastWhatsNewVersion we read to
/// tell upgraders apart from fresh installs.</summary>
private void MaybeShowKeyboardShortcutsGlobalNotice()
{
if (IsDisposed) return;
AppConfig cfg;
try { cfg = AppConfig.Load(); }
catch { return; }
if (cfg.KeyboardShortcutsGlobalNoticeShown) return;
// A non-empty LastWhatsNewVersion means a previous version has run on this machine — i.e. this
// is an upgrade, so there were per-profile shortcuts that have now reset. A fresh install has it
// empty (it's set later, by MaybeShowWhatsNewAfterUpdate) and has nothing to reset.
var isUpgrade = !string.IsNullOrEmpty(cfg.LastWhatsNewVersion);
if (isUpgrade)
{
logFile.Event("keyboard shortcuts: showing one-time 'now shared across profiles' notice");
var page = new TaskDialogPage
{
Caption = "RemSound",
Heading = "Your keyboard shortcuts are now shared across profiles",
Text = "Keyboard shortcuts used to be saved separately for each profile, so a shortcut you set on one "
+ "profile wouldn't work on another. From this version they're shared across all your profiles "
+ "instead — one set for the whole app, which our users have requested.\n\n"
+ "Because of this change, your shortcuts have started fresh at their defaults. If you'd set up any "
+ "shortcuts of your own, please set them again in Options → Keyboard shortcuts (Ctrl+K). You only "
+ "need to do this once — from now on they'll stay put whatever profile you're on.",
Icon = TaskDialogIcon.Information,
Buttons = { TaskDialogButton.OK },
AllowCancel = true,
};
try { ForegroundDialog.Show(owner => TaskDialog.ShowDialog(owner, page)); }
catch (Exception ex) { logFile.Event($"keyboard shortcuts notice failed: {ex.GetType().Name}: {ex.Message}"); }
}
// Mark done either way (shown to upgraders, silently to fresh installs) so it's strictly one-time.
try
{
var fresh = AppConfig.Load();
fresh.KeyboardShortcutsGlobalNoticeShown = true;
fresh.Save();
}
catch { /* harmless — at worst the notice shows again next launch */ }
}
/// <summary>If the user opted in (<see cref="AppConfig.ShowWhatsNewAfterUpdate"/>) and the
/// running version changed since the last launch we recorded, open the About box once so
/// they see what changed in the update just installed. Always records the current version
+1 -1
View File
@@ -14,7 +14,7 @@
tag_name on the latest GitHub release; bump it on every public release. The
AssemblyVersion / FileVersion default to this value, and Assembly.GetName().Version
is what the About dialog and the updater both read. -->
<Version>4.3.1</Version>
<Version>4.4</Version>
</PropertyGroup>
<ItemGroup>
+26
View File
@@ -147,6 +147,32 @@ public sealed class AppConfig
/// days ago are deleted at startup. Range 130, default 14. Only consulted when that flag is on.</summary>
public int PruneOldLogsDays { get; set; } = 14;
/// <summary>The keyboard shortcuts, machine-wide as of v4.4. Before v4.4 these lived on each
/// <see cref="Profile"/>, so a shortcut set on one profile didn't apply on another (issue #14).
/// They now live here — one set shared by every profile, loaded/saved via
/// <see cref="RemSoundSettingsStore"/>'s Load*/Save* hotkey methods. Null = use the built-in default
/// for that action. The old per-profile <see cref="HotkeyRecord"/> fields on <see cref="Profile"/>
/// are kept only so old profile JSONs still deserialise; they are no longer read or written.</summary>
public HotkeyRecord? ReceiveMuteHotkey { get; set; }
public HotkeyRecord? SendMuteHotkey { get; set; }
public HotkeyRecord? TrayHotkey { get; set; }
public HotkeyRecord? VolumeUpHotkey { get; set; }
public HotkeyRecord? VolumeDownHotkey { get; set; }
public HotkeyRecord? ToggleRecordingHotkey { get; set; }
public HotkeyRecord? RemoteVolumeUpHotkey { get; set; }
public HotkeyRecord? RemoteVolumeDownHotkey { get; set; }
public HotkeyRecord? RemoteMuteToggleHotkey { get; set; }
public HotkeyRecord? SystemVolumeUpHotkey { get; set; }
public HotkeyRecord? SystemVolumeDownHotkey { get; set; }
public HotkeyRecord? SystemMuteToggleHotkey { get; set; }
public HotkeyRecord? QuickProfileSwitchHotkey { get; set; }
public HotkeyRecord? SpeakStatusLineHotkey { get; set; }
/// <summary>True once the one-time "your keyboard shortcuts are now shared across profiles" notice
/// has been shown (to an upgrader), or silently marked done on a fresh install that had nothing to
/// reset. Stops the notice re-appearing. v4.4.</summary>
public bool KeyboardShortcutsGlobalNoticeShown { get; set; }
/// <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
+43 -192
View File
@@ -14,145 +14,73 @@ public sealed class RemSoundSettingsStore
{
public RemSoundSettingsStore(string appName) { }
public HotkeyInfo LoadReceiveMuteHotkey() =>
Try(() => Load()?.ReceiveMuteHotkey?.ToHotkeyInfo()) ?? new HotkeyInfo(Keys.R, true, true, true);
public void SaveReceiveMuteHotkey(HotkeyInfo hotkey)
// Keyboard shortcuts are MACHINE-WIDE as of v4.4 — one set shared by every profile, stored in
// AppConfig (issue #14: before v4.4 they lived on each Profile, so a shortcut set on one profile
// didn't apply on another). The Load*/Save* method names are unchanged, so the hotkey controller
// didn't need touching; only the backing store moved from the per-profile cache to AppConfig. The
// built-in defaults below are unchanged.
private static void SaveGlobalHotkey(Action<AppConfig> set)
{
var s = Load() ?? new Settings();
s.ReceiveMuteHotkey = HotkeySetting.From(hotkey);
Save(s);
var c = AppConfig.Load();
set(c);
try { c.Save(); } catch { /* best-effort, like the app's other AppConfig writes */ }
}
public HotkeyInfo LoadReceiveMuteHotkey() =>
AppConfig.Load().ReceiveMuteHotkey?.ToHotkeyInfo() ?? new HotkeyInfo(Keys.R, true, true, true);
public void SaveReceiveMuteHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.ReceiveMuteHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadSendMuteHotkey() =>
Try(() => Load()?.SendMuteHotkey?.ToHotkeyInfo()) ?? new HotkeyInfo(Keys.S, true, true, true);
public void SaveSendMuteHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.SendMuteHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().SendMuteHotkey?.ToHotkeyInfo() ?? new HotkeyInfo(Keys.S, true, true, true);
public void SaveSendMuteHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.SendMuteHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadTrayHotkey() =>
Try(() => Load()?.TrayHotkey?.ToHotkeyInfo()) ?? new HotkeyInfo(Keys.F10, true, true, false);
public void SaveTrayHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.TrayHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().TrayHotkey?.ToHotkeyInfo() ?? new HotkeyInfo(Keys.F10, true, true, false);
public void SaveTrayHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.TrayHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadVolumeUpHotkey() =>
Try(() => Load()?.VolumeUpHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveVolumeUpHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.VolumeUpHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().VolumeUpHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveVolumeUpHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.VolumeUpHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadVolumeDownHotkey() =>
Try(() => Load()?.VolumeDownHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveVolumeDownHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.VolumeDownHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().VolumeDownHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveVolumeDownHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.VolumeDownHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadToggleRecordingHotkey() =>
Try(() => Load()?.ToggleRecordingHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveToggleRecordingHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.ToggleRecordingHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().ToggleRecordingHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveToggleRecordingHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.ToggleRecordingHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadRemoteVolumeUpHotkey() =>
Try(() => Load()?.RemoteVolumeUpHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveRemoteVolumeUpHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.RemoteVolumeUpHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().RemoteVolumeUpHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveRemoteVolumeUpHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.RemoteVolumeUpHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadRemoteVolumeDownHotkey() =>
Try(() => Load()?.RemoteVolumeDownHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveRemoteVolumeDownHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.RemoteVolumeDownHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().RemoteVolumeDownHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveRemoteVolumeDownHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.RemoteVolumeDownHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadRemoteMuteToggleHotkey() =>
Try(() => Load()?.RemoteMuteToggleHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveRemoteMuteToggleHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.RemoteMuteToggleHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().RemoteMuteToggleHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveRemoteMuteToggleHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.RemoteMuteToggleHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadSystemVolumeUpHotkey() =>
Try(() => Load()?.SystemVolumeUpHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveSystemVolumeUpHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.SystemVolumeUpHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().SystemVolumeUpHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveSystemVolumeUpHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.SystemVolumeUpHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadSystemVolumeDownHotkey() =>
Try(() => Load()?.SystemVolumeDownHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveSystemVolumeDownHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.SystemVolumeDownHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().SystemVolumeDownHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveSystemVolumeDownHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.SystemVolumeDownHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadSystemMuteToggleHotkey() =>
Try(() => Load()?.SystemMuteToggleHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveSystemMuteToggleHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.SystemMuteToggleHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().SystemMuteToggleHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveSystemMuteToggleHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.SystemMuteToggleHotkey = HotkeyRecord.From(hotkey));
public HotkeyInfo LoadQuickProfileSwitchHotkey() =>
Try(() => Load()?.QuickProfileSwitchHotkey?.ToHotkeyInfo()) ?? HotkeyInfo.Unset;
public void SaveQuickProfileSwitchHotkey(HotkeyInfo hotkey)
{
var s = Load() ?? new Settings();
s.QuickProfileSwitchHotkey = HotkeySetting.From(hotkey);
Save(s);
}
AppConfig.Load().QuickProfileSwitchHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveQuickProfileSwitchHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.QuickProfileSwitchHotkey = HotkeyRecord.From(hotkey));
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);
}
AppConfig.Load().SpeakStatusLineHotkey?.ToHotkeyInfo() ?? HotkeyInfo.Unset;
public void SaveSpeakStatusLineHotkey(HotkeyInfo hotkey) => SaveGlobalHotkey(c => c.SpeakStatusLineHotkey = HotkeyRecord.From(hotkey));
public bool LoadAcceptRemoteVolumeCommands(bool defaultValue = false) =>
Try(() => Load()?.AcceptRemoteVolumeCommands) ?? defaultValue;
@@ -590,20 +518,9 @@ public sealed class RemSoundSettingsStore
if (profile is null) throw new ArgumentNullException(nameof(profile));
cache = new Settings
{
ReceiveMuteHotkey = profile.ReceiveMuteHotkey is null ? null : HotkeySettingFromRecord(profile.ReceiveMuteHotkey),
SendMuteHotkey = profile.SendMuteHotkey is null ? null : HotkeySettingFromRecord(profile.SendMuteHotkey),
TrayHotkey = profile.TrayHotkey is null ? null : HotkeySettingFromRecord(profile.TrayHotkey),
VolumeUpHotkey = profile.VolumeUpHotkey is null ? null : HotkeySettingFromRecord(profile.VolumeUpHotkey),
VolumeDownHotkey = profile.VolumeDownHotkey is null ? null : HotkeySettingFromRecord(profile.VolumeDownHotkey),
ToggleRecordingHotkey = profile.ToggleRecordingHotkey is null ? null : HotkeySettingFromRecord(profile.ToggleRecordingHotkey),
RemoteVolumeUpHotkey = profile.RemoteVolumeUpHotkey is null ? null : HotkeySettingFromRecord(profile.RemoteVolumeUpHotkey),
RemoteVolumeDownHotkey = profile.RemoteVolumeDownHotkey is null ? null : HotkeySettingFromRecord(profile.RemoteVolumeDownHotkey),
RemoteMuteToggleHotkey = profile.RemoteMuteToggleHotkey is null ? null : HotkeySettingFromRecord(profile.RemoteMuteToggleHotkey),
SystemVolumeUpHotkey = profile.SystemVolumeUpHotkey is null ? null : HotkeySettingFromRecord(profile.SystemVolumeUpHotkey),
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),
// Keyboard shortcuts are no longer per-profile (v4.4) — they live in AppConfig now and are
// not carried through the profile cache. Profile's HotkeyRecord fields remain only so old
// profile JSONs still deserialise; they're ignored.
AcceptRemoteVolumeCommands = profile.AcceptRemoteVolumeCommands,
MaxLatencyMs = profile.MaxLatencyMs,
Codec = profile.Codec,
@@ -647,20 +564,7 @@ public sealed class RemSoundSettingsStore
{
if (profile is null) throw new ArgumentNullException(nameof(profile));
var s = cache;
profile.ReceiveMuteHotkey = s.ReceiveMuteHotkey is null ? null : HotkeyRecordFromSetting(s.ReceiveMuteHotkey);
profile.SendMuteHotkey = s.SendMuteHotkey is null ? null : HotkeyRecordFromSetting(s.SendMuteHotkey);
profile.TrayHotkey = s.TrayHotkey is null ? null : HotkeyRecordFromSetting(s.TrayHotkey);
profile.VolumeUpHotkey = s.VolumeUpHotkey is null ? null : HotkeyRecordFromSetting(s.VolumeUpHotkey);
profile.VolumeDownHotkey = s.VolumeDownHotkey is null ? null : HotkeyRecordFromSetting(s.VolumeDownHotkey);
profile.ToggleRecordingHotkey = s.ToggleRecordingHotkey is null ? null : HotkeyRecordFromSetting(s.ToggleRecordingHotkey);
profile.RemoteVolumeUpHotkey = s.RemoteVolumeUpHotkey is null ? null : HotkeyRecordFromSetting(s.RemoteVolumeUpHotkey);
profile.RemoteVolumeDownHotkey = s.RemoteVolumeDownHotkey is null ? null : HotkeyRecordFromSetting(s.RemoteVolumeDownHotkey);
profile.RemoteMuteToggleHotkey = s.RemoteMuteToggleHotkey is null ? null : HotkeyRecordFromSetting(s.RemoteMuteToggleHotkey);
profile.SystemVolumeUpHotkey = s.SystemVolumeUpHotkey is null ? null : HotkeyRecordFromSetting(s.SystemVolumeUpHotkey);
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);
// Keyboard shortcuts moved to AppConfig (machine-wide) in v4.4 — no longer written to profiles.
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;
@@ -697,38 +601,8 @@ public sealed class RemSoundSettingsStore
if (s.RecordingSettings is RecordingSettings rs) profile.RecordingSettings = rs.Clone();
}
private static HotkeySetting HotkeySettingFromRecord(HotkeyRecord r) => new()
{
Key = r.Key,
Control = r.Control,
Shift = r.Shift,
Alt = r.Alt,
};
private static HotkeyRecord HotkeyRecordFromSetting(HotkeySetting s) => new()
{
Key = s.Key,
Control = s.Control,
Shift = s.Shift,
Alt = s.Alt,
};
private sealed class Settings
{
public HotkeySetting? ReceiveMuteHotkey { get; set; }
public HotkeySetting? SendMuteHotkey { get; set; }
public HotkeySetting? TrayHotkey { get; set; }
public HotkeySetting? VolumeUpHotkey { get; set; }
public HotkeySetting? VolumeDownHotkey { get; set; }
public HotkeySetting? ToggleRecordingHotkey { get; set; }
public HotkeySetting? RemoteVolumeUpHotkey { get; set; }
public HotkeySetting? RemoteVolumeDownHotkey { get; set; }
public HotkeySetting? RemoteMuteToggleHotkey { get; set; }
public HotkeySetting? SystemVolumeUpHotkey { get; set; }
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; }
@@ -769,27 +643,4 @@ public sealed class RemSoundSettingsStore
public RecordingSettings? RecordingSettings { get; set; }
}
private sealed class HotkeySetting
{
public string Key { get; set; } = "M";
public bool Control { get; set; }
public bool Shift { get; set; }
public bool Alt { get; set; }
public static HotkeySetting From(HotkeyInfo hotkey) => new()
{
Key = hotkey.Key.ToString(),
Control = hotkey.Control,
Shift = hotkey.Shift,
Alt = hotkey.Alt,
};
public HotkeyInfo ToHotkeyInfo()
{
if (!Enum.TryParse<Keys>(Key, out var parsedKey)) return HotkeyInfo.Default;
var hotkey = new HotkeyInfo(parsedKey, Control, Shift, Alt);
if (hotkey.IsUnset) return HotkeyInfo.Unset;
return hotkey.IsValid ? hotkey : HotkeyInfo.Default;
}
}
}